PluginProbe
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) / 1.8.11
Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) v1.8.11
1.8.13 1.8.12.3 1.8.12.2 1.8.12.1 1.8.12 1.8.11.3 1.8.11.2 1.8.11.1 1.8.11 1.6.6 1.6.60 1.6.7 1.6.8 1.6.9 1.7.0 1.7.0.1 1.7.0.11 1.7.0.12 1.7.0.14 1.7.0.2 1.7.0.3 1.7.0.5 1.7.0.6 1.7.0.7 1.7.0.9 All 211 releases
charitable / assets / js / admin / charitable-admin.js

charitable-admin.js in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.8.11, at assets/js/admin/charitable-admin.js

1,073 lines 29.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 CHARITABLE_ADMIN = window.CHARITABLE_ADMIN || {};
2
3 /**
4 * Datepicker
5 */
6 ( function( exports, $ ){
7
8 if ( ! $.fn.datepicker ) {
9 return;
10 }
11
12 var Datepicker = function( $el ) {
13 this.$el = $el;
14 var options = {
15 dateFormat : this.$el.data('format') || 'yy/mm/dd',
16 minDate : this.$el.data('min-date') || '',
17 beforeShow : function( input, inst ) {
18 $('#ui-datepicker-div').addClass('charitable-datepicker-table');
19 }
20 }
21
22 this.$el.datepicker( options );
23
24 if ( this.$el.data('date') ) {
25 this.$el.datepicker( 'setDate', this.$el.data('date') );
26 }
27
28 if ( this.$el.data('min-date') ) {
29 this.$el.datepicker( 'option', 'minDate', this.$el.data('min-date') );
30 }
31 }
32
33 exports.Datepicker = Datepicker;
34
35 })( CHARITABLE_ADMIN, jQuery );
36
37 /**
38 * Conditional settings.
39 */
40 ( function( exports, $ ){
41
42 var Settings = function( $el ) {
43 var triggers = [];
44
45 show_setting = function(value, $trigger) {
46 var not = '!' === value[0],
47 compare = not ? value.slice(1) : value,
48 show;
49
50 if ('checked' === compare) {
51 show = $trigger.is(':checked');
52 } else if ('selected' === compare) {
53 show = $trigger.selected();
54 } else {
55 show = $trigger.val() === compare;
56 }
57
58 return not ? !show : show;
59 };
60
61 toggle_setting = function($setting, $trigger) {
62 var $el = (function($setting){
63 var $tr = $setting.parents('tr');
64 return $tr.length ? $tr.first() : $setting;
65 })($setting),
66 value = get_setting_value( $setting ),
67 show = show_setting(value, $trigger);
68
69 $el.toggle(show);
70 };
71
72 get_setting_value = function($setting) {
73 var value = $setting.data( 'trigger-value' );
74
75 /* Backwards compatibility for pre 1.5 */
76 if ( 'undefined' === typeof value ) {
77 value = $setting.data( 'show-only-if-value' );
78 }
79
80 return value;
81 };
82
83 toggle_options = function($setting, $trigger) {
84 var value = $trigger.val(),
85 options = $setting.data( 'trigger-value' ),
86 available;
87
88 /* If it's a radio input that isn't checked, ignore the event. */
89 if ( 'radio' === $trigger.attr( 'type' ) && ! $trigger.prop( 'checked' ) ) {
90 return;
91 }
92
93 if ( ! options.hasOwnProperty( value ) ) {
94 return;
95 }
96
97 available = options[value];
98
99 $setting.find( 'input' ).each( function(){
100 var $option = $(this),
101 disabled = ! ( $option.val() in available );
102
103 if ( disabled ) {
104 $option.prop( 'checked', false );
105 }
106
107 $option.prop( 'disabled', disabled ).trigger( 'change' );
108 });
109 };
110
111 get_trigger_id = function($setting) {
112 var id = $setting.data( 'trigger-key' );
113
114 /* Backwards compatibility for pre 1.5 */
115 if ( 'undefined' === typeof id ) {
116 id = '#' + $setting.data( 'show-only-if-key' );
117 }
118
119 return id;
120 };
121
122 get_trigger = function(id) {
123 if ( '#' === id[0] ) {
124 return $( id );
125 }
126
127 return $( '[name="' + id + '"]' );
128 };
129
130 get_change_type = function($setting) {
131 var type = $setting.data( 'trigger-change-type' );
132
133 if ( 'undefined' === typeof type ) {
134 type = 'visibility';
135 }
136
137 return type;
138 };
139
140 on_change = function() {
141 var $trigger = $( this ),
142 trigger_idx = $trigger.data( 'trigger_idx' ),
143 settings;
144
145 trigger_idx.forEach( function( id ) {
146
147 settings = triggers[id]['settings'];
148
149 settings.forEach( function( $setting ) {
150 var change = get_change_type( $setting );
151
152 if ( 'visibility' === change ) {
153 toggle_setting( $setting, $trigger );
154 } else if ( 'options' === change ) {
155 toggle_options( $setting, $trigger );
156 }
157 } );
158 } );
159 };
160
161 this.$el = $el;
162
163 var i = 0;
164
165 this.$el.find( '[data-trigger-key],[data-show-only-if-key]' ).each( function(){
166 var $this = $(this),
167 trigger_id = get_trigger_id( $this ),
168 element = triggers[trigger_id];
169
170 if ( 'undefined' === typeof triggers[trigger_id] ) {
171 triggers[i] = {
172 trigger_id : trigger_id,
173 settings : []
174 };
175 }
176
177 triggers[i].settings.push( $this );
178
179 i += 1;
180 });
181
182 triggers.forEach( function( trigger, i ) {
183 var $trigger = get_trigger( trigger['trigger_id'] ),
184 trigger_idx = $trigger.data( 'trigger_idx' );
185
186 if ( 'undefined' === typeof( trigger_idx ) ) {
187 trigger_idx = [];
188 }
189
190 trigger_idx.push( i );
191
192 $trigger.data( 'trigger_idx', trigger_idx );
193
194 $trigger.on( 'change', on_change );
195
196 $trigger.trigger( 'change' );
197 } );
198 };
199
200 exports.Settings = Settings;
201
202 })( CHARITABLE_ADMIN, jQuery );
203
204 ( function($){
205
206 var setup_license_check = function() {
207
208 $('#charitable-settings-connect-btn').on( 'click', function( e ){
209 var $btn = $( this );
210 var data = {
211 action : 'charitable_license_check',
212 'license' : $('input[name="license-key"]').val(), // 022effc6d03bdda601503a1dc13672fd
213 'nonce' : $('input[name="_wpnonce"]').val(),
214 'charitable_action' : $btn.data('action'),
215 };
216
217 // If the button contains the 'data-pro-connect' attribute and it's true, don't show the button.
218 if ( $('#charitable-settings-connect-btn').data( 'pro-connect' ) && $('#charitable-settings-connect-btn').data( 'pro-connect' ) == '1' ) {
219 return;
220 }
221
222 var originalHtml = $btn.html();
223 var spinnerHtml = '<i class="fa fa-spinner fa-spin" aria-hidden="true"></i> ';
224 if ( data.charitable_action === 'verify' ) {
225 $btn.html( spinnerHtml + charitable_admin.verifying );
226 } else {
227 $btn.html( spinnerHtml + charitable_admin.deactivating );
228 }
229
230 $btn.prop('disabled', true);
231
232 $.ajax({
233 type: 'POST',
234 data: data,
235 dataType: 'json',
236 url: ajaxurl,
237 xhrFields: {
238 withCredentials: true
239 },
240 success: function (response) {
241 if ( response.success ) {
242
243 // Redirect to upgrade.wpcharitable.com when backend returns upgrade_url (e.g. Pro installed but not activated).
244 if ( response.data.upgrade_url ) {
245 $btn.data( 'charitable-skip-restore', true );
246 window.location.href = response.data.upgrade_url;
247 return;
248 }
249 if ( response.data.show_manual_upgrade && response.data.url ) {
250 $.alert( {
251 title: charitable_admin.license_validated || charitable_admin.success,
252 content: response.data.message,
253 icon: 'fa fa-check-circle',
254 type: 'green',
255 boxWidth: '800px',
256 buttons: {
257 confirm: {
258 text: charitable_admin.ok,
259 btnClass: 'btn-confirm',
260 keys: [ 'enter' ],
261 action: function() {
262 window.location.reload();
263 },
264 },
265 manual: {
266 text: charitable_admin.manual_install,
267 btnClass: 'btn-confirm',
268 action: function() {
269 window.open( response.data.url, '_blank' );
270 window.location.reload();
271 },
272 },
273 },
274 } );
275 return;
276 }
277
278 // Pro installed but inactive: show popup to activate (no redirect to upgrade site or valid=valid).
279 if ( response.data.show_activate_pro_popup ) {
280 if ( typeof CharitableConnect !== 'undefined' && CharitableConnect.showActivateProPopup ) {
281 CharitableConnect.showActivateProPopup( response.data );
282 } else {
283 $.alert( {
284 title: charitable_admin.license_validated || charitable_admin.success,
285 content: response.data.message,
286 icon: 'fa fa-check-circle',
287 type: 'green',
288 boxWidth: '800px',
289 buttons: {
290 activate: {
291 text: charitable_admin.activate_now,
292 btnClass: 'btn-confirm',
293 keys: [ 'enter' ],
294 action: function() {
295 window.location.href = ( response.data.redirect_url || ( charitable_admin.admin_url + 'admin.php?page=charitable-settings&tab=general' ) ) + '&valid=valid&pro=activate';
296 },
297 },
298 cancel: {
299 text: charitable_admin.cancel,
300 keys: [ 'esc' ],
301 action: function() {
302 window.location.reload();
303 },
304 },
305 },
306 } );
307 }
308 return;
309 }
310
311 if ( response.data.valid === true ) {
312
313 var is_pro_plugin_installed = 'undefined' !== typeof charitable_admin.is_pro_installed && charitable_admin.is_pro_installed === '1' ? true : false;
314
315 $('#charitable-license-message').html( response.data.message );
316
317 // If the pro plugin is installed, redirect to a page that will activate it.
318 if ( is_pro_plugin_installed ) {
319
320 // Generate an alert modal to confirm we are about to activate the pro plugin.
321
322 $.alert( {
323 title: charitable_admin.activated_title,
324 content: charitable_admin.activated_content,
325 icon: 'fa fa-check-circle',
326 type: 'green',
327 boxWidth: '800px',
328 buttons: {
329 confirmActivate: {
330 text : charitable_admin.plugin_activate_btn,
331 btnClass: 'btn-confirm',
332 keys : [ 'enter' ],
333 action: function( confirmActivateButton ) {
334 window.location.href = charitable_admin.admin_url + 'admin.php?page=charitable-settings&tab=general&valid=valid&pro=activate';
335 return false;
336 }
337 }
338 },
339
340 } );
341
342
343 } else {
344 $btn.data( 'charitable-skip-restore', true );
345 if ( 'undefined' !== typeof charitable_admin.admin_url ) {
346 window.location.href = charitable_admin.admin_url + 'admin.php?page=charitable-settings&tab=general&valid=valid';
347 } else {
348 location.reload();
349 }
350 }
351
352 } else {
353 $('#charitable-license-message').html( response.data.message );
354
355 if ( 'undefined' !== typeof charitable_admin.admin_url ) {
356
357 $btn.data( 'charitable-skip-restore', true );
358 if ( response.data.license_limit === true ) {
359
360 window.location.href = charitable_admin.admin_url + 'admin.php?page=charitable-settings&tab=general&valid=invalid&license_limit=true';
361 } else if ( response.data.comm_success === false ) {
362 window.location.href = charitable_admin.admin_url + 'admin.php?page=charitable-settings&tab=general&valid=invalid&comm_success=false';
363 } else if ( data.charitable_action === 'verify' ) {
364 window.location.href = charitable_admin.admin_url + 'admin.php?page=charitable-settings&tab=general&valid=invalid';
365 } else {
366 window.location.href = charitable_admin.admin_url + 'admin.php?page=charitable-settings&tab=general&valid=success';
367 }
368 } else {
369
370 $btn.data( 'charitable-skip-restore', true );
371 location.reload();
372 }
373 }
374 }
375 // $user_fields.removeClass( 'loading-data' );
376 }
377 }).fail(function (data) {
378 if ( window.console && window.console.log ) {
379 // console.log( data );
380 // $user_fields.removeClass( 'loading-data' );
381 }
382 }).always(function () {
383 var $restoreBtn = $( '#charitable-settings-connect-btn' );
384 if ( $restoreBtn.length && $restoreBtn.data( 'charitable-skip-restore' ) ) {
385 $restoreBtn.removeData( 'charitable-skip-restore' ).removeData( 'charitable-license-original-html' );
386 return;
387 }
388 if ( $restoreBtn.length && $restoreBtn.data( 'charitable-license-original-html' ) ) {
389 $restoreBtn.html( $restoreBtn.data( 'charitable-license-original-html' ) ).prop( 'disabled', false ).removeData( 'charitable-license-original-html' );
390 }
391 });
392
393 $btn.data( 'charitable-license-original-html', originalHtml );
394
395 return false;
396
397 } );
398 };
399
400 var setup_campaign_end_date_field = function() {
401 $( '#campaign_end_date' ).on( 'change', function() {
402 var $field = $( this ),
403 date = $field.val(),
404 $span = $field.siblings( '.charitable-end-time' ),
405 $input = $field.siblings( '#campaign_end_time' );
406
407 if ( '' === date || ! date ) {
408 $span.hide();
409 $input.val( 0 );
410 } else {
411 $span.text( '@ 23:59 PM' ).show();
412 $input.val( '23:59:59' );
413 }
414 });
415 };
416
417 var setup_charitable_ajax = function() {
418 $('[data-charitable-action]').on( 'click', function( e ){
419 var data = $(this).data( 'charitable-args' ) || {},
420 action = 'charitable-' + $(this).data( 'charitable-action' );
421
422 $.post( ajaxurl,
423 {
424 'action' : action,
425 'data' : data
426 },
427 function( response ) {
428 // console.log( "Response: " + response );
429 }
430 );
431
432 return false;
433 } );
434 };
435
436 var setup_charitable_toggle = function() {
437 $( '[data-charitable-toggle]' ).on( 'click', function( e ){
438 var toggle_id = $(this).data( 'charitable-toggle' ),
439 toggle_text = $(this).attr( 'data-charitable-toggle-text' );
440
441 if ( toggle_text && toggle_text.length ) {
442 $(this).attr( 'data-charitable-toggle-text', $(this).text() );
443 $(this).text( toggle_text );
444 }
445
446 $('#' + toggle_id).toggle();
447
448 return false;
449 } );
450 };
451
452 var setup_advanced_meta_box = function() {
453 var $meta_box = $('#charitable-campaign-advanced-metabox');
454
455 if ( ! $meta_box.length ) {
456 return;
457 }
458
459 $meta_box.tabs();
460
461 var min_height = $meta_box.find('.charitable-tabs').height();
462
463 $meta_box.find('.ui-tabs-panel').each( function(){
464 $(this).css( 'min-height', min_height );
465 });
466 };
467
468 var toggle_custom_donations_checkbox = function() {
469 var $custom = $('#campaign_allow_custom_donations'),
470 $suggestions = $('.charitable-campaign-suggested-donations tbody tr:not(.to-copy)'),
471 has_suggestions = $suggestions.length > 1 || false === $suggestions.first().hasClass('no-suggested-amounts');
472
473 // check to see if $custom exists.
474 if ( ! $custom.length ) {
475 return;
476 }
477
478 $custom.prop( 'disabled', ! has_suggestions );
479
480 if ( ! has_suggestions ) {
481 $custom.prop( 'checked', true );
482 }
483 };
484
485 // Suggested Donations (in settings)
486 var setup_sortable_suggested_donations = function(){
487 if ( 'undefined' !== typeof $.fn.sortable ) {
488 $('.charitable-campaign-suggested-donations tbody').sortable({
489 items: "tr:not(.to-copy)",
490 handle: ".handle",
491 stop: function( event, ui ) {
492 reindex_rows();
493 }
494
495 });
496 }
497 };
498
499 var add_suggested_amount_row = function( $button ) {
500 var $table = $button.closest( '.charitable-campaign-suggested-donations' ).find('tbody');
501 var $clone = $table.find('tr.to-copy').clone().removeClass('to-copy hidden');
502
503 // check to see if $table or $clone exists.
504 if ( ! $table.length || ! $clone.length ) {
505 return;
506 }
507
508 $table.find( '.no-suggested-amounts' ).hide();
509 $table.append( $clone );
510 reindex_rows();
511 toggle_custom_donations_checkbox();
512 };
513
514 var delete_suggested_amount_row = function($button) {
515
516 $button.closest( 'tr' ).remove();
517 var $table = $button.closest('.charitable-campaign-suggested-donations').find('tbody');
518 if( $table.find( 'tr:not(.to-copy)' ).length == 1 ){
519 $table.find( '.no-suggested-amounts' ).removeClass('hidden').show();
520 }
521 reindex_rows();
522 toggle_custom_donations_checkbox();
523 };
524
525 var reindex_rows = function(){
526 $('.charitable-campaign-suggested-donations tbody').each(function(){
527 $(this).children('tr').not('.no-suggested-amounts .to-copy').each(function(index) {
528
529 $(this).find('input[name="_campaign_suggested_donations_default[]"').val( index );
530 $(this).data('index', index );
531 $(this).find('input').each(function(i) {
532 this.name = this.name.replace(/(\[\d\])/, '[' + index + ']');
533 });
534 });
535 });
536 };
537
538 // Suggested Donations (in left sidebar in preview)
539 var setup_sortable_suggested_donations_mini = function(){
540 if ( 'undefined' !== typeof $.fn.sortable ) {
541 $('.charitable-campaign-suggested-donations-mini tbody').sortable({
542 items: "tr:not(.to-copy)",
543 handle: ".handle",
544 stop: function( event, ui ) {
545 reindex_rows_mini();
546 }
547
548 });
549 }
550 };
551
552 var reindex_rows_mini = function(){
553 $('.charitable-campaign-suggested-donations-mini tbody').each(function(){
554 $(this).children('tr').not('.no-suggested-amounts .to-copy').each(function(index) {
555
556 $(this).find('input[name="_campaign_suggested_donations_default[]"').val( index );
557 $(this).data('index', index );
558 $(this).find('input').each(function(i) {
559 this.name = this.name.replace(/(\[\d\])/, '[' + index + ']');
560 });
561 });
562 });
563 };
564
565 // var setup_dashboard_widgets = function() {
566 // var $widget = $( '#charitable_dashboard_donations' );
567
568 // if ( $widget.length ) {
569 // $.ajax({
570 // type: "GET",
571 // data: {
572 // action: 'charitable_load_dashboard_donations_widget'
573 // },
574 // url: ajaxurl,
575 // success: function (response) {
576 // $widget.find( '.inside' ).html( response );
577 // }
578 // });
579 // }
580 // };
581
582 var setup_actions_form = function() {
583 var $form = $( '.charitable-actions-form-wrapper' ),
584 $select,
585 $submit,
586 $button;
587
588 if ( ! $form.length ) {
589 return;
590 }
591
592 $select = $form.find( '.charitable-action-select' );
593 $submit = $form.find( '.charitable-actions-submit' );
594 $button = $submit.find( 'button' );
595
596 $submit.hide();
597
598 $select.on( 'change', function() {
599 var action = $select.val(),
600 text = $select.find( 'option:selected' ).data( 'button-text');
601
602 if ( '' === action ) {
603 $submit.hide();
604 return;
605 }
606
607 $form.find( '.charitable-action-fields' ).each( function() {
608 var $el = $( this );
609 $el.toggle( action === $el.data( 'type' ) );
610 });
611
612 if ( text ) {
613 $button.text( text );
614 } else {
615 $button.text( $button.prop( 'title' ) );
616 }
617
618 $submit.show();
619 });
620 }
621
622 var setup_select2 = function() {
623 if ( ! $.fn.select2 ) {
624 return;
625 }
626
627 $( '.select2 select, select.select2' ).select2();
628 }
629
630 var setup_donor_select = function() {
631 var user_fields;
632
633 var get_user_fields = function() {
634 if ( 'object' === typeof user_fields ) {
635 return user_fields;
636 }
637
638 user_fields = [];
639
640 $( '#charitable-user-fields-wrap' ).find( 'select,input,textarea' ).each( function() {
641 user_fields.push(this.name);
642 });
643
644 return user_fields;
645 };
646
647 $( '.charitable-admin-donation-form #donor-id' ).on( 'change', function() {
648 var donor_id = $(this).val(),
649 $user_fields,
650 field;
651
652 if ( '' === donor_id || 'new' === donor_id ) {
653 return;
654 }
655
656 $user_fields = $( '#charitable-user-fields-wrap' );
657 $user_fields.addClass( 'loading-data' );
658
659 data = {
660 action : 'charitable_get_donor_data',
661 donor_id : donor_id,
662 fields : get_user_fields(),
663 nonce : $(this).data( 'nonce' )
664 };
665
666 $.ajax({
667 type: 'POST',
668 data: data,
669 dataType: 'json',
670 url: ajaxurl,
671 xhrFields: {
672 withCredentials: true
673 },
674 success: function (response) {
675 if ( response.success ) {
676 for ( field in response.data ) {
677 $user_fields.find( "[name=" + field + "]" ).val( response.data[field] );
678 }
679 }
680 $user_fields.removeClass( 'loading-data' );
681 }
682 }).fail(function (data) {
683 if ( window.console && window.console.log ) {
684 // console.log( data );
685 $user_fields.removeClass( 'loading-data' );
686 }
687 });
688 });
689 }
690
691 var setup_currency_inputs = function() {
692 if ( 'undefined' === typeof accounting ) {
693 return;
694 }
695
696 if ( 'undefined' === typeof CHARITABLE || CHARITABLE === null ) {
697 return;
698 }
699
700 var unformat = function( amount ) {
701 return Math.abs( parseFloat( accounting.unformat( amount, CHARITABLE.currency_format_decimal_sep ) ) );
702 }
703
704 var format = function( amount ) {
705 return accounting.formatMoney( amount, {
706 symbol : '',
707 decimal : CHARITABLE.currency_format_decimal_sep,
708 thousand : CHARITABLE.currency_format_thousand_sep,
709 precision : CHARITABLE.currency_format_num_decimals,
710 format : CHARITABLE.currency_format
711 }).trim();
712 }
713
714 $( 'body' ).on( 'change', '.currency-input', function() {
715 var amount = unformat( $( this ).val() );
716
717 if ( $.trim( amount ) > 0 ) {
718 $( this ).val( format( amount ) );
719 }
720 } );
721
722 $( '.currency-input' ).trigger( 'change' );
723 };
724
725
726 $(document).ready( function(){
727
728 $('body').on( 'click', 'th.default_amount-col a', function( e ) {
729
730 e.stopPropagation();
731
732 $('.default_amount-col input').prop('checked', false);
733
734 $(this).blur();
735
736 });
737
738 // if there are stripe keys already entered, allow fields to be added via ajax to allow user to view/edit them.
739
740 $( 'a#charitable-modify-keys' ).on( 'click', function( e ) {
741
742 e.stopPropagation();
743
744 var link = $(this);
745
746 link.css('pointer-events', 'none');
747 link.css('opacity', '0.25');
748
749 var data = {
750 action : 'charitable-' + $(this).data( 'charitable-action' ),
751 args : $(this).data( 'charitable-args' ),
752 nonce : $(this).data( 'nonce' )
753 };
754
755 $.ajax({
756 type: "POST",
757 data: data,
758 dataType: "json",
759 url: ajaxurl,
760 xhrFields: {
761 withCredentials: true
762 },
763 success: function (response) {
764
765 link.closest('tr').after( response.data );
766 link.closest('tr').hide();
767 }
768 }).fail(function (data) {
769 if ( window.console && window.console.log ) {
770 link.css('pointer-events', 'all');
771 link.css('opacity', '1.0');
772 }
773 });
774
775 });
776
777
778 if ( CHARITABLE_ADMIN.Datepicker ) {
779 $( '.charitable-datepicker' ).each( function() {
780 CHARITABLE_ADMIN.Datepicker( $(this ) );
781 });
782 }
783
784 /* check for valid dates and valid input on export and filter forms */
785
786 $(document).on( 'click', '#charitable-campaigns-export-modal form button', function( e ) {
787 e.preventDefault();
788 var form_invalid = false;
789 // check all text fields to ensure dates are proper.
790 $('#charitable-campaigns-export-modal form input[type=text]').each(function(){
791 if ( ( $(this).val() ).trim() !== '' ) {
792 isValidDate = dateIsValid( $(this).val() );
793 if ( isValidDate === false ) {
794 form_invalid = true;
795 $(this).val('');
796 }
797 }
798 })
799 if ( form_invalid === true ) {
800 var today = new Date(),
801 dd = ( '0' + today.getDate() ).slice(-2),
802 mm = ( '0' + ( today.getMonth()+1 ) ).slice(-2),
803 yyyy = today.getFullYear();
804 alert ('You have entered an invalid date format. Please use the following format: yyyy/mm/dd. For example: [' + yyyy + '/' + mm + '/' + dd + ']' );
805 } else {
806 $('#charitable-campaigns-export-modal form').submit();
807 }
808 });
809
810 $(document).on( 'click', '#charitable-campaigns-filter-modal form button', function( e ) {
811 e.preventDefault();
812 var form_invalid = false;
813 // check all text fields to ensure dates are proper.
814 $('#charitable-campaigns-filter-modal form input[type=text]').each(function(){
815 if ( ( $(this).val() ).trim() !== '' ) {
816 isValidDate = dateIsValid( $(this).val() );
817 if ( isValidDate === false ) {
818 form_invalid = true;
819 $(this).val('');
820 }
821 }
822 })
823 if ( form_invalid === true ) {
824 var today = new Date(),
825 dd = ( '0' + today.getDate() ).slice(-2),
826 mm = ( '0' + ( today.getMonth()+1 ) ).slice(-2),
827 yyyy = today.getFullYear();
828 alert ('You have entered an invalid date format. Please use the following format: yyyy/mm/dd. For example: [' + yyyy + '/' + mm + '/' + dd + ']' );
829 } else {
830 $('#charitable-campaigns-filter-modal form').submit();
831 }
832 });
833
834 $(document).on( 'click', '#charitable-donations-export-modal form button', function( e ) {
835 e.preventDefault();
836 var form_invalid = false;
837 // check all text fields to ensure dates are proper.
838 $('#charitable-donations-export-modal form input[type=text]').each(function(){
839 // ignore recurring donation text field - added in version 1.8.1.8.
840 if ( $(this).attr('id') === 'charitable-filter-part-of-recurring' ) {
841 return;
842 }
843 if ( ( $(this).val() ).trim() !== '' ) {
844 isValidDate = dateIsValid( $(this).val() );
845 if ( isValidDate === false ) {
846 form_invalid = true;
847 $(this).val('');
848 }
849 }
850 })
851 if ( form_invalid === true ) {
852 var today = new Date(),
853 dd = ( '0' + today.getDate() ).slice(-2),
854 mm = ( '0' + ( today.getMonth()+1 ) ).slice(-2),
855 yyyy = today.getFullYear();
856 alert ('You have entered an invalid date format. Please use the following format: yyyy/mm/dd. For example: [' + yyyy + '/' + mm + '/' + dd + ']' );
857 } else {
858 $('#charitable-donations-export-modal form').submit();
859 }
860 });
861
862 $(document).on( 'click', '#charitable-donations-filter-modal form button', function( e ) {
863 e.preventDefault();
864 var form_invalid = false;
865 // check all text fields to ensure dates are proper.
866 $('#charitable-donations-filter-modal form input[type=text]').each(function(){
867 if ( ( $(this).val() ).trim() !== '' ) {
868 isValidDate = dateIsValid( $(this).val() );
869 if ( isValidDate === false ) {
870 form_invalid = true;
871 $(this).val('');
872 }
873 }
874 })
875 if ( form_invalid === true ) {
876 var today = new Date(),
877 dd = ( '0' + today.getDate() ).slice(-2),
878 mm = ( '0' + ( today.getMonth()+1 ) ).slice(-2),
879 yyyy = today.getFullYear();
880 alert ('You have entered an invalid date format. Please use the following format: yyyy/mm/dd. For example: [' + yyyy + '/' + mm + '/' + dd + ']' );
881 } else {
882 $('#charitable-donations-filter-modal form').submit();
883 }
884 });
885
886 function dateIsValid( date_string ) {
887
888 const regex = /^(\d{4})(\/|-)(\d{1,2})(\/|-)(\d{1,2})$/;
889
890 if (date_string.match(regex) === null) {
891 return false;
892 }
893
894 const converted_date_string = date_string.replace(/\//g, '-');
895 const date = new Date(converted_date_string);
896 const timestamp = date.getTime();
897 const iso_date_string = date.toISOString();
898
899 if (typeof timestamp !== 'number' || Number.isNaN(timestamp)) {
900 return false;
901 }
902
903 return iso_date_string.startsWith(converted_date_string);
904 }
905
906 $( '#charitable-settings, body.post-type-campaign form#post, body.post-type-donation form#post' ).each( function(){
907 CHARITABLE_ADMIN.Settings( $(this) );
908 });
909
910 $('body.post-type-campaign .handlediv, body.post-type-donation .handlediv').remove();
911 $('body.post-type-campaign .hndle, body.post-type-donation .hndle').removeClass( 'hndle ui-sortable-handle' ).addClass( 'postbox-title' );
912
913 setup_advanced_meta_box();
914 setup_sortable_suggested_donations();
915 setup_sortable_suggested_donations_mini(); // might need to run this again when fields are added/removed
916 toggle_custom_donations_checkbox();
917 setup_charitable_ajax();
918 setup_charitable_toggle();
919 // setup_dashboard_widgets();
920 setup_campaign_end_date_field();
921 setup_actions_form();
922 setup_select2();
923 setup_donor_select();
924 setup_currency_inputs();
925 setup_license_check();
926
927 /* view donor history on donation post type pages */
928
929 $(document).on( 'click', 'a.donor-list-view-donations', function( e ) {
930 e.preventDefault();
931 $( 'table.charitable-donor-history-table' ).toggle();
932 $(this).text($(this).text() == 'Hide Donations' ? 'Show Donations' : 'Hide Donations');
933 });
934
935 /* activate color picker on settings pages that need it */
936 if ( $( 'body.charitable_page_charitable-settings input.charitable-color-field' ).length ) {
937 $( 'input.charitable-color-field' ).wpColorPicker();
938 }
939
940 $('[data-charitable-add-row]').on( 'click', function() {
941 var type = $( this ).data( 'charitable-add-row' );
942
943 if ( 'suggested-amount' === type ) {
944 add_suggested_amount_row($(this));
945 }
946
947 return false;
948 });
949
950 $('.charitable-campaign-suggested-donations').on( 'click', '.charitable-delete-row', function() {
951 delete_suggested_amount_row( $(this) );
952 return false;
953 });
954
955 $('body').on( 'click', '[data-campaign-benefactor-delete]', function() {
956 var $block = $( this ).parents( '.charitable-benefactor' ),
957 data = {
958 action : 'charitable_delete_benefactor',
959 benefactor_id : $(this).data( 'campaign-benefactor-delete' ),
960 nonce : $(this).data( 'nonce' )
961 };
962
963 $.ajax({
964 type: "POST",
965 data: data,
966 dataType: "json",
967 url: ajaxurl,
968 xhrFields: {
969 withCredentials: true
970 },
971 success: function (response) {
972 if ( response.deleted ) {
973 $block.remove();
974 }
975 }
976 }).fail(function (data) {
977 if ( window.console && window.console.log ) {
978 // console.log( 'failed' );
979 // console.log( data );
980 }
981 });
982
983 return false;
984 });
985
986 $('#change-donation-status').on( 'change', function() {
987 $(this).parents( 'form' ).submit();
988 });
989
990 if ( $('table.wp-list-table.posts').length > 0 && 'undefined' !== typeof CHARITABLE && null !== CHARITABLE && 'undefined' !== typeof CHARITABLE.banner ) {
991 var banner_html = CHARITABLE.banner,
992 col_count = 0;
993
994 if ( banner_html === false || '' === banner_html) {
995 return;
996 }
997
998 $('table.wp-list-table.posts thead tr:nth-child(1) td').each(function () {
999 if ($(this).attr('colspan')) {
1000 col_count += +$(this).attr('colspan');
1001 } else {
1002 col_count++;
1003 }
1004 });
1005
1006
1007 $('table.wp-list-table.posts thead tr:nth-child(1) th').each(function () {
1008 if ($(this).attr('colspan')) {
1009 col_count += +$(this).attr('colspan');
1010 } else {
1011 col_count++;
1012 }
1013 });
1014
1015 $('table.wp-list-table.posts').append('<tr class="child"><td colspan="' + ( col_count ) + '">' + CHARITABLE.banner + '</td></tr>');
1016 }
1017
1018 // Handle Square webhooks checkbox visibility
1019 // Removed webhook checkbox functionality - now using conditional display in PHP
1020 var $legacyCheckbox = $('#charitable_settings_gateways_square_square_legacy_settings');
1021 var $legacyNonLegacyContent = $('tr.square-non-legacy');
1022 var $legacyLegacyContent = $('tr.square-legacy');
1023
1024 if ($legacyCheckbox.is(':checked')) {
1025 $legacyNonLegacyContent.hide();
1026 $legacyLegacyContent.show();
1027 } else {
1028 $legacyNonLegacyContent.show();
1029 $legacyLegacyContent.hide();
1030 }
1031 $legacyCheckbox.on('change', function() {
1032 if (!$(this).is(':checked')) {
1033 $legacyNonLegacyContent.show();
1034 $legacyLegacyContent.hide();
1035 } else {
1036 $legacyNonLegacyContent.hide();
1037 $legacyLegacyContent.show();
1038 }
1039 });
1040
1041 // Test Mode Flash Effect
1042 // Check if we should highlight the test mode checkbox
1043 // Only trigger when sessionStorage indicates user came from admin bar badge
1044 if (sessionStorage.getItem('charitable_from_admin_bar') === 'true') {
1045 // Clear the sessionStorage flag immediately
1046 sessionStorage.removeItem('charitable_from_admin_bar');
1047
1048 // Wait for the page to fully load
1049 $(window).on('load', function() {
1050 // Find the test mode checkbox row
1051 var $testModeRow = $('tr.charitable-settings-field.charitable-test-mode-checkbox');
1052
1053 if ($testModeRow.length) {
1054 // Add flash animation class
1055 $testModeRow.addClass('charitable-test-mode-flash');
1056
1057 // Remove the class after animation completes
1058 setTimeout(function() {
1059 $testModeRow.removeClass('charitable-test-mode-flash');
1060 }, 2000);
1061
1062 // Scroll to the row
1063 $('html, body').animate({
1064 scrollTop: $testModeRow.offset().top - 100
1065 }, 800);
1066 }
1067 });
1068 }
1069
1070
1071 });
1072
1073 })( jQuery );