PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.0.5
GiveWP – Donation Plugin and Fundraising Platform v2.0.5
4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / assets / js / admin / admin-scripts.js
give / assets / js / admin Last commit date
tinymce 9 years ago admin-forms.js 8 years ago admin-forms.min.js 8 years ago admin-scripts.js 8 years ago admin-scripts.min.js 8 years ago admin-settings.js 8 years ago admin-settings.min.js 8 years ago admin-shortcodes.js 9 years ago admin-shortcodes.min.js 9 years ago admin-widgets.js 8 years ago admin-widgets.min.js 8 years ago
admin-scripts.js
3161 lines
1 /*!
2 * Give Admin JS
3 *
4 * @description: The Give Admin scripts
5 * @package: Give
6 * @subpackage: Assets/JS
7 * @copyright: Copyright (c) 2016, WordImpress
8 * @license: http://opensource.org/licenses/gpl-2.0.php GNU Public License
9 */
10
11 jQuery.noConflict();
12 // Provided access to global level.
13 var give_setting_edit = false;
14 (function ($) {
15 /**
16 * Show/Hide ajax loader.
17 *
18 * @since 2.0
19 *
20 * @param $parent
21 * @param args
22 */
23 var giveAjaxLoader = function ($parent, args) {
24 args = jQuery.extend(
25 {
26 wrapper: true,
27 show: false
28 },
29 args
30 );
31
32 var $loaderParent = args.wrapper ? $('.give-spinner-wrapper', $parent) : {},
33 $loader = $('.give-spinner', $parent);
34
35 // Show loader.
36 if (args.show) {
37 if ($loaderParent.length) {
38 $loaderParent.addClass('is-active');
39 }
40
41 $loader.addClass('is-active');
42 return;
43 }
44
45 // Hide loader.
46 if ($loaderParent.length) {
47 $loaderParent.removeClass('is-active');
48 }
49
50 $loader.removeClass('is-active');
51 };
52
53 /**
54 * Onclick remove give-message parameter from url
55 *
56 * @since 1.8.14
57 */
58 var give_dismiss_notice = function () {
59 $('body').on('click', 'button.notice-dismiss', function () {
60 if ('give-invalid-license' !== jQuery(this).closest('div.give-notice').data('notice-id')) {
61 give_remove_give_message();
62 }
63 });
64 };
65
66 /**
67 * Remove give-message parameter from URL.
68 *
69 * @since 1.8.14
70 */
71 var give_remove_give_message = function () {
72 var parameter = 'give-message',
73 url = document.location.href,
74 urlparts = url.split('?');
75
76 if (urlparts.length >= 2) {
77 var urlBase = urlparts.shift();
78 var queryString = urlparts.join("?");
79
80 var prefix = encodeURIComponent(parameter) + '=';
81 var pars = queryString.split(/[&;]/g);
82 for (var i = pars.length; i-- > 0;) {
83 if (pars[i].lastIndexOf(prefix, 0) !== -1) {
84 pars.splice(i, 1);
85 }
86 }
87 url = urlBase + '?' + pars.join('&');
88 window.history.pushState('', document.title, url); // added this line to push the new url directly to url bar .
89 }
90 return url;
91 };
92
93 /**
94 * Setup Admin Datepicker
95 * @since: 1.0
96 */
97 var enable_admin_datepicker = function () {
98
99 // Date picker.
100 if ($('.give_datepicker').length > 0) {
101 var dateFormat = 'mm/dd/yy';
102 $('.give_datepicker').datepicker({
103 dateFormat: dateFormat
104 });
105 }
106 };
107
108 /**
109 * Setup Pretty Chosen Select Fields
110 */
111 var setup_chosen_give_selects = function () {
112
113 // Setup Chosen Selects.
114 var $give_chosen_containers = $('.give-select-chosen');
115
116 // Add loader with each input field.
117 $give_chosen_containers.on('chosen:ready', function () {
118 $(this).next('.chosen-container')
119 .find('input.chosen-search-input')
120 .after('<span class="spinner"></span>');
121 });
122
123 // No results returned from search trigger.
124 $give_chosen_containers.on('chosen:no_results', function () {
125 var $container = $(this).next('.chosen-container'),
126 $no_results_li = $container.find('li.no-results'),
127 error_string = '';
128
129 if ($container.hasClass('give-select-chosen-ajax') && $no_results_li.length) {
130 error_string = give_vars.chosen.ajax_search_msg.replace('{search_term}', '"' + $('input', $container).val() + '"');
131 } else {
132 error_string = give_vars.chosen.no_results_msg.replace('{search_term}', '"' + $('input', $container).val() + '"');
133 }
134
135 $no_results_li.html(error_string);
136
137 });
138
139 // Initiate chosen.
140 $give_chosen_containers.chosen({
141 inherit_select_classes: true,
142 placeholder_text_single: give_vars.one_option,
143 placeholder_text_multiple: give_vars.one_or_more_option
144 });
145
146 // Fix: Chosen JS - Zero Width Issue.
147 // @see https://github.com/harvesthq/chosen/issues/472#issuecomment-344414059
148 $( '.chosen-container' ).each( function() {
149 if ( 0 === $( this ).width() ) {
150 $( this ).css( 'width', '100%' );
151 }
152 });
153
154 // This fixes the Chosen box being 0px wide when the thickbox is opened.
155 $( '#post' ).on( 'click', '.give-thickbox', function() {
156 $( '.give-select-chosen', '#choose-give-form' ).css( 'width', '100%' );
157 });
158
159 // Variables for setting up the typing timer.
160 var typingTimer; // Timer identifier.
161 var doneTypingInterval = 342; // Time in ms, Slow - 521ms, Moderate - 342ms, Fast - 300ms.
162
163 // Replace options with search results.
164 $(document.body).on('keyup', '.give-select.chosen-container .chosen-search input, .give-select.chosen-container .search-field input', function (e) {
165
166 var val = $(this).val(),
167 $container = $(this).closest('.give-select-chosen'),
168 select = $container.prev(),
169 $search_field = $container.find('input[type="text"]'),
170 variations = $container.hasClass('variations'),
171 lastKey = e.which,
172 search_type = 'give_forms_search';
173
174 // Detect if we have a defined search type, otherwise default to donation forms.
175 if ($container.prev().data('search-type')) {
176
177 // Don't trigger AJAX if this select has all options loaded.
178 if ('no_ajax' === select.data('search-type')) {
179 return;
180 }
181
182 search_type = 'give_' + select.data('search-type') + '_search';
183 }
184
185 // Don't fire if short or is a modifier key (shift, ctrl, apple command key, or arrow keys).
186 if (
187 val.length <= 3 ||
188 !search_type.length ||
189 (
190 ( 9 === lastKey ) || // Tab.
191 ( 13 === lastKey ) || // Enter.
192 ( 16 === lastKey ) || // Shift.
193 ( 17 === lastKey ) || // Ctrl.
194 ( 18 === lastKey ) || // Alt.
195 ( 19 === lastKey ) || // Pause, Break.
196 ( 20 === lastKey ) || // CapsLock.
197 ( 27 === lastKey ) || // Esc.
198 ( 33 === lastKey ) || // Page Up.
199 ( 34 === lastKey ) || // Page Down.
200 ( 35 === lastKey ) || // End.
201 ( 36 === lastKey ) || // Home.
202 ( 37 === lastKey ) || // Left arrow.
203 ( 38 === lastKey ) || // Up arrow.
204 ( 39 === lastKey ) || // Right arrow.
205 ( 40 === lastKey ) || // Down arrow.
206 ( 44 === lastKey ) || // PrntScrn.
207 ( 45 === lastKey ) || // Insert.
208 ( 144 === lastKey ) || // NumLock.
209 ( 145 === lastKey ) || // ScrollLock.
210 ( 91 === lastKey ) || // WIN Key (Start).
211 ( 93 === lastKey ) || // WIN Menu.
212 ( 224 === lastKey ) || // Command key.
213 ( 112 <= lastKey && 123 >= lastKey ) // F1 to F12 lastKey.
214 )
215 ) {
216 return;
217 }
218 clearTimeout(typingTimer);
219 $container.addClass('give-select-chosen-ajax');
220
221 typingTimer = setTimeout(
222 function () {
223 $.ajax({
224 type: 'GET',
225 url: ajaxurl,
226 data: {
227 action: search_type,
228 s: val
229 },
230 dataType: 'json',
231 beforeSend: function () {
232 select.closest('ul.chosen-results').empty();
233 $search_field.prop('disabled', true);
234 },
235 success: function (data) {
236
237 $container.removeClass('give-select-chosen-ajax');
238
239 // Remove all options but those that are selected.
240 $('option:not(:selected)', select).remove();
241
242 if (data.length) {
243 $.each(data, function (key, item) {
244
245 // Add any option that doesn't already exist.
246 if (!$('option[value="' + item.id + '"]', select).length) {
247 select.prepend('<option value="' + item.id + '">' + item.name + '</option>');
248 }
249 });
250
251 // Trigger update event.
252 $container.prev('select.give-select-chosen').trigger('chosen:updated');
253
254 } else {
255
256 // Trigger no result message event.
257 $container.prev('select.give-select-chosen').trigger('chosen:no_results');
258 }
259
260 // Ensure the original query is retained within the search input.
261 $search_field.prop('disabled', false);
262 $search_field.val(val).focus();
263
264 }
265 }).fail(function (response) {
266 if (window.console && window.console.log) {
267 console.log(response);
268 }
269 }).done(function (response) {
270 $search_field.prop('disabled', false);
271 });
272 },
273 doneTypingInterval
274 );
275 });
276
277 $('.give-select-chosen .chosen-search input').each(function () {
278 var type = $(this).parent().parent().parent().prev('select.give-select-chosen').data('search-type');
279 var placeholder = '';
280
281 if ('form' === type) {
282 placeholder = give_vars.search_placeholder;
283 } else {
284 type = 'search_placeholder_' + type;
285 if (give_vars[type]) {
286 placeholder = give_vars[type];
287 }
288 }
289 $(this).attr('placeholder', placeholder);
290
291 });
292
293 };
294
295 /**
296 * Unformat Currency
297 *
298 * @use string give_vars.currency_decimals Number of decimals
299 *
300 * @param {string} price Price
301 * @param {number|bool} dp Number of decimals
302 *
303 * @returns {string}
304 */
305 function give_unformat_currency(price, dp) {
306 price = accounting.unformat(price, give_vars.decimal_separator).toString();
307 dp = ( 'undefined' === dp ? false : dp );
308
309 // Set default value for number of decimals.
310 if (false !== dp) {
311 price = parseFloat(price).toFixed(dp);
312 } else {
313
314 // If price do not have decimal value then set default number of decimals.
315 price = parseFloat(price).toFixed(give_vars.currency_decimals);
316 }
317
318 return price;
319 }
320
321 /**
322 * List donation screen JS
323 */
324
325 var GiveListDonation = {
326
327 init: function () {
328 this.deleteSingleDonation();
329 this.resendSingleDonationReceipt();
330 },
331
332 deleteSingleDonation: function () {
333 $('body').on('click', '.delete-single-donation', function () {
334 return confirm(give_vars.delete_payment);
335 });
336 },
337
338 resendSingleDonationReceipt: function () {
339 $('body').on('click', '.resend-single-donation-receipt', function () {
340 return confirm(give_vars.resend_receipt);
341 });
342 }
343
344 };
345
346 /**
347 * Edit donation screen JS
348 */
349 var Give_Edit_Donation = {
350
351 init: function () {
352 this.edit_address();
353 this.add_note();
354 this.remove_note();
355 this.new_donor();
356 this.resend_receipt();
357 this.variable_price_list();
358 },
359
360 edit_address: function () {
361
362 // Update base state field based on selected base country.
363 $('select[name="give-payment-address[0][country]"]').change(function () {
364 var $this = $(this);
365
366 data = {
367 action: 'give_get_states',
368 country: $this.val(),
369 field_name: 'give-payment-address[0][state]'
370 };
371 $.post(ajaxurl, data, function (response) {
372
373 // Show the states dropdown menu.
374 $this.closest('.column-container').find('#give-order-address-state-wrap').removeClass('give-hidden');
375
376 // Add support to zip fields.
377 $this.closest( '.column-container' ).find( '.give-column' ).removeClass( 'column-full' );
378 $this.closest( '.column-container' ).find( '.give-column' ).addClass( 'column' );
379
380 var state_wrap = $( '#give-order-address-state-wrap' );
381 state_wrap.find( '*' ).not( '.order-data-address-line' ).remove();
382 if ( typeof ( response.states_found ) !== undefined && true === response.states_found ) {
383 state_wrap.append( response.data );
384 state_wrap.find( 'select' ).chosen();
385 } else {
386 state_wrap.append( '<input type="text" name="give-payment-address[0][state]" value="' + response.default_state + '" class="give-edit-toggles medium-text"/>' );
387
388 if ( typeof ( response.show_field ) !== undefined && false === response.show_field ) {
389 // Hide the states dropdown menu.
390 $this.closest( '.column-container' ).find( '#give-order-address-state-wrap' ).addClass( 'give-hidden' );
391
392 // Add support to zip fields.
393 $this.closest( '.column-container' ).find( '.give-column' ).addClass( 'column-full' );
394 $this.closest( '.column-container' ).find( '.give-column' ).removeClass( 'column' );
395 }
396 }
397 });
398
399 return false;
400 });
401
402 },
403
404 add_note: function () {
405
406 $('#give-add-payment-note').on('click', function (e) {
407 e.preventDefault();
408 var postData = {
409 action: 'give_insert_payment_note',
410 payment_id: $(this).data('payment-id'),
411 note: $('#give-payment-note').val()
412 };
413
414 if (postData.note) {
415
416 $.ajax({
417 type: 'POST',
418 data: postData,
419 url: ajaxurl,
420 success: function (response) {
421 $('#give-payment-notes-inner').append(response);
422 $('.give-no-payment-notes').hide();
423 $('#give-payment-note').val('');
424 }
425 }).fail(function (data) {
426 if (window.console && window.console.log) {
427 console.log(data);
428 }
429 });
430
431 } else {
432 var border_color = $('#give-payment-note').css('border-color');
433 $('#give-payment-note').css('border-color', 'red');
434 setTimeout(function () {
435 $('#give-payment-note').css('border-color', border_color);
436 }, 500);
437 }
438
439 });
440
441 },
442
443 remove_note: function () {
444
445 $('body').on('click', '.give-delete-payment-note', function (e) {
446
447 e.preventDefault();
448
449 if (confirm(give_vars.delete_payment_note)) {
450
451 var postData = {
452 action: 'give_delete_payment_note',
453 payment_id: $(this).data('payment-id'),
454 note_id: $(this).data('note-id')
455 };
456
457 $.ajax({
458 type: 'POST',
459 data: postData,
460 url: ajaxurl,
461 success: function (response) {
462 $('#give-payment-note-' + postData.note_id).remove();
463 if (!$('.give-payment-note').length) {
464 $('.give-no-payment-notes').show();
465 }
466 return false;
467 }
468 }).fail(function (data) {
469 if (window.console && window.console.log) {
470 console.log(data);
471 }
472 });
473 return true;
474 }
475
476 });
477
478 },
479
480 new_donor: function () {
481
482 $('#give-donor-details').on('click', '.give-payment-new-donor, .give-payment-new-donor-cancel', function (e) {
483 e.preventDefault();
484 $('.donor-info').toggle();
485 $('.new-donor').toggle();
486
487 if ($('.new-donor').is(':visible')) {
488 $('#give-new-donor').val(1);
489 } else {
490 $('#give-new-donor').val(0);
491 }
492
493 });
494
495 },
496
497 resend_receipt: function () {
498 $('body').on('click', '#give-resend-receipt', function (e) {
499 return confirm(give_vars.resend_receipt);
500 });
501 },
502
503
504 variable_price_list: function () {
505 // Update variable price list when form changes.
506 $('#give_payment_form_select').chosen().change(function () {
507 var give_form_id,
508 variable_prices_html_container = $('.give-donation-level');
509
510 // Check for form ID.
511 if (!( give_form_id = $(this).val() )) {
512 return false;
513 }
514
515 // Bailout.
516 if (!variable_prices_html_container.length) {
517 return false;
518 }
519
520 // Ajax.
521 $.ajax({
522 type: 'POST',
523 url: ajaxurl,
524 data: {
525 form_id: give_form_id,
526 payment_id: $('input[name="give_payment_id"]').val(),
527 action: 'give_check_for_form_price_variations_html'
528 },
529 success: function (response) {
530 response = response.trim();
531 if (response) {
532
533 // Update Variable price html.
534 variable_prices_html_container.html(response);
535
536 // Add chosen feature to select tag.
537 $('select[name="give-variable-price"]').chosen().change();
538 } else {
539 // Update Variable price html.
540 variable_prices_html_container.html('');
541 }
542 }
543 });
544 });
545
546 // Add total donation amount if level changes.
547 $( '#give-donation-overview' ).on( 'change', 'select[name="give-variable-price"]', function () {
548 var prices = jQuery( this ).data( 'prices' ),
549 $total_amount = $( '#give-payment-total' );
550
551 if ( '' !== prices && $( this ).val() in prices ) {
552
553 $total_amount.val( prices[ $( this ).val() ] ).css( 'background-color', 'yellow' );
554
555 window.setTimeout(
556 function () {
557 $total_amount.css( 'background-color', 'white' );
558 },
559 1000
560 );
561 }
562 } );
563 }
564
565 };
566
567 /**
568 * Settings screen JS
569 */
570 var Give_Settings = {
571
572 init: function () {
573 this.setting_change_country();
574 this.toggle_options();
575 this.main_setting_update_notice();
576 this.verify_settings();
577 this.saveButtonTriggered();
578 this.changeAlert();
579 this.detectSettingsChange();
580 },
581
582 /**
583 * Fire when user change the country from the dropdown
584 *
585 * @since 1.8.14
586 */
587 setting_change_country: function () {
588 $('select[name="base_country"]').change(function () {
589 var $this = $(this);
590 var data = {
591 action: 'give_get_states',
592 country: $this.val(),
593 field_name: 'base_state',
594 };
595
596 $.post(ajaxurl, data, function (response) {
597 // Show the states dropdown menu.
598 $this.closest('tr').next().show()
599 if (typeof ( response.states_found ) != undefined && true == response.states_found) {
600 $(':input[name="base_state"]').replaceWith(response.data);
601 } else {
602 if (typeof ( response.show_field ) != undefined && false == response.show_field) {
603 // Hide the states dropdown menu.
604 $this.closest('tr').next().hide();
605 }
606 $(':input[name="base_state"]').replaceWith('<input type="text" name="' + data.field_name + '" value="' + response.default_state + '" class="give-edit-toggles medium-text"/>');
607 }
608 });
609 return false;
610 });
611 },
612
613 toggle_options: function() {
614
615 /**
616 * Email access
617 */
618 var emailAccess = $( 'input[name="email_access"]', '.give-setting-tab-body-general' );
619 emailAccess.on( 'change', function() {
620 var fieldValueEmail = $( 'input[name="email_access"]:checked', '.give-setting-tab-body-general' ).val();
621 var fieldValueRecaptcha = $( 'input[name="enable_recaptcha"]:checked', '.give-setting-tab-body-general' ).val();
622 if ( 'enabled' === fieldValueEmail ) {
623 $( 'input[name="enable_recaptcha"]' ).parents( 'tr' ).show();
624
625 if ( 'enabled' === fieldValueRecaptcha ) {
626 $( '#recaptcha_key' ).parents( 'tr' ).show();
627 $( '#recaptcha_secret' ).parents( 'tr' ).show();
628 } else {
629 $( '#recaptcha_key' ).parents( 'tr' ).hide();
630 $( '#recaptcha_secret' ).parents( 'tr' ).hide();
631 }
632 } else {
633 $( '#recaptcha_key' ).parents( 'tr' ).hide();
634 $( '#recaptcha_secret' ).parents( 'tr' ).hide();
635 $( 'input[name="enable_recaptcha"]' ).parents( 'tr' ).hide();
636 }
637 }).change();
638
639 /**
640 * Email reCAPTCHA
641 */
642 var recaptcha = $( 'input[name="enable_recaptcha"]', '.give-setting-tab-body-general' );
643 recaptcha.on( 'change', function() {
644 var fieldValueEmail = $( 'input[name="email_access"]:checked', '.give-setting-tab-body-general' ).val();
645 var fieldValueRecaptcha = $( 'input[name="enable_recaptcha"]:checked', '.give-setting-tab-body-general' ).val();
646
647 if ( 'enabled' === fieldValueEmail && 'enabled' === fieldValueRecaptcha ) {
648 $( '#recaptcha_key' ).parents( 'tr' ).show();
649 $( '#recaptcha_secret' ).parents( 'tr' ).show();
650 } else {
651 $( '#recaptcha_key' ).parents( 'tr' ).hide();
652 $( '#recaptcha_secret' ).parents( 'tr' ).hide();
653 }
654 }).change();
655
656 /**
657 * Form featured image
658 */
659 var form_featured_image = $('input[name="form_featured_img"]', '.give-setting-tab-body-display');
660 form_featured_image.on('change', function () {
661 var field_value = $('input[name="form_featured_img"]:checked', '.give-setting-tab-body-display').val();
662 if ('enabled' === field_value) {
663 $('#featured_image_size').parents('tr').show();
664 } else {
665 $('#featured_image_size').parents('tr').hide();
666 }
667 }).change();
668
669 /**
670 * Terms and Conditions
671 */
672 var terms_and_conditions = $('input[name="terms"]', '.give-setting-tab-body-display');
673 terms_and_conditions.on('change', function () {
674 var field_value = $('input[name="terms"]:checked', '.give-setting-tab-body-display').val();
675 if ('enabled' === field_value) {
676 $('#agree_to_terms_label').parents('tr').show();
677 $('#wp-agreement_text-wrap').parents('tr').show();
678 } else {
679 $('#agree_to_terms_label').parents('tr').hide();
680 $('#wp-agreement_text-wrap').parents('tr').hide();
681 }
682 }).change();
683
684 /**
685 * Disable admin notification
686 */
687 var admin_notification = $('input[name="admin_notices"]', '.give-setting-tab-body-emails');
688 admin_notification.on('change', function () {
689 var field_value = $('input[name="admin_notices"]:checked', '.give-setting-tab-body-emails').val();
690 if ('enabled' === field_value) {
691 $('#donation_notification_subject').parents('tr').show();
692 $('#wp-donation_notification-wrap').parents('tr').show();
693 $('#admin_notice_emails').parents('tr').show();
694 } else {
695 $('#donation_notification_subject').parents('tr').hide();
696 $('#wp-donation_notification-wrap').parents('tr').hide();
697 $('#admin_notice_emails').parents('tr').hide();
698 }
699 }).change();
700 },
701
702 main_setting_update_notice: function () {
703 var $setting_message = $('#setting-error-give-setting-updated');
704 if ($setting_message.length) {
705
706 // auto hide setting message in 5 seconds.
707 window.setTimeout(
708 function () {
709 $setting_message.slideUp();
710 },
711 5000
712 );
713 }
714 },
715
716 verify_settings: function () {
717 var success_setting = $('#success_page');
718 var failure_setting = $('#failure_page');
719
720 /**
721 * Verify success and failure page.
722 */
723 success_setting.add(failure_setting).change(function () {
724 if (success_setting.val() === failure_setting.val()) {
725 var notice_html = '<div id="setting-error-give-matched-success-failure-page" class="updated settings-error notice is-dismissible"> <p><strong>' + give_vars.matched_success_failure_page + '</strong></p> <button type="button" class="notice-dismiss"><span class="screen-reader-text">' + give_vars.dismiss_notice_text + '</span></button> </div>',
726 $notice_container = $('#setting-error-give-matched-success-failure-page');
727
728 // Unset setting field.
729 $(this).val('');
730
731 // Bailout.
732 if ($notice_container.length) {
733 return false;
734 }
735
736 // Add html.
737 $('h1', '#give-mainform').after(notice_html);
738 $notice_container = $('#setting-error-give-matched-success-failure-page');
739
740 // Add event to dismiss button.
741 $('.notice-dismiss', $notice_container).click(function () {
742 $notice_container.remove();
743 });
744 }
745 }).change();
746 },
747
748 saveButtonTriggered: function() {
749 $( '.give-settings-setting-page' ).on( 'click', '.give-save-button', function() {
750 $( window ).unbind( 'beforeunload' );
751 });
752 },
753
754 /**
755 * Show alert when admin try to reload the page with saving the changes.
756 *
757 * @since 1.8.14
758 */
759 changeAlert: function () {
760
761 $( window ).bind( 'beforeunload', function ( e ) {
762
763 var confirmationMessage = give_vars.setting_not_save_message;
764
765 if ( give_setting_edit ) {
766 ( e || window.event ).returnValue = confirmationMessage; //Gecko + IE.
767 return confirmationMessage; //Webkit, Safari, Chrome.
768 }
769 });
770 },
771
772 /**
773 * Display alert in setting page of give if user try to reload the page with saving the changes.
774 *
775 * @since 1.8.14
776 */
777 detectSettingsChange: function() {
778
779 var settingsPage = $( '.give-settings-setting-page' );
780
781 // Check if it give setting page or not.
782 if ( settingsPage.length > 0 ) {
783
784 // Get the default value.
785 var on_load_value = $( '#give-mainform' ).serialize();
786
787 /**
788 * Keyup event add to support to text box and textarea.
789 * blur event add to support to dropdown.
790 * Change event add to support to rest all element.
791 */
792 settingsPage.on( 'change keyup blur', 'form', function() {
793 // Get the form value after change.
794 var on_change_value = $( '#give-mainform' ).serialize();
795
796 // If both the value are same then no change has being made else change has being made.
797 give_setting_edit = ( on_load_value !== on_change_value ) ? true : false;
798
799 } );
800 }
801 }
802
803 };
804
805 /**
806 * Reports / Exports / Tools screen JS
807 */
808 var Give_Reports = {
809
810 init: function () {
811 this.date_options();
812 this.donors_export();
813 this.recount_stats();
814 },
815
816 date_options: function () {
817
818 // Show hide extended date options.
819 $('#give-graphs-date-options').change(function () {
820 var $this = $(this);
821 if ('other' === $this.val()) {
822 $('#give-date-range-options').show();
823 } else {
824 $('#give-date-range-options').hide();
825 }
826 });
827
828 },
829
830 donors_export: function () {
831
832 // Show / hide Donation Form option when exporting donors.
833 $('#give_donor_export_form').change(function () {
834
835 var $this = $(this),
836 form_id = $('option:selected', $this).val(),
837 customer_export_option = $('#give_customer_export_option');
838
839 if ('0' === $this.val()) {
840 customer_export_option.show();
841 } else {
842 customer_export_option.hide();
843 }
844
845 var price_options_select = $('.give_price_options_select');
846
847 // On Form Select, Check if Variable Prices Exist.
848 if (parseInt(form_id) != 0) {
849 var data = {
850 action: 'give_check_for_form_price_variations',
851 form_id: form_id,
852 all_prices: true
853 };
854
855 $.post(ajaxurl, data, function (response) {
856 price_options_select.remove();
857 $('#give_donor_export_form_chosen').after(response);
858 });
859 } else {
860 price_options_select.remove();
861 }
862
863 });
864
865 },
866
867 recount_stats: function () {
868
869 $('body').on('change', '#recount-stats-type', function () {
870
871 var export_form = $('#give-tools-recount-form');
872 var selected_type = $('option:selected', this).data('type');
873 var submit_button = $('#recount-stats-submit');
874 var forms = $('.tools-form-dropdown');
875
876 // Reset the form
877 export_form.find('.notice-wrap').remove();
878 submit_button.removeClass('button-disabled').attr('disabled', false);
879 forms.hide();
880 $('.give-recount-stats-descriptions span').hide();
881
882 if ('reset-stats' === selected_type) {
883 export_form.append('<div class="notice-wrap"></div>');
884 var notice_wrap = export_form.find('.notice-wrap');
885 notice_wrap.html('<div class="notice notice-warning"><p><input type="checkbox" id="confirm-reset" name="confirm_reset_store" value="1" /> <label for="confirm-reset">' + give_vars.reset_stats_warn + '</label></p></div>');
886 submit_button.addClass('button-disabled').attr('disabled', 'disabled');
887
888 // Add check when admin try to delete all the test donors.
889 } else if ('delete-test-donors' === selected_type) {
890 export_form.append('<div class="notice-wrap"></div>');
891 var notice_wrap = export_form.find('.notice-wrap');
892 notice_wrap.html('<div class="notice notice-warning"><p><input type="checkbox" id="confirm-reset" name="confirm_reset_store" value="1" /> <label for="confirm-reset">' + give_vars.delete_test_donor + '</label></p></div>');
893 submit_button.addClass('button-disabled').attr('disabled', 'disabled');
894 // Add check when admin try to delete all the imported donations.
895 } else if ('delete-import-donors' === selected_type) {
896
897 export_form.append('<div class="notice-wrap"></div>');
898 var notice_wrap = export_form.find('.notice-wrap');
899 notice_wrap.html('<div class="notice notice-warning"><p><input type="checkbox" id="confirm-reset" name="confirm_reset_store" value="1" /> <label for="confirm-reset">' + give_vars.delete_import_donor + '</label></p></div>');
900 submit_button.addClass('button-disabled').attr('disabled', 'disabled');
901 } else {
902 forms.hide();
903 forms.val(0);
904 }
905
906 current_forms = $('.tools-form-dropdown-' + selected_type);
907 current_forms.show();
908 current_forms.find('.give-select-chosen').css({
909 'width': 'auto',
910 'min-width': '250px'
911 });
912 $('#' + selected_type).show();
913 });
914
915 $('body').on('change', '#confirm-reset', function () {
916 var checked = $(this).is(':checked');
917 if (checked) {
918 $('#recount-stats-submit').removeClass('button-disabled').removeAttr('disabled');
919 } else {
920 $('#recount-stats-submit').addClass('button-disabled').attr('disabled', 'disabled');
921 }
922 });
923
924 $('#give-tools-recount-form').submit(function (e) {
925 var selection = $('#recount-stats-type').val();
926 var export_form = $(this);
927 var selected_type = $('option:selected', this).data('type');
928
929 if ('reset-stats' === selected_type) {
930 var is_confirmed = $('#confirm-reset').is(':checked');
931 if (is_confirmed) {
932 return true;
933 } else {
934 has_errors = true;
935 }
936 }
937
938 export_form.find('.notice-wrap').remove();
939
940 export_form.append('<div class="notice-wrap"></div>');
941 var notice_wrap = export_form.find('.notice-wrap');
942 var has_errors = false;
943
944 if (null === selection || 0 === selection) {
945 // Needs to pick a method give_vars.batch_export_no_class.
946 notice_wrap.html('<div class="updated error"><p>' + give_vars.batch_export_no_class + '</p></div>');
947 has_errors = true;
948 }
949
950 if ('recount-form' === selected_type) {
951
952 var selected_form = $('select[name="form_id"]').val();
953 if (selected_form == 0) {
954 // Needs to pick give_vars.batch_export_no_reqs.
955 notice_wrap.html('<div class="updated error"><p>' + give_vars.batch_export_no_reqs + '</p></div>');
956 has_errors = true;
957 }
958
959 }
960
961 if (has_errors) {
962 export_form.find('.button-disabled').removeClass('button-disabled');
963 return false;
964 }
965 });
966 }
967
968 };
969
970 /**
971 * Export screen JS
972 */
973 var Give_Export = {
974
975 init: function () {
976 this.submit();
977 this.dismiss_message();
978 },
979
980 submit: function () {
981
982 var self = this;
983
984 $(document.body).on('submit', '.give-export-form', function (e) {
985 e.preventDefault();
986
987 var submitButton = $(this).find('input[type="submit"]');
988
989 if (!submitButton.hasClass('button-disabled')) {
990
991 var data = $(this).serialize();
992
993 submitButton.addClass('button-disabled');
994 $( 'form.give-export-form select' ).attr( 'disabled', true ).trigger("chosen:updated");
995 $(this).find('.notice-wrap').remove();
996 $(this).append('<div class="notice-wrap give-clearfix"><span class="spinner is-active"></span><div class="give-progress"><div></div></div></div>');
997
998 // start the process
999 self.process_step(1, data, self);
1000
1001 }
1002
1003 });
1004 },
1005
1006 process_step: function (step, data, self) {
1007 /**
1008 * Do not allow user to reload the page
1009 *
1010 * @since 1.8.14
1011 */
1012 give_setting_edit = true;
1013
1014 var reset_form = false;
1015
1016 $.ajax({
1017 type: 'POST',
1018 url: ajaxurl,
1019 data: {
1020 form: data,
1021 action: 'give_do_ajax_export',
1022 step: step,
1023 },
1024 dataType: 'json',
1025 success: function (response) {
1026 if ('done' == response.step || response.error || response.success) {
1027
1028 /**
1029 * Now allow user to reload the page
1030 *
1031 * @since 1.8.14
1032 */
1033 give_setting_edit = false;
1034
1035 reset_form = true;
1036
1037 // We need to get the actual in progress form, not all forms on the page
1038 var export_form = $('.give-export-form').find('.give-progress').parent().parent();
1039 var notice_wrap = export_form.find('.notice-wrap');
1040 export_form.find('.button-disabled').removeClass('button-disabled');
1041 $( 'form.give-export-form select' ).attr( 'disabled', false ).trigger("chosen:updated");
1042 if (response.error) {
1043 var error_message = response.message;
1044 notice_wrap.html('<div class="updated error"><p>' + error_message + '</p></div>');
1045 } else if (response.success) {
1046 var success_message = response.message;
1047 notice_wrap.html('<div id="give-batch-success" class="updated notice is-dismissible"><p>' + success_message + '<span class="notice-dismiss"></span></p></div>');
1048 } else {
1049 notice_wrap.remove();
1050 window.location = response.url;
1051 }
1052 } else {
1053 $('.give-progress div').animate({
1054 width: response.percentage + '%',
1055 }, 50, function () {
1056 // Animation complete.
1057 });
1058 self.process_step(parseInt(response.step), data, self);
1059 }
1060
1061 if ( true === reset_form ) {
1062 // Reset the form for preventing multiple ajax request.
1063 $( '#give-tools-recount-form' )[ 0 ].reset();
1064 $( '#give-tools-recount-form .tools-form-dropdown' ).hide();
1065 $( '#give-tools-recount-form .tools-form-dropdown-recount-form-select' ).val('0').trigger('chosen:updated');
1066 }
1067 }
1068 }).fail(function (response) {
1069 /**
1070 * Now allow user to reload the page
1071 *
1072 * @since 1.8.14
1073 */
1074 give_setting_edit = false;
1075
1076 if (window.console && window.console.log) {
1077 console.log(response);
1078 }
1079 $('.notice-wrap').append(response.responseText);
1080 });
1081 },
1082
1083 dismiss_message: function () {
1084 $('body').on('click', '#give-batch-success .notice-dismiss', function () {
1085 $('#give-batch-success').parent().slideUp('fast');
1086 });
1087 }
1088
1089 };
1090
1091 /**
1092 * Updates screen JS
1093 */
1094 var Give_Updates = {
1095 el: {},
1096
1097 init: function () {
1098 this.submit();
1099 this.dismiss_message();
1100 },
1101
1102 submit: function () {
1103 var $self = this, step = 1, resume_update_step = 0;
1104
1105 $self.el.main_container = Give_Selector_Cache.get('#give-db-updates');
1106 $self.el.update_link = Give_Selector_Cache.get('.give-update-now', $self.el.main_container);
1107 $self.el.run_upload_container = Give_Selector_Cache.get('.give-run-database-update', $self.el.progress_main_container);
1108 $self.el.progress_main_container = Give_Selector_Cache.get('.progress-container', $self.el.main_container);
1109 $self.el.heading = Give_Selector_Cache.get('.update-message', $self.el.progress_main_container);
1110 $self.el.progress_container = Give_Selector_Cache.get('.progress-content', $self.el.progress_main_container);
1111 $self.el.update_progress_counter = Give_Selector_Cache.get( $( '.give-update-progress-count') );
1112
1113 if( $self.el.main_container.data('resume-update') ) {
1114 $self.el.update_link.addClass('active').hide().removeClass('give-hidden');
1115
1116 if( ! $('#give-restart-upgrades').length ) {
1117 window.setTimeout(Give_Updates.get_db_updates_info, 1000, $self );
1118 }
1119 }
1120
1121 // Bailout.
1122 if ($self.el.update_link.hasClass('active')) {
1123 return;
1124 }
1125
1126 $self.el.update_link.on('click', '', function (e) {
1127 e.preventDefault();
1128
1129 $self.el.run_upload_container.find('.notice').remove();
1130 $self.el.run_upload_container.append('<div class="notice notice-error non-dismissible give-run-update-containt"><p> <a href="#" class="give-run-update-button button">' + give_vars.db_update_confirmation_msg_button + '</a> ' + give_vars.db_update_confirmation_msg + '</p></div>');
1131 });
1132
1133 $('#give-db-updates').on('click', 'a.give-run-update-button', function (e) {
1134 e.preventDefault();
1135
1136 if ($(this).hasClass('active')) {
1137 return false;
1138 }
1139
1140 $(this).addClass('active').fadeOut();
1141 $self.el.update_link.addClass('active').fadeOut();
1142 $('#give-db-updates .give-run-update-containt').slideUp();
1143
1144 $self.el.progress_container.find('.notice-wrap').remove();
1145 $self.el.progress_container.append('<div class="notice-wrap give-clearfix"><span class="spinner is-active"></span><div class="give-progress"><div></div></div></div>');
1146 $self.el.progress_main_container.removeClass('give-hidden');
1147
1148 $.ajax({
1149 type: 'POST',
1150 url: ajaxurl,
1151 data: {
1152 action: 'give_run_db_updates',
1153 run_db_update: 1
1154 },
1155 dataType: 'json',
1156 success: function (response) {
1157
1158 }
1159 });
1160
1161 window.setTimeout(Give_Updates.get_db_updates_info, 500, $self );
1162
1163 return false;
1164 });
1165 },
1166
1167 get_db_updates_info: function( $self ){
1168 $.ajax({
1169 type: 'POST',
1170 url: ajaxurl,
1171 data: {
1172 action: 'give_db_updates_info',
1173 },
1174 dataType: 'json',
1175 success: function (response) {
1176 // We need to get the actual in progress form, not all forms on the page.
1177 var notice_wrap = Give_Selector_Cache.get('.notice-wrap', $self.el.progress_container, true);
1178
1179 if (-1 !== $.inArray('success', Object.keys(response))) {
1180 if (response.success) {
1181 if ($self.el.update_progress_counter.length) {
1182 $self.el.update_progress_counter.text('100%');
1183 }
1184
1185 // Update steps info.
1186 if (-1 !== $.inArray('heading', Object.keys(response.data))) {
1187 $self.el.heading.html('<strong>' + response.data.heading + '</strong>');
1188 }
1189
1190 $self.el.update_link.closest('p').remove();
1191 notice_wrap.html('<div class="notice notice-success is-dismissible"><p>' + response.data.message + '</p><button type="button" class="notice-dismiss"></button></div>');
1192
1193 } else {
1194 // Update steps info.
1195 if (-1 !== $.inArray('heading', Object.keys(response.data))) {
1196 $self.el.heading.html('<strong>' + response.data.heading + '</strong>');
1197 }
1198
1199 if( response.data.message ) {
1200 $self.el.update_link.closest('p').remove();
1201 notice_wrap.html('<div class="notice notice-error is-dismissible"><p>' + response.data.message + '</p><button type="button" class="notice-dismiss"></button></div>');
1202 } else{
1203 setTimeout(function () {
1204 $self.el.update_link.removeClass('active').show();
1205 $self.el.progress_main_container.addClass('give-hidden');
1206 }, 1000);
1207 }
1208 }
1209 } else {
1210 if (response && -1 !== $.inArray('percentage', Object.keys(response.data))) {
1211 if ($self.el.update_progress_counter.length) {
1212 $self.el.update_progress_counter.text(response.data.total_percentage + '%');
1213 }
1214
1215 // Update steps info.
1216 if (-1 !== $.inArray('heading', Object.keys(response.data))) {
1217 $self.el.heading.html('<strong>' + response.data.heading + '</strong>');
1218 }
1219
1220 // Update progress.
1221 $('.give-progress div', '#give-db-updates').animate({
1222 width: response.data.percentage + '%',
1223 }, 50, function () {
1224 // Animation complete.
1225 });
1226
1227 window.setTimeout(Give_Updates.get_db_updates_info, 1000, $self );
1228 } else {
1229 notice_wrap.html('<div class="notice notice-error"><p>' + give_vars.updates.ajax_error + '</p></div>');
1230
1231 setTimeout(function () {
1232 $self.el.update_link.removeClass('active').show();
1233 $self.el.progress_main_container.addClass('give-hidden');
1234 }, 1000);
1235 }
1236 }
1237 }
1238 });
1239 },
1240
1241 process_step: function (step, update, $self) {
1242
1243 give_setting_edit = true;
1244
1245 $.ajax({
1246 type: 'POST',
1247 url: ajaxurl,
1248 data: {
1249 action: 'give_do_ajax_updates',
1250 step: parseInt(step),
1251 update: parseInt(update)
1252 },
1253 dataType: 'json',
1254 success: function (response) {
1255 give_setting_edit = false;
1256
1257 // We need to get the actual in progress form, not all forms on the page.
1258 var notice_wrap = Give_Selector_Cache.get('.notice-wrap', $self.el.progress_container, true);
1259
1260 if (-1 !== $.inArray('success', Object.keys(response))) {
1261 if (response.success) {
1262 // Update steps info.
1263 if (-1 !== $.inArray('heading', Object.keys(response.data))) {
1264 $self.el.heading.html('<strong>' + response.data.heading + '</strong>');
1265 }
1266
1267 $self.el.update_link.closest('p').remove();
1268 notice_wrap.html('<div class="notice notice-success is-dismissible"><p>' + response.data.message + '</p><button type="button" class="notice-dismiss"></button></div>');
1269
1270 } else {
1271 // Update steps info.
1272 if (-1 !== $.inArray('heading', Object.keys(response.data))) {
1273 $self.el.heading.html('<strong>' + response.data.heading + '</strong>');
1274 }
1275
1276 notice_wrap.html('<div class="notice notice-error"><p>' + response.data.message + '</p></div>');
1277
1278 setTimeout(function () {
1279 $self.el.update_link.removeClass('active').show();
1280 $self.el.progress_main_container.addClass('give-hidden');
1281 }, 5000);
1282 }
1283 } else {
1284 if (response && -1 !== $.inArray('percentage', Object.keys(response.data))) {
1285 // Update progress.
1286 $('.give-progress div', '#give-db-updates').animate({
1287 width: response.data.percentage + '%',
1288 }, 50, function () {
1289 // Animation complete.
1290 });
1291
1292 // Update steps info.
1293 if (-1 !== $.inArray('heading', Object.keys(response.data))) {
1294 $self.el.heading.html('<strong>' + response.data.heading.replace('{update_count}', $self.el.heading.data('update-count')) + '</strong>');
1295 }
1296
1297 $self.process_step(parseInt(response.data.step), response.data.update, $self);
1298 } else {
1299 notice_wrap.html('<div class="notice notice-error"><p>' + give_vars.updates.ajax_error + '</p></div>');
1300
1301 setTimeout(function () {
1302 $self.el.update_link.removeClass('active').show();
1303 $self.el.progress_main_container.addClass('give-hidden');
1304 }, 5000);
1305 }
1306 }
1307
1308 }
1309 }).fail(function (response) {
1310
1311 give_setting_edit = false;
1312
1313 if (window.console && window.console.log) {
1314 console.log(response);
1315 }
1316
1317 Give_Selector_Cache.get('.notice-wrap', self.el.progress_container).append(response.responseText);
1318
1319 }).always(function () {
1320 });
1321
1322 },
1323
1324 dismiss_message: function () {
1325 $('body').on('click', '#poststuff .notice-dismiss', function () {
1326 $(this).parent().slideUp('fast');
1327 });
1328 }
1329
1330 };
1331
1332 /**
1333 * Admin Status Select Field Change
1334 *
1335 * @description: Handle status switching
1336 * @since: 1.0
1337 */
1338 var handle_status_change = function () {
1339
1340 $('select[name="give-payment-status"]').on('change', function () {
1341
1342 var status = $(this).val();
1343
1344 $('.give-donation-status').removeClass(function (index, css) {
1345 return (css.match(/\bstatus-\S+/g) || []).join(' ');
1346 }).addClass('status-' + status);
1347
1348 });
1349
1350 };
1351
1352 /**
1353 * Donor management screen JS
1354 */
1355 var GiveDonor = {
1356
1357 init: function () {
1358 this.editDonor();
1359 this.add_email();
1360 this.removeUser();
1361 this.cancelEdit();
1362 this.add_note();
1363 this.delete_checked();
1364 this.addressesAction();
1365 this.unlockDonorFields();
1366 this.bulkDeleteDonor();
1367 $( 'body' ).on( 'click', '#give-donors-filter .bulkactions input[type="submit"]', this.handleBulkActions );
1368 },
1369
1370 unlockDonorFields: function (e) {
1371 $('body').on('click', '.give-lock-block', function (e) {
1372 alert(give_vars.unlock_donor_fields);
1373 e.preventDefault();
1374 });
1375 },
1376
1377 editDonor: function () {
1378 $('body').on('click', '#edit-donor', function (e) {
1379 e.preventDefault();
1380 $('#give-donor-card-wrapper .editable').hide();
1381 $('#give-donor-card-wrapper .edit-item').fadeIn().css('display', 'block');
1382 });
1383 },
1384
1385 removeUser: function () {
1386 $('body').on('click', '#disconnect-donor', function (e) {
1387 e.preventDefault();
1388
1389 if (!confirm(give_vars.disconnect_user)) {
1390 return false;
1391 }
1392
1393 var donorID = $('input[name="customerinfo[id]"]').val();
1394
1395 var postData = {
1396 give_action: 'disconnect-userid',
1397 customer_id: donorID,
1398 _wpnonce: $('#edit-donor-info #_wpnonce').val()
1399 };
1400
1401 $.post(ajaxurl, postData, function (response) {
1402 window.location.href = response.redirect;
1403 }, 'json');
1404
1405 });
1406 },
1407
1408 cancelEdit: function () {
1409 $('body').on('click', '#give-edit-donor-cancel', function (e) {
1410 e.preventDefault();
1411 $('#give-donor-card-wrapper .edit-item').hide();
1412 $('#give-donor-card-wrapper .editable').show();
1413 $('.give_user_search_results').html('');
1414 });
1415 },
1416
1417 add_note: function () {
1418 $('body').on('click', '#add-donor-note', function (e) {
1419 e.preventDefault();
1420 var postData = {
1421 give_action: 'add-donor-note',
1422 customer_id: $('#donor-id').val(),
1423 donor_note: $('#donor-note').val(),
1424 add_donor_note_nonce: $('#add_donor_note_nonce').val()
1425 };
1426
1427 if (postData.donor_note) {
1428
1429 $.ajax({
1430 type: 'POST',
1431 data: postData,
1432 url: ajaxurl,
1433 success: function (response) {
1434 $('#give-donor-notes').prepend(response);
1435 $('.give-no-donor-notes').hide();
1436 $('#donor-note').val('');
1437 }
1438 }).fail(function (data) {
1439 if (window.console && window.console.log) {
1440 console.log(data);
1441 }
1442 });
1443
1444 } else {
1445 var border_color = $('#donor-note').css('border-color');
1446 $('#donor-note').css('border-color', 'red');
1447 setTimeout(function () {
1448 $('#donor-note').css('border-color', border_color);
1449 }, 500);
1450 }
1451 });
1452 },
1453 delete_checked: function () {
1454 $('#give-donor-delete-confirm').change(function () {
1455 var records_input = $('#give-donor-delete-records');
1456 var submit_button = $('#give-delete-donor');
1457
1458 if ($(this).prop('checked')) {
1459 records_input.attr('disabled', false);
1460 submit_button.attr('disabled', false);
1461 } else {
1462 records_input.attr('disabled', true);
1463 records_input.prop('checked', false);
1464 submit_button.attr('disabled', true);
1465 }
1466 });
1467 },
1468 add_email: function () {
1469 if (!$('#add-donor-email').length) {
1470 return;
1471 }
1472
1473 $(document.body).on('click', '#add-donor-email', function (e) {
1474 e.preventDefault();
1475 var button = $(this);
1476 var wrapper = button.parent();
1477
1478 wrapper.parent().find('.notice-wrap').remove();
1479 wrapper.find('.spinner').css('visibility', 'visible');
1480 button.attr('disabled', true);
1481
1482 var customer_id = wrapper.find('input[name="donor-id"]').val();
1483 var email = wrapper.find('input[name="additional-email"]').val();
1484 var primary = wrapper.find('input[name="make-additional-primary"]').is(':checked');
1485 var nonce = wrapper.find('input[name="add_email_nonce"]').val();
1486
1487 var postData = {
1488 give_action: 'add_donor_email',
1489 customer_id: customer_id,
1490 email: email,
1491 primary: primary,
1492 _wpnonce: nonce
1493 };
1494
1495 $.post(ajaxurl, postData, function (response) {
1496
1497 if (true === response.success) {
1498 window.location.href = response.redirect;
1499 } else {
1500 button.attr('disabled', false);
1501 wrapper.after('<div class="notice-wrap"><div class="notice notice-error inline"><p>' + response.message + '</p></div></div>');
1502 wrapper.find('.spinner').css('visibility', 'hidden');
1503 }
1504
1505 }, 'json');
1506
1507 });
1508 },
1509
1510 addressesAction: function () {
1511 var $obj = this,
1512 $addressWrapper = $('#donor-address-wrapper'),
1513 $allAddress = $('.all-address', $addressWrapper),
1514 $noAddressMessageWrapper = $('.give-no-address-message', $addressWrapper),
1515 $allAddressParent = $($allAddress).parent(),
1516 $addressForm = $('.address-form', $addressWrapper),
1517 $addressFormCancelBtn = $('.js-cancel', $addressForm),
1518 $addressFormCountryField = $('select[name="country"]', $addressForm),
1519 $addNewAddressBtn = $('.add-new-address', $addressWrapper),
1520 donorID = parseInt($('input[name="donor-id"]').val());
1521
1522 $addressFormCountryField.on('change', function () {
1523 $(this).trigger('chosen:updated');
1524 });
1525
1526 // Edit current address button event.
1527 $allAddress.on('click', '.js-edit', function (e) {
1528 var $parent = $(this).closest('.address');
1529
1530 e.preventDefault();
1531
1532 // Remove notice.
1533 $('.notice', $allAddressParent).remove();
1534
1535 $obj.__set_address_form_val($parent);
1536 $obj.__set_address_form_action('update', $parent.data('address-id'));
1537
1538 $addNewAddressBtn.hide();
1539 $allAddress.addClass('give-hidden');
1540 $addressForm.removeClass('add-new-address-form-hidden');
1541 $addressForm.data('process', 'update');
1542 });
1543
1544 // Remove address button event.
1545 $allAddress.on('click', '.js-remove', function (e) {
1546 e.preventDefault();
1547
1548 var $parent = $(this).closest('.address');
1549
1550 // Remove notice.
1551 $('.notice', $allAddressParent).remove();
1552
1553 $addressForm.data('changed', true);
1554 $obj.__set_address_form_val($parent);
1555 $obj.__set_address_form_action('remove', $parent.data('address-id'));
1556
1557 $addressForm.trigger('submit');
1558 });
1559
1560 // Add new address button event.
1561 $addNewAddressBtn.on('click', function (e) {
1562 e.preventDefault();
1563
1564 // Remove notice.
1565 $('.notice', $allAddressParent).remove();
1566
1567 $(this).hide();
1568 $allAddress.addClass('give-hidden');
1569 $addressForm.removeClass('add-new-address-form-hidden');
1570 $obj.__set_address_form_action('add');
1571
1572
1573 $obj.__set_address_form_action();
1574 });
1575
1576 // Cancel add new address form button event.
1577 $addressFormCancelBtn.on('click', function (e) {
1578 e.preventDefault();
1579
1580 // Reset form.
1581 $addressForm.find('input[type="text"]').val('');
1582
1583 $addNewAddressBtn.show();
1584 $allAddress.removeClass('give-hidden');
1585 $addressForm.addClass('add-new-address-form-hidden');
1586 });
1587
1588 // Save address.
1589 $addressForm
1590 .on('change', function () {
1591 $(this).data('changed', true);
1592 })
1593 .on('submit', function (e) {
1594 e.preventDefault();
1595
1596 var $this = $(this);
1597
1598 // Remove notice.
1599 $('.notice', $allAddressParent).remove();
1600
1601 // Do not send ajax if form does not change.
1602 if (!$(this).data('changed')) {
1603 $addNewAddressBtn.show();
1604 $allAddress.removeClass('give-hidden');
1605 $addressForm.addClass('add-new-address-form-hidden');
1606
1607 return false;
1608 }
1609
1610 $.ajax({
1611 type: 'POST',
1612 url: ajaxurl,
1613 data: {
1614 action: 'donor_manage_addresses',
1615 donorID: donorID,
1616 form: $('form', $addressForm).serialize()
1617 },
1618 beforeSend: function () {
1619 giveAjaxLoader($addressWrapper, {show: true});
1620 },
1621 success: function (response) {
1622 giveAjaxLoader($addressWrapper);
1623
1624 if (response.success) {
1625 var parent;
1626
1627 switch (response.data.action) {
1628 case 'add':
1629 $('.give-grid-row', $allAddress).append(response.data.address_html);
1630
1631 if (!$noAddressMessageWrapper.hasClass('give-hidden') && $('div.give-grid-col-4', $allAddress).length) {
1632 $noAddressMessageWrapper.addClass('give-hidden');
1633 }
1634 break;
1635
1636 case 'remove':
1637 parent = $allAddress
1638 .find('div[data-address-id*="' + response.data.id + '"]').parent();
1639
1640 if (parent.length) {
1641 parent.animate(
1642 {'margin-left': '-999'},
1643 1000,
1644 function () {
1645 parent.remove();
1646
1647 if (
1648 $noAddressMessageWrapper.hasClass('give-hidden') &&
1649 !$('div.give-grid-col-4', $allAddress).length
1650 ) {
1651 $noAddressMessageWrapper.removeClass('give-hidden');
1652 }
1653 }
1654 );
1655 }
1656
1657 break;
1658
1659 case 'update':
1660 parent = $allAddress
1661 .find('div[data-address-id*="' + response.data.id + '"]').parent();
1662 var $prevParent = parent.prev(),
1663 $nextParent = {},
1664 is_address_added = false;
1665
1666 if (parseInt($('.give-grid-row>div', $allAddress).length) < 2) {
1667 $('.give-grid-row', $allAddress).append(response.data.address_html);
1668 } else {
1669 if ($prevParent.length) {
1670 $prevParent.after(response.data.address_html);
1671 is_address_added = true;
1672 }
1673
1674 if (!is_address_added) {
1675 $nextParent = parent.next();
1676
1677 if ($nextParent.length) {
1678 $nextParent.before(response.data.address_html);
1679 }
1680 }
1681 }
1682
1683 parent.remove();
1684
1685 break;
1686 }
1687
1688 $allAddressParent.prepend(response.data.success_msg);
1689
1690 } else {
1691 $allAddressParent.prepend(response.data.error_msg);
1692 }
1693 },
1694 dataType: 'json'
1695 }).always(function () {
1696 $this.data('changed', false);
1697
1698 // Reset form.
1699 $addressForm.find('input[type="text"]').val('');
1700
1701 $addNewAddressBtn.show();
1702 $allAddress.removeClass('give-hidden');
1703 $addressForm.addClass('add-new-address-form-hidden');
1704 });
1705
1706 return false;
1707 });
1708 },
1709
1710 __set_address_form_action: function (addressAction, addressID) {
1711 var $addressWrapper = $('#donor-address-wrapper'),
1712 $addressForm = $('.address-form', $addressWrapper),
1713 $addressActionField = $('input[name="address-action"]', $addressForm),
1714 $addressIDField = $('input[name="address-id"]', $addressForm);
1715
1716 addressAction = addressAction || 'add';
1717 addressID = addressID || 'billing';
1718
1719 $addressActionField.val(addressAction);
1720 $addressIDField.val(addressID);
1721 },
1722
1723 __set_address_form_val: function ($form) {
1724 var $addressWrapper = $('#donor-address-wrapper'),
1725 $addressForm = $('.address-form', $addressWrapper),
1726 state = $('[data-address-type="state"]', $form).text().substr(2).trim(); // State will be like ", HR".
1727
1728 if ($('select[name="country"]', $addressForm).val().trim() !== $('[data-address-type="country"]', $form).text().trim()) {
1729 $('select[name="country"]', $addressForm).val($('[data-address-type="country"]', $form).text().trim()).trigger('chosen:updated').change();
1730
1731 // Update state after some time because state load by ajax for each country.
1732 window.setTimeout(function () {
1733 $('[name="state"]', $addressForm).val(state).trigger('chosen:updated');
1734 }, 500);
1735 } else {
1736 $('[name="state"]', $addressForm).val(state).trigger('chosen:updated');
1737 }
1738
1739 $('input[name="line1"]', $addressForm).val($('[data-address-type="line1"]', $form).text().trim());
1740 $('input[name="line2"]', $addressForm).val($('[data-address-type="line2"]', $form).text().trim());
1741 $('input[name="city"]', $addressForm).val($('[data-address-type="city"]', $form).text().trim());
1742 $('input[name="zip"]', $addressForm).val($('[data-address-type="zip"]', $form).text().trim());
1743 },
1744
1745 bulkDeleteDonor: function() {
1746 var $body = $('body');
1747
1748 // Cancel button click event for donor.
1749 $body.on('click', '#give-bulk-delete-cancel', function (e) {
1750 $(this).closest('tr').hide();
1751 $('.give-skip-donor').trigger('click');
1752 e.preventDefault();
1753 });
1754
1755 // Select All checkbox.
1756 $body.on('click', '#cb-select-all-1, #cb-select-all-2', function () {
1757
1758 var selectAll = $(this);
1759
1760 // Loop through donor selector checkbox.
1761 $.each($('.donor-selector'), function () {
1762
1763 var donorId = $(this).val(),
1764 donorName = $(this).data('name'),
1765 donorHtml = '<div id="give-donor-' + donorId + '" data-id="' + donorId + '">' +
1766 '<a class="give-skip-donor" title="' + give_vars.remove_from_bulk_delete + '">X</a>' +
1767 donorName + '</div>';
1768
1769 if( selectAll.is( ':checked' ) && ! $( this ).is( ':checked' ) ) {
1770 $( '#give-bulk-donors' ).append( donorHtml );
1771 } else if ( ! selectAll.is( ':checked' ) ) {
1772 $( '#give-bulk-donors' ).find( '#give-donor-' + donorId ).remove();
1773 }
1774 });
1775 });
1776
1777 // On checking checkbox, add to bulk delete donor.
1778 $body.on('click', '.donor-selector', function () {
1779 var donorId = $(this).val(),
1780 donorName = $(this).data('name'),
1781 donorHtml = '<div id="give-donor-' + donorId + '" data-id="' + donorId + '">' +
1782 '<a class="give-skip-donor" title="' + give_vars.remove_from_bulk_delete + '">X</a>' +
1783 donorName + '</div>';
1784
1785 if ($(this).is(':checked')) {
1786 $('#give-bulk-donors').prepend(donorHtml);
1787 } else {
1788 $('#give-bulk-donors').find('#give-donor-' + donorId).remove();
1789 }
1790 });
1791
1792 // CheckBox click event to confirm deletion of donor.
1793 $body.on('click', '#give-delete-donor-confirm', function () {
1794 if ($(this).is(':checked')) {
1795 $('#give-bulk-delete-button').removeAttr('disabled');
1796 } else {
1797 $('#give-bulk-delete-button').attr('disabled', true);
1798 $('#give-delete-donor-records').removeAttr('checked');
1799 }
1800 });
1801
1802 // CheckBox click event to delete records with donor.
1803 $body.on('click', '#give-delete-donor-records', function () {
1804 if ($(this).is(':checked')) {
1805 $('#give-delete-donor-confirm').attr('checked', 'checked');
1806 $('#give-bulk-delete-button').removeAttr('disabled');
1807 }
1808 });
1809
1810 // Skip Donor from Bulk Delete List.
1811 $body.on('click', '.give-skip-donor', function () {
1812 var donorId = $(this).closest('div').data('id');
1813 $('#give-donor-' + donorId).remove();
1814 $('#donor-' + donorId).find('input[type="checkbox"]').removeAttr('checked');
1815 });
1816
1817 // Clicking Event to Delete Single Donor.
1818 $body.on( 'click', '.give-single-donor-delete', function( e ) {
1819 var donorId = $( this ).data( 'id' ),
1820 donorSelector = $( 'tr#donor-' + donorId ).find( '.donor-selector' ),
1821 selectAll = $( '[id^="cb-select-all-"]' ),
1822 bulkDeleteList = $('#give-bulk-donors'),
1823 donorName = donorSelector.data( 'name' ),
1824 donorHtml = '<div id="give-donor-' + donorId + '" data-id="' + donorId + '">' +
1825 '<a class="give-skip-donor" title="' + give_vars.remove_from_bulk_delete + '">X</a>' +
1826 donorName + '</div>';
1827
1828 // Reset Donors List.
1829 bulkDeleteList.html('');
1830
1831 // Check whether the select all donor checkbox is already set, then unset it.
1832 if ( selectAll.is( ':checked' ) ) {
1833 selectAll.removeAttr( 'checked' );
1834 }
1835
1836 // Select the donor checkbox for which delete is clicked and others should be de-selected.
1837 $( '.donor-selector' ).removeAttr( 'checked' );
1838 donorSelector.attr( 'checked', 'checked' );
1839
1840 // Add Donor to the Bulk Delete List, if donor doesn't exists in the list.
1841 if ( $( '#give-donor-' + donorId ).length === 0 ) {
1842 bulkDeleteList.prepend(donorHtml);
1843 $('#give-bulk-delete').slideDown();
1844 }
1845
1846 e.preventDefault();
1847 });
1848 },
1849
1850 handleBulkActions: function( e ) {
1851
1852 var currentAction = $( this ).closest( '.tablenav' ).find( 'select' ).val(),
1853 donors = [],
1854 selectBulkActionNotice = give_vars.donors_bulk_action.no_action_selected,
1855 confirmActionNotice = give_vars.donors_bulk_action.no_donor_selected;
1856
1857 $.each( $( ".donor-selector:checked" ), function() {
1858 donors.push( $( this ).val() );
1859 });
1860
1861 // If there is no bulk action selected then show an alert message.
1862 if ( '-1' === currentAction ) {
1863 alert( selectBulkActionNotice );
1864 return false;
1865 }
1866
1867 // If there is no donor selected then show an alert.
1868 if ( ! parseInt( donors ) ) {
1869 alert( confirmActionNotice );
1870 return false;
1871 }
1872
1873 if( 'delete' === currentAction ) {
1874 $( '#give-bulk-delete' ).slideDown();
1875 }
1876
1877 e.preventDefault();
1878 }
1879 };
1880
1881 /**
1882 * API screen JS
1883 */
1884 var API_Screen = {
1885
1886 init: function () {
1887 this.revoke_api_key();
1888 this.regenerate_api_key();
1889 },
1890
1891 revoke_api_key: function () {
1892 $('body').on('click', '.give-revoke-api-key', function (e) {
1893 return confirm(give_vars.revoke_api_key);
1894 });
1895 },
1896 regenerate_api_key: function () {
1897 $('body').on('click', '.give-regenerate-api-key', function (e) {
1898 return confirm(give_vars.regenerate_api_key);
1899 });
1900 }
1901 };
1902
1903 /**
1904 * Edit Donation form screen Js
1905 */
1906 var Edit_Form_Screen = {
1907 init: function () {
1908 var default_tab_id = $.query.get('give_tab').length ? $.query.get('give_tab') : 'form_field_options';
1909
1910 this.handle_metabox_tab_click();
1911 this.setup_colorpicker_fields();
1912 this.setup_media_fields();
1913 this.setup_repeatable_fields();
1914 this.handle_repeater_group_events();
1915
1916 // Multi level repeater field js.
1917 this.handle_multi_levels_repeater_group_events();
1918
1919 // Set active tab on page load.
1920 this.activate_tab($('a[href="#' + default_tab_id + '"]'));
1921 },
1922
1923 /**
1924 * Attach click event handler to tabs.
1925 */
1926 handle_metabox_tab_click: function () {
1927 var self = this;
1928 var $tab_links = $('.give-metabox-tabs a');
1929
1930 $tab_links.on('click', function (e) {
1931 e.preventDefault();
1932 $this = $(this);
1933 self.activate_tab($this);
1934 self.update_query($this);
1935 });
1936 },
1937
1938 /**
1939 * Set the active tab.
1940 */
1941 activate_tab: function ($tab_link) {
1942 var tab_id = $tab_link.data('tab-id'),
1943 $li_parent = $tab_link.parent(),
1944 $sub_field = $('ul.give-metabox-sub-tabs', $li_parent),
1945 has_sub_field = $sub_field.length,
1946 $tab_links = $('.give-metabox-tabs a'),
1947 $all_tab_links_li = $tab_links.parents('li'),
1948 $all_sub_fields = $('ul.give-metabox-sub-tabs'),
1949 in_sub_fields = $tab_link.parents('ul.give-metabox-sub-tabs').length;
1950
1951 // Update active tab hidden field to maintain tab after save.
1952 $('#give_form_active_tab').val(tab_id);
1953
1954 if (has_sub_field) {
1955 $li_parent.toggleClass('active');
1956 $sub_field.removeClass('give-hidden');
1957
1958 var $active_subtab_li = $('li.active', 'ul.give-metabox-sub-tabs');
1959
1960 // Show hide sub fields if any and exit.
1961 $all_sub_fields.not($sub_field).addClass('give-hidden');
1962 $all_tab_links_li.not($li_parent).removeClass('active');
1963
1964 $active_subtab_li.addClass('active');
1965 } else if (!in_sub_fields) {
1966 // Hide all tab and sub tabs.
1967 $all_tab_links_li.each(function (index, item) {
1968 item = $(item);
1969 item.removeClass('active');
1970
1971 if (item.hasClass('has-sub-fields')) {
1972 $('ul.give-metabox-sub-tabs', item).addClass('give-hidden');
1973 }
1974 });
1975 } else if (in_sub_fields) {
1976 // Hide all sub tabs.
1977 $('ul.give-metabox-sub-tabs').addClass('give-hidden');
1978 $all_tab_links_li.removeClass('active');
1979
1980 // Hide all tab inside sub tabs.
1981 $tab_link.parents('ul.give-metabox-sub-tabs')
1982 .removeClass('give-hidden')
1983 .children('li')
1984 .removeClass('active');
1985
1986 // Add active class to parent li.
1987 $tab_link.parents('li.has-sub-fields').addClass('active');
1988 }
1989
1990 // Add active class to current tab link.
1991 $tab_link.parent().addClass('active');
1992
1993 // Hide all tab contents.
1994 $('.give_options_panel').removeClass('active');
1995
1996 // Show tab content.
1997 $($tab_link.attr('href')).addClass('active');
1998 },
1999
2000 /**
2001 * Update query string with active tab ID.
2002 */
2003 update_query: function ($tab_link) {
2004 var tab_id = $tab_link.data('tab-id');
2005 var new_query = $.query.set('give_tab', tab_id).remove('message').toString();
2006
2007 if (history.replaceState) {
2008 history.replaceState(null, null, new_query);
2009 }
2010 },
2011
2012 /**
2013 * Initialize colorpicker.
2014 */
2015 setup_colorpicker_fields: function () {
2016 $(document).ready(function () {
2017 var $colorpicker_fields = $('.give-colorpicker');
2018
2019 if ($colorpicker_fields.length) {
2020 $colorpicker_fields.each(function (index, item) {
2021 var $item = $(item);
2022
2023 // Bailout: do not automatically initialize color picker for repeater field group template.
2024 if ($item.parents('.give-template').length) {
2025 return;
2026 }
2027
2028 $item.wpColorPicker();
2029 });
2030 }
2031 });
2032 },
2033
2034 setup_media_fields: function () {
2035 var give_media_uploader,
2036 $give_upload_button,
2037 $body = $('body');
2038
2039 /**
2040 * Set media modal.
2041 */
2042 $body.on('click', '.give-upload-button', function (e) {
2043 e.preventDefault();
2044 var $media_modal_config = {};
2045
2046 // Cache input field.
2047 $give_upload_button = $(this);
2048
2049 // Set modal config.
2050 switch ($(this).data('field-type')) {
2051 case 'media':
2052 $media_modal_config = {
2053 title: give_vars.metabox_fields.media.button_title,
2054 button: {text: give_vars.metabox_fields.media.button_title},
2055 multiple: false, // Set to true to allow multiple files to be selected.
2056 library: {type: 'image'}
2057 };
2058 break;
2059
2060 default:
2061 $media_modal_config = {
2062 title: give_vars.metabox_fields.file.button_title,
2063 button: {text: give_vars.metabox_fields.file.button_title},
2064 multiple: false
2065 };
2066 }
2067
2068 var editing = jQuery(this).closest('.give-field-wrap').find('.give-input-field').attr('editing');
2069 if ('undefined' !== typeof( editing )) {
2070 wp.media.controller.Library.prototype.defaults.contentUserSetting = false;
2071 }
2072
2073 var $library = jQuery(this).closest('.give-field-wrap').find('.give-input-field').attr('library');
2074 if ('undefined' !== typeof( $library ) && '' !== $library) {
2075 $media_modal_config.library = {type: $library};
2076 }
2077
2078 // Extend the wp.media object.
2079 give_media_uploader = wp.media($media_modal_config);
2080
2081 // When a file is selected, grab the URL and set it as the text field's value.
2082 give_media_uploader.on('select', function () {
2083 var attachment = give_media_uploader.state().get('selection').first().toJSON(),
2084 $input_field = $give_upload_button.prev(),
2085 fvalue = ( 'id' === $give_upload_button.data('fvalue') ? attachment.id : attachment.url );
2086
2087 $body.trigger('give_media_inserted', [attachment, $input_field]);
2088
2089 // Set input field value.
2090 $input_field.val(fvalue);
2091
2092 // Update attachment id field value if fvalue is not set to id.
2093 if ('id' !== $give_upload_button.data('fvalue')) {
2094 var attachment_id_field_name = 'input[name="' + $input_field.attr('name') + '_id"]',
2095 id_field = $input_field.closest('tr').next('tr').find(attachment_id_field_name);
2096
2097 if (id_field.length) {
2098 $input_field.closest('tr').next('tr').find(attachment_id_field_name).val(attachment.id);
2099 }
2100 }
2101 });
2102
2103 // Open the uploader dialog.
2104 give_media_uploader.open();
2105 });
2106
2107 /**
2108 * Show image preview.
2109 */
2110 $body.on('give_media_inserted', function (e, attachment) {
2111 var $parent = $give_upload_button.parents('.give-field-wrap'),
2112 $image_container = $('.give-image-thumb', $parent);
2113
2114 // Bailout.
2115 if (!$image_container.length) {
2116 return false;
2117 }
2118
2119 // Bailout and hide preview.
2120 if ('image' !== attachment.type) {
2121 $image_container.addClass('give-hidden');
2122 $('img', $image_container).attr('src', '');
2123 return false;
2124 }
2125
2126 // Set the attachment URL to our custom image input field.
2127 $image_container.find('img').attr('src', attachment.url);
2128
2129 // Hide the add image link.
2130 $image_container.removeClass('give-hidden');
2131 });
2132
2133 /**
2134 * Delete Image Link.
2135 */
2136 $('span.give-delete-image-thumb', '.give-image-thumb').on('click', function (event) {
2137
2138 event.preventDefault();
2139
2140 var $parent = $(this).parents('.give-field-wrap'),
2141 $image_container = $(this).parent(),
2142 $image_input_field = $('input[type="text"]', $parent);
2143
2144 // Clear out the preview image.
2145 $image_container.addClass('give-hidden');
2146
2147 // Remove image link from input field.
2148 $image_input_field.val('');
2149
2150 // Hide the add image link.
2151 $('img', $image_container).attr('src', '');
2152 });
2153 },
2154
2155 /**
2156 * Setup repeater field.
2157 */
2158 setup_repeatable_fields: function () {
2159 jQuery(function () {
2160 jQuery('.give-repeatable-field-section').each(function () {
2161 var $this = $(this);
2162
2163 // Note: Do not change option params, it can break repeatable fields functionality.
2164 var options = {
2165 wrapper: '.give-repeatable-fields-section-wrapper',
2166 container: '.container',
2167 row: '.give-row',
2168 add: '.give-add-repeater-field-section-row',
2169 remove: '.give-remove',
2170 move: '.give-move',
2171 template: '.give-template',
2172 confirm_before_remove_row: true,
2173 confirm_before_remove_row_text: give_vars.confirm_before_remove_row_text,
2174 is_sortable: true,
2175 before_add: null,
2176 after_add: handle_metabox_repeater_field_row_count,
2177 //after_add: after_add, Note: after_add is internal function in repeatable-fields.js. Uncomment this can cause of js error.
2178 before_remove: null,
2179 after_remove: handle_metabox_repeater_field_row_remove,
2180 sortable_options: {
2181 placeholder: 'give-ui-placeholder-state-highlight',
2182 start: function (event, ui) {
2183 $('body').trigger('repeater_field_sorting_start', [ui.item]);
2184 },
2185 stop: function (event, ui) {
2186 $('body').trigger('repeater_field_sorting_stop', [ui.item]);
2187 },
2188 update: function (event, ui) {
2189 // Do not allow any row at position 0.
2190 if (ui.item.next().hasClass('give-template')) {
2191 ui.item.next().after(ui.item);
2192 }
2193
2194 var $rows = $('.give-row', $this).not('.give-template');
2195
2196 if ($rows.length) {
2197 var row_count = 1;
2198 $rows.each(function (index, item) {
2199 // Set name for fields.
2200 var $fields = $('.give-field, label', $(item));
2201
2202 if ($fields.length) {
2203 $fields.each(function () {
2204 var $parent = $(this).parents('.give-field-wrap'),
2205 $currentElement = $(this);
2206
2207 $.each(this.attributes, function (index, element) {
2208 var old_class_name_prefix = this.value.replace(/\[/g, '_').replace(/]/g, ''),
2209 old_class_name = old_class_name_prefix + '_field',
2210 new_class_name = '',
2211 new_class_name_prefix = '';
2212
2213 // Bailout.
2214 if (!this.value) {
2215 return;
2216 }
2217
2218 // Reorder index.
2219 this.value = this.value.replace(/\[\d+\]/g, '[' + (row_count - 1) + ']');
2220 new_class_name_prefix = this.value.replace(/\[/g, '_').replace(/]/g, '');
2221
2222 // Update class name.
2223 if ($parent.hasClass(old_class_name)) {
2224 new_class_name = new_class_name_prefix + '_field';
2225 $parent.removeClass(old_class_name).addClass(new_class_name);
2226 }
2227
2228 // Update field id.
2229 if (old_class_name_prefix == $currentElement.attr('id')) {
2230 $currentElement.attr('id', new_class_name_prefix);
2231 }
2232 });
2233 });
2234 }
2235
2236 row_count++;
2237 });
2238
2239 // Fire event.
2240 $this.trigger('repeater_field_row_reordered', [ui.item]);
2241 }
2242 }
2243 }
2244 //row_count_placeholder: '{{row-count-placeholder}}' Note: do not modify this param otherwise it will break repeatable field functionality.
2245 };
2246
2247 jQuery(this).repeatable_fields(options);
2248 });
2249 });
2250 },
2251
2252 /**
2253 * Handle repeater field events.
2254 */
2255 handle_repeater_group_events: function () {
2256 var $repeater_fields = $('.give-repeatable-field-section'),
2257 $body = $('body');
2258
2259 // Auto toggle repeater group
2260 $body.on('click', '.give-row-head button', function () {
2261 var $parent = $(this).closest('tr');
2262 $parent.toggleClass('closed');
2263 $('.give-row-body', $parent).toggle();
2264 });
2265
2266 // Reset header title when new row added.
2267 $repeater_fields.on('repeater_field_new_row_added repeater_field_row_deleted repeater_field_row_reordered', function () {
2268 handle_repeater_group_add_number_suffix($(this));
2269 });
2270
2271 // Disable editor when sorting start.
2272 $body.on('repeater_field_sorting_start', function (e, row) {
2273 var $textarea = $('.wp-editor-area', row);
2274
2275 if ($textarea.length) {
2276 $textarea.each(function (index, item) {
2277 window.setTimeout(
2278 function () {
2279 tinyMCE.execCommand('mceRemoveEditor', true, $(item).attr('id'));
2280 },
2281 300
2282 );
2283 });
2284 }
2285 });
2286
2287 // Enable editor when sorting stop.
2288 $body.on('repeater_field_sorting_stop', function (e, row) {
2289 var $textarea = $('.wp-editor-area', row);
2290
2291 if ($textarea.length) {
2292 $textarea.each(function (index, item) {
2293 window.setTimeout(
2294 function () {
2295 var textarea_id = $(item).attr('id');
2296 tinyMCE.execCommand('mceAddEditor', true, textarea_id);
2297
2298 // Switch editor to tmce mode to fix some glitch which appear when you reorder rows.
2299 window.setTimeout(function () {
2300 // Hack to show tmce mode.
2301 switchEditors.go(textarea_id, 'html');
2302 $('#' + textarea_id + '-tmce').trigger('click');
2303 }, 100);
2304 },
2305 300
2306 );
2307 });
2308 }
2309 });
2310
2311 // Process jobs on document load for repeater fields.
2312 $repeater_fields.each(function (index, item) {
2313 // Reset title on document load for already exist groups.
2314 var $item = $(item);
2315 handle_repeater_group_add_number_suffix($item);
2316
2317 // Close all tabs when page load.
2318 if (parseInt($item.data('close-tabs'))) {
2319 $('.give-row-head button', $item).trigger('click');
2320 $('.give-template', $item).removeClass('closed');
2321 $('.give-template .give-row-body', $item).show();
2322 }
2323 });
2324
2325 // Setup colorpicker field when row added.
2326 $repeater_fields.on('repeater_field_new_row_added', function (e, container, new_row) {
2327 $('.give-colorpicker', $(this)).each(function (index, item) {
2328 var $item = $(item);
2329
2330 // Bailout: skip already init colorpocker fields.
2331 if ($item.parents('.wp-picker-container').length || $item.parents('.give-template').length) {
2332 return;
2333 }
2334
2335 $item.wpColorPicker();
2336 });
2337
2338 // Load WordPress editor by ajax.
2339 var wysiwyg_editor_container = $('div[data-wp-editor]', new_row);
2340
2341 if (wysiwyg_editor_container.length) {
2342 wysiwyg_editor_container.each(function (index, item) {
2343 var $item = $(item),
2344 wysiwyg_editor = $('.wp-editor-wrap', $item),
2345 textarea = $('textarea', $item),
2346 textarea_id = 'give_wysiwyg_unique_' + Math.random().toString().replace('.', '_'),
2347 wysiwyg_editor_label = wysiwyg_editor.prev();
2348
2349 textarea.attr('id', textarea_id);
2350
2351 $.post(
2352 ajaxurl,
2353 {
2354 action: 'give_load_wp_editor',
2355 wp_editor: $item.data('wp-editor'),
2356 wp_editor_id: textarea_id,
2357 textarea_name: $('textarea', $item).attr('name')
2358 },
2359 function (res) {
2360 wysiwyg_editor.remove();
2361 wysiwyg_editor_label.after(res);
2362
2363 // Setup qt data for editor.
2364 tinyMCEPreInit.qtInit[textarea.attr('id')] = $.extend(
2365 true,
2366 tinyMCEPreInit.qtInit['_give_agree_text'],
2367 {id: textarea_id}
2368 );
2369
2370 // Setup mce data for editor.
2371 tinyMCEPreInit.mceInit[textarea_id] = $.extend(
2372 true,
2373 tinyMCEPreInit.mceInit['_give_agree_text'],
2374 {
2375 body_class: textarea_id + ' post-type-give_forms post-status-publish locale-' + tinyMCEPreInit.mceInit['_give_agree_text']['wp_lang_attr'].toLowerCase(),
2376 selector: '#' + textarea_id
2377 }
2378 );
2379
2380 // Setup editor.
2381 tinymce.init(tinyMCEPreInit.mceInit[textarea_id]);
2382 quicktags(tinyMCEPreInit.qtInit[textarea_id]);
2383 QTags._buttonsInit();
2384
2385 window.setTimeout(function () {
2386 // Hack to show tmce mode.
2387 switchEditors.go(textarea_id, 'html');
2388 $('#' + textarea_id + '-tmce').trigger('click');
2389 }, 100);
2390
2391 if (!window.wpActiveEditor) {
2392 window.wpActiveEditor = textarea_id;
2393 }
2394 }
2395 );
2396 });
2397 }
2398
2399 });
2400
2401 },
2402
2403 /**
2404 * Handle events for multi level repeater group.
2405 */
2406 handle_multi_levels_repeater_group_events: function () {
2407 var $repeater_fields = $('#_give_donation_levels_field');
2408
2409 // Add level title as suffix to header title when admin add level title.
2410 $('body').on('keyup', '.give-multilevel-text-field', function () {
2411 var $parent = $(this).closest('tr'),
2412 $header_title_container = $('.give-row-head h2 span', $parent),
2413 donation_level_header_text_prefix = $header_title_container.data('header-title');
2414
2415 // Donation level header already set.
2416 if ($(this).val() && ( $(this).val() === $header_title_container.html() )) {
2417 return false;
2418 }
2419
2420 if ($(this).val()) {
2421 // Change donaiton level header text.
2422 $header_title_container.html(donation_level_header_text_prefix + ': ' + $(this).val());
2423 } else {
2424 // Reset donation level header heading text.
2425 $header_title_container.html(donation_level_header_text_prefix);
2426 }
2427 });
2428
2429 // Add level title as suffix to header title on document load.
2430 $('.give-multilevel-text-field').each(function (index, item) {
2431
2432 // Skip first element.
2433 if (!index) {
2434 return;
2435 }
2436
2437 // Check if item is jquery object or not.
2438 var $item = $(item);
2439
2440 var $parent = $item.closest('tr'),
2441 $header_title_container = $('.give-row-head h2 span', $parent),
2442 donation_level_header_text_prefix = $header_title_container.data('header-title');
2443
2444 // Donation level header already set.
2445 if ($item.val() && ( $item.val() === $header_title_container.html() )) {
2446 return false;
2447 }
2448
2449 if ($item.val()) {
2450 // Change donaiton level header text.
2451 $header_title_container.html(donation_level_header_text_prefix + ': ' + $item.val());
2452 } else {
2453 // Reset donation level header heading text.
2454 $header_title_container.html(donation_level_header_text_prefix);
2455 }
2456 });
2457
2458 // Handle row deleted event for levels repeater field.
2459 $repeater_fields.on('repeater_field_row_deleted', function () {
2460 var $this = $(this);
2461
2462 window.setTimeout(
2463 function () {
2464 var $parent = $this,
2465 $repeatable_rows = $('.give-row', $parent).not('.give-template'),
2466 $default_radio = $('.give-give_default_radio_inline', $repeatable_rows),
2467 number_of_level = $repeatable_rows.length;
2468
2469 if (number_of_level === 1) {
2470 $default_radio.prop('checked', true);
2471 }
2472 },
2473 200
2474 );
2475 });
2476
2477 // Handle row added event for levels repeater field.
2478 $repeater_fields.on('repeater_field_new_row_added', function (e, container, new_row) {
2479 var $this = $(this),
2480 max_level_id = 0;
2481
2482 // Auto set default level if no level set as default.
2483 window.setTimeout(
2484 function () {
2485 // Set first row as default if selected default row deleted.
2486 // When a row is removed containing the default selection then revert default to first repeatable row.
2487 if ($('.give-give_default_radio_inline', $this).is(':checked') === false) {
2488 $('.give-row', $this)
2489 .not('.give-template')
2490 .first()
2491 .find('.give-give_default_radio_inline')
2492 .prop('checked', true);
2493 }
2494 },
2495 200
2496 );
2497
2498 // Get max level id.
2499 $('input[type="hidden"].give-levels_id', $this).each(function (index, item) {
2500 var $item = $(item),
2501 current_level = parseInt($item.val());
2502 if (max_level_id < current_level) {
2503 max_level_id = current_level;
2504 }
2505 });
2506
2507 // Auto set level id for new setting level setting group.
2508 $('input[type="hidden"].give-levels_id', new_row).val(++max_level_id);
2509 });
2510 }
2511 };
2512
2513 /**
2514 * Handle row count and field count for repeatable field.
2515 */
2516 var handle_metabox_repeater_field_row_count = function (container, new_row) {
2517 var row_count = $(container).attr('data-rf-row-count'),
2518 $container = $(container),
2519 $parent = $container.parents('.give-repeatable-field-section');
2520
2521 row_count++;
2522
2523 // Set name for fields.
2524 $('*', new_row).each(function () {
2525 $.each(this.attributes, function (index, element) {
2526 this.value = this.value.replace('{{row-count-placeholder}}', row_count - 1);
2527 });
2528 });
2529
2530 // Set row counter.
2531 $(container).attr('data-rf-row-count', row_count);
2532
2533 // Fire event: Row added.
2534 $parent.trigger('repeater_field_new_row_added', [container, new_row]);
2535 };
2536
2537 /**
2538 * Handle row remove for repeatable field.
2539 */
2540 var handle_metabox_repeater_field_row_remove = function (container) {
2541 var $container = $(container),
2542 $parent = $container.parents('.give-repeatable-field-section'),
2543 row_count = $(container).attr('data-rf-row-count');
2544
2545 // Reduce row count.
2546 $container.attr('data-rf-row-count', --row_count);
2547
2548 // Fire event: Row deleted.
2549 $parent.trigger('repeater_field_row_deleted');
2550 };
2551
2552 /**
2553 * Add number suffix to repeater group.
2554 */
2555 var handle_repeater_group_add_number_suffix = function ($parent) {
2556
2557 // Bailout: check if auto group numbering is on or not.
2558 if (!parseInt($parent.data('group-numbering'))) {
2559 return;
2560 }
2561
2562 var $header_title_container = $('.give-row-head h2 span', $parent),
2563 header_text_prefix = $header_title_container.data('header-title');
2564
2565 $header_title_container.each(function (index, item) {
2566 var $item = $(item);
2567
2568 // Bailout: do not rename header title in fields template.
2569 if ($item.parents('.give-template').length) {
2570 return;
2571 }
2572
2573 $item.html(header_text_prefix + ': ' + index);
2574 });
2575 };
2576
2577 /**
2578 * Payment history listing page js
2579 */
2580 var GivePaymentHistory = {
2581 init: function () {
2582 $('body').on('click', '#give-payments-filter input[type="submit"]', this.handleBulkActions);
2583 },
2584
2585 handleBulkActions: function () {
2586 var currentAction = $(this).closest('.tablenav').find('select').val(),
2587 currentActionLabel = $(this).closest('.tablenav').find('option[value="' + currentAction + '"]').text(),
2588 $payments = $('input[name="payment[]"]:checked').length,
2589 isStatusTypeAction = ( -1 !== currentAction.indexOf('set-status-') ),
2590 confirmActionNotice = '',
2591 status = '';
2592
2593 // Set common action, if action type is status.
2594 currentAction = isStatusTypeAction ?
2595 'set-to-status' :
2596 currentAction;
2597
2598 if (Object.keys(give_vars.donations_bulk_action).length) {
2599 for (status in give_vars.donations_bulk_action) {
2600 if (status === currentAction) {
2601
2602 // Get status text if current action types is status.
2603 confirmActionNotice = isStatusTypeAction ?
2604 give_vars.donations_bulk_action[currentAction].zero.replace('{status}', currentActionLabel.replace('Set To ', '')) :
2605 give_vars.donations_bulk_action[currentAction].zero;
2606
2607 // Check if admin selected any donations or not.
2608 if (!parseInt($payments)) {
2609 alert(confirmActionNotice);
2610 return false;
2611 }
2612
2613 // Get message on basis of payment count.
2614 confirmActionNotice = ( 1 < $payments ) ?
2615 give_vars.donations_bulk_action[currentAction].multiple :
2616 give_vars.donations_bulk_action[currentAction].single;
2617
2618 // Trigger Admin Confirmation PopUp.
2619 return window.confirm(confirmActionNotice
2620 .replace('{payment_count}', $payments)
2621 .replace('{status}', currentActionLabel.replace('Set To ', ''))
2622 );
2623 }
2624 }
2625 }
2626
2627 return true;
2628 }
2629 };
2630
2631 // On DOM Ready.
2632 $(function () {
2633
2634 give_dismiss_notice();
2635 enable_admin_datepicker();
2636 handle_status_change();
2637 setup_chosen_give_selects();
2638 give_import_donation_onload();
2639 $.giveAjaxifyFields({type: 'country_state', debug: true});
2640 GiveListDonation.init();
2641 Give_Edit_Donation.init();
2642 Give_Settings.init();
2643 Give_Reports.init();
2644 GiveDonor.init();
2645 API_Screen.init();
2646 Give_Export.init();
2647 Give_Updates.init();
2648 Edit_Form_Screen.init();
2649 GivePaymentHistory.init();
2650
2651
2652 // Footer.
2653 $('a.give-rating-link').click(function () {
2654 jQuery(this).parent().text(jQuery(this).data('rated'));
2655 });
2656
2657 // Ajax user search.
2658 $('.give-ajax-user-search').on('keyup', function () {
2659 var user_search = $(this).val();
2660 var exclude = '';
2661
2662 if ($(this).data('exclude')) {
2663 exclude = $(this).data('exclude');
2664 }
2665
2666 $('.give-ajax').show();
2667 data = {
2668 action: 'give_search_users',
2669 user_name: user_search,
2670 exclude: exclude
2671 };
2672
2673 document.body.style.cursor = 'wait';
2674
2675 $.ajax({
2676 type: 'POST',
2677 data: data,
2678 dataType: 'json',
2679 url: ajaxurl,
2680 success: function (search_response) {
2681 $('.give-ajax').hide();
2682 $('.give_user_search_results').removeClass('hidden');
2683 $('.give_user_search_results span').html('');
2684 $(search_response.results).appendTo('.give_user_search_results span');
2685 document.body.style.cursor = 'default';
2686 }
2687 });
2688 });
2689
2690 $('body').on('click.giveSelectUser', '.give_user_search_results span a', function (e) {
2691 e.preventDefault();
2692 var login = $(this).data('login');
2693 $('.give-ajax-user-search').val(login);
2694 $('.give_user_search_results').addClass('hidden');
2695 $('.give_user_search_results span').html('');
2696 });
2697
2698 $('body').on('click.giveCancelUserSearch', '.give_user_search_results a.give-ajax-user-cancel', function (e) {
2699 e.preventDefault();
2700 $('.give-ajax-user-search').val('');
2701 $('.give_user_search_results').addClass('hidden');
2702 $('.give_user_search_results span').html('');
2703 });
2704
2705 var $poststuff = $( '#poststuff' ),
2706 thousand_separator = give_vars.thousands_separator,
2707 decimal_separator = give_vars.decimal_separator,
2708 thousand_separator_count = '',
2709 alphabet_count = '',
2710 price_string = '',
2711
2712 // Thousand separation limit in price depends upon decimal separator symbol.
2713 // If thousand separator is equal to decimal separator then price does not have more then 1 thousand separator otherwise limit is zero.
2714 thousand_separator_limit = ( decimal_separator === thousand_separator ? 1 : 0 );
2715
2716 // Check & show message on keyup event.
2717 $poststuff.on('keyup', 'input.give-money-field, input.give-price-field', function () {
2718 var tootltip_setting = {
2719 label: give_vars.price_format_guide.trim()
2720 };
2721
2722 // Count thousand separator in price string.
2723 thousand_separator_count = ( $(this).val().match(new RegExp(thousand_separator, 'g')) || [] ).length;
2724 alphabet_count = ( $(this).val().match(new RegExp('[a-z]', 'g')) || [] ).length;
2725
2726 // Show qtip conditionally if thousand separator detected on price string.
2727 if (( -1 !== $(this).val().indexOf(thousand_separator) ) && ( thousand_separator_limit < thousand_separator_count )) {
2728 $(this).giveHintCss('show', tootltip_setting);
2729 } else if (alphabet_count) {
2730 $(this).giveHintCss('show', tootltip_setting);
2731 } else {
2732 $(this).giveHintCss('hide', tootltip_setting);
2733 }
2734
2735 // Reset thousand separator count.
2736 thousand_separator_count = alphabet_count = '';
2737 });
2738
2739 // Format price sting of input field on focusout.
2740 $poststuff.on('focusout', 'input.give-money-field, input.give-price-field', function () {
2741 price_string = give_unformat_currency($(this).val(), false);
2742
2743 // Back out.
2744 if (give_unformat_currency('0', false) === give_unformat_currency($(this).val(), false)) {
2745 var default_amount = $(this).attr('placeholder');
2746 default_amount = !default_amount ? '0' : default_amount;
2747
2748 $(this).val(default_amount);
2749
2750 return false;
2751 }
2752
2753 // Replace dot decimal separator with user defined decimal separator.
2754 price_string = price_string.replace('.', decimal_separator);
2755
2756 // Check if current number is negative or not.
2757 if (-1 !== price_string.indexOf('-')) {
2758 price_string = price_string.replace('-', '');
2759 }
2760
2761 // Update format price string in input field.
2762 $(this).val(price_string);
2763 });
2764
2765 // Set default value to 1 even if user inputs empty or negative number of donations.
2766 $poststuff.on( 'focusout', '#_give_number_of_donation_goal', function() {
2767 if ( 1 > $( this ).val() ) {
2768 $( this ).val( 1 );
2769 }
2770 });
2771
2772 /**
2773 * Responsive setting tab features.
2774 */
2775
2776 // Show/Hide sub tab nav.
2777 $('.give-settings-page').on('click', '#give-show-sub-nav', function (e) {
2778 e.preventDefault();
2779
2780 var $sub_tab_nav = $(this).next();
2781
2782 if (!$sub_tab_nav.is(':hover')) {
2783 $sub_tab_nav.toggleClass('give-hidden');
2784 }
2785
2786 return false;
2787 }).on('blur', '#give-show-sub-nav', function () {
2788 var $sub_tab_nav = $(this).next();
2789
2790 if (!$sub_tab_nav.is(':hover')) {
2791 $sub_tab_nav.addClass('give-hidden');
2792 }
2793 });
2794
2795 /**
2796 * Automatically show/hide email setting fields.
2797 */
2798 $('.give_email_api_notification_status_setting input').change(function () {
2799 // Bailout.
2800 var value = $(this).val(),
2801 is_enabled = ( 'enabled' === value ),
2802 $setting_fields = {};
2803
2804 // Get setting fields.
2805 if ($(this).closest('.give_options_panel').length) {
2806 $setting_fields = $(this).closest('.give_options_panel').children('.give-field-wrap:not(.give_email_api_notification_status_setting), .give-repeatable-field-section' );
2807 } else if ($(this).closest('table').length) {
2808 $setting_fields = $(this).closest('table').find('tr:not(.give_email_api_notification_status_setting)');
2809 }
2810
2811 if (-1 === jQuery.inArray(value, ['enabled', 'disabled', 'global'])) {
2812 return false;
2813 }
2814
2815 // Bailout.
2816 if (!$setting_fields.length) {
2817 return false;
2818 }
2819
2820 // Show hide setting fields.
2821 is_enabled ? $setting_fields.show() : $setting_fields.hide();
2822 });
2823
2824 $('.give_email_api_notification_status_setting input:checked').change();
2825
2826 // Render setting tab.
2827 give_render_responsive_tabs();
2828 });
2829 })(jQuery);
2830
2831 /**
2832 * Responsive js.
2833 */
2834 jQuery(window).resize(function () {
2835 give_render_responsive_tabs();
2836 });
2837
2838 /**
2839 * Render responsive tabs
2840 */
2841 function give_render_responsive_tabs() {
2842 var $setting_page_form = jQuery( '.give-settings-page' ),
2843 $main_tab_nav = jQuery( 'h2.give-nav-tab-wrapper' ),
2844 setting_page_form_width = $setting_page_form.width(),
2845 $sub_tab_nav_wrapper = jQuery( '.give-sub-nav-tab-wrapper' ),
2846 $sub_tab_nav = jQuery( 'nav', $sub_tab_nav_wrapper ),
2847 $setting_tab_links = jQuery( 'div.give-nav-tab-wrapper > a:not(give-not-tab)' ),
2848 $show_tabs = [],
2849 $hide_tabs = [],
2850 tab_width = 0;
2851
2852 if ( 600 < jQuery( window ).outerWidth() ) {
2853 tab_width = 200;
2854 }
2855
2856 // Bailout.
2857 if ( ! $setting_page_form.length ) {
2858 return false;
2859 }
2860
2861 // Update tab wrapper css.
2862 $main_tab_nav.css({
2863 height: 'auto',
2864 overflow: 'visible'
2865 });
2866
2867 // Show all tab if anyone hidden to calculate correct tab width.
2868 $setting_tab_links.removeClass( 'give-hidden' );
2869
2870 var refactor_tabs = new Promise(
2871 function( resolve, reject ) {
2872
2873 // Collect tabs to show or hide.
2874 jQuery.each( $setting_tab_links, function( index, $tab_link ) {
2875 $tab_link = jQuery( $tab_link );
2876 tab_width = tab_width + parseInt( $tab_link.outerWidth() );
2877
2878 if ( tab_width < setting_page_form_width ) {
2879 $show_tabs.push( $tab_link );
2880 } else {
2881 $hide_tabs.push( $tab_link );
2882 }
2883 });
2884
2885 resolve( true );
2886 }
2887 );
2888
2889 refactor_tabs.then( function( is_refactor_tabs ) {
2890
2891 // Remove current tab from sub menu and add this to main menu if exist and get last tab from main menu and add this to sub menu.
2892 if ( $hide_tabs.length && ( -1 !== window.location.search.indexOf( '&tab=' ) ) ) {
2893 var $current_tab_nav = {},
2894 query_params = get_url_params();
2895
2896 $hide_tabs = $hide_tabs.filter( function( $tab_link ) {
2897 var is_current_nav_item = ( -1 !== parseInt( $tab_link.attr( 'href' ).indexOf( '&tab=' + query_params['tab'] ) ) );
2898
2899 if ( is_current_nav_item ) {
2900 $current_tab_nav = $tab_link;
2901 }
2902
2903 return ( ! is_current_nav_item );
2904 });
2905
2906 if ( $current_tab_nav.length ) {
2907 $hide_tabs.unshift( $show_tabs.pop() );
2908 $show_tabs.push( $current_tab_nav );
2909 }
2910 }
2911
2912 var show_tabs = new Promise( function( resolve, reject ) {
2913
2914 // Show main menu tabs.
2915 if ( $show_tabs.length ) {
2916 jQuery.each( $show_tabs, function( index, $tab_link ) {
2917 $tab_link = jQuery( $tab_link );
2918
2919 if ( $tab_link.hasClass( 'give-hidden' ) ) {
2920 $tab_link.removeClass( 'give-hidden' );
2921 }
2922 });
2923 }
2924
2925 resolve( true );
2926 });
2927
2928 show_tabs.then( function( is_show_tabs ) {
2929
2930 // Hide sub menu tabs.
2931 if ( $hide_tabs.length ) {
2932 $sub_tab_nav.html( '' );
2933
2934 jQuery.each( $hide_tabs, function( index, $tab_link ) {
2935 $tab_link = jQuery( $tab_link );
2936 if ( ! $tab_link.hasClass( 'nav-tab-active' ) ) {
2937 $tab_link.addClass( 'give-hidden' );
2938 }
2939 $tab_link.clone().removeClass().appendTo( $sub_tab_nav );
2940 });
2941
2942 if ( ! jQuery( '.give-sub-nav-tab-wrapper', $main_tab_nav ).length ) {
2943 $main_tab_nav.append( $sub_tab_nav_wrapper );
2944 }
2945
2946 $sub_tab_nav_wrapper.show();
2947 } else {
2948 $sub_tab_nav_wrapper.hide();
2949 }
2950 });
2951 });
2952 }
2953
2954 /**
2955 * Get url query params.
2956 *
2957 * @returns {Array}
2958 */
2959 function get_url_params() {
2960 var vars = [], hash;
2961 var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
2962 for (var i = 0; i < hashes.length; i++) {
2963 hash = hashes[i].split('=');
2964 vars[hash[0]] = hash[1];
2965 }
2966 return vars;
2967 }
2968
2969 /**
2970 * Run when user click on submit button.
2971 *
2972 * @since 1.8.17
2973 */
2974 function give_on_core_settings_import_start() {
2975 var $form = jQuery('form.tools-setting-page-import');
2976 var progress = $form.find('.give-progress');
2977
2978 give_setting_edit = true;
2979
2980 jQuery.ajax({
2981 type: 'POST',
2982 url: ajaxurl,
2983 data: {
2984 action: give_vars.core_settings_import,
2985 fields: $form.serialize()
2986 },
2987 dataType: 'json',
2988 success: function (response) {
2989 give_setting_edit = false;
2990 if (true === response.success) {
2991 jQuery(progress).find('div').width(response.percentage + '%');
2992 } else {
2993 alert(give_vars.error_message);
2994 }
2995 window.location = response.url;
2996 },
2997 error: function () {
2998 give_setting_edit = false;
2999 alert(give_vars.error_message);
3000 }
3001 });
3002 }
3003
3004 /**
3005 * Run when user click on upload CSV.
3006 *
3007 * @since 1.8.13
3008 */
3009 function give_on_donation_import_start() {
3010 give_on_donation_import_ajax();
3011 }
3012
3013 /**
3014 * Upload CSV ajax
3015 *
3016 * @since 1.8.13
3017 */
3018 function give_on_donation_import_ajax() {
3019 var $form = jQuery('form.tools-setting-page-import');
3020
3021 /**
3022 * Do not allow user to reload the page
3023 *
3024 * @since 1.8.14
3025 */
3026 give_setting_edit = true;
3027
3028 var progress = $form.find('.give-progress');
3029
3030 var total_ajax = jQuery(progress).data('total_ajax'),
3031 current = jQuery(progress).data('current'),
3032 start = jQuery(progress).data('start'),
3033 end = jQuery(progress).data('end'),
3034 next = jQuery(progress).data('next'),
3035 total = jQuery(progress).data('total'),
3036 per_page = jQuery(progress).data('per_page');
3037
3038 jQuery.ajax({
3039 type: 'POST',
3040 url: ajaxurl,
3041 data: {
3042 action: give_vars.give_donation_import,
3043 total_ajax: total_ajax,
3044 current: current,
3045 start: start,
3046 end: end,
3047 next: next,
3048 total: total,
3049 per_page: per_page,
3050 fields: $form.serialize()
3051 },
3052 dataType: 'json',
3053 success: function (response) {
3054 jQuery(progress).data('current', response.current);
3055 jQuery(progress).find('div').width(response.percentage + '%');
3056
3057 if (response.next == true) {
3058 jQuery(progress).data('start', response.start);
3059 jQuery(progress).data('end', response.end);
3060
3061 if (response.last == true) {
3062 jQuery(progress).data('next', false);
3063 }
3064 give_on_donation_import_ajax();
3065 } else {
3066 /**
3067 * Now user is allow to reload the page.
3068 *
3069 * @since 1.8.14
3070 */
3071 give_setting_edit = false;
3072 window.location = response.url;
3073 }
3074 },
3075 error: function () {
3076 /**
3077 * Now user is allow to reload the page.
3078 *
3079 * @since 1.8.14
3080 */
3081 give_setting_edit = false;
3082 alert(give_vars.error_message);
3083 }
3084 });
3085 }
3086
3087 /**
3088 * Give Import donation run on load once page is load completed.
3089 */
3090 function give_import_donation_onload() {
3091 window.onload = function () {
3092 give_import_donation_required_fields_check();
3093 give_import_donation_on_drop_down_change();
3094 }
3095 }
3096
3097 /**
3098 * Give import donation on change of drop down and update the required fields.
3099 */
3100 function give_import_donation_on_drop_down_change() {
3101 var fields = document.querySelector( '.give-tools-setting-page-import table.step-2 tbody select' );
3102 if ( fields !== 'undefined' && fields !== null ) {
3103 jQuery( '.give-tools-setting-page-import table.step-2 tbody' ).on( 'change', 'select', function ( ) {
3104 give_import_donation_required_fields_check();
3105 } );
3106 }
3107 }
3108
3109 /**
3110 * Give Import Donations check required fields
3111 */
3112 function give_import_donation_required_fields_check() {
3113 var required_fields = document.querySelector( '.give-tools-setting-page-import table.step-2 .give-import-donation-required-fields' );
3114 if ( required_fields !== 'undefined' && required_fields !== null ) {
3115 var submit = true,
3116 email = false,
3117 first_name = false,
3118 amount = false,
3119 form = false;
3120
3121 document.querySelectorAll( '.give-import-donation-required-fields li' ).forEach( function (value) {
3122 value.querySelector( '.dashicons' ).classList.remove( 'dashicons-yes' );
3123 value.querySelector( '.dashicons' ).classList.add( 'dashicons-no-alt' );
3124 } );
3125
3126 var select_fields = Array.from( document.querySelectorAll( 'table.step-2 tbody select' ) ).map( function ( field ) {
3127 return field.value;
3128 } );
3129
3130 if ( select_fields.includes( 'email' ) ) {
3131 email = true;
3132 document.querySelector( '.give-import-donation-required-email .dashicons' ).classList.remove( 'dashicons-no-alt' );
3133 document.querySelector( '.give-import-donation-required-email .dashicons' ).classList.add( 'dashicons-yes' );
3134 }
3135
3136 if ( select_fields.includes( 'first_name' ) ) {
3137 first_name = true;
3138 document.querySelector( '.give-import-donation-required-first .dashicons' ).classList.remove( 'dashicons-no-alt' );
3139 document.querySelector( '.give-import-donation-required-first .dashicons' ).classList.add( 'dashicons-yes' );
3140 }
3141
3142
3143 if ( select_fields.includes( 'amount' ) ) {
3144 amount = true;
3145 document.querySelector( '.give-import-donation-required-amount .dashicons' ).classList.remove( 'dashicons-no-alt' );
3146 document.querySelector( '.give-import-donation-required-amount .dashicons' ).classList.add( 'dashicons-yes' );
3147 }
3148
3149 if ( select_fields.includes( 'form_id' ) || select_fields.includes( 'form_title' ) ) {
3150 form = true;
3151 document.querySelector( '.give-import-donation-required-form .dashicons' ).classList.remove( 'dashicons-no-alt' );
3152 document.querySelector( '.give-import-donation-required-form .dashicons' ).classList.add( 'dashicons-yes' );
3153 }
3154
3155 if ( email && first_name && amount && form ) {
3156 submit = false;
3157 }
3158
3159 document.getElementById( 'recount-stats-submit' ).disabled = submit;
3160 }
3161 }