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 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 All 212 releases
charitable / assets / js / campaign-builder / drag-fields.js

drag-fields.js in Charitable – Donation & Fundraising Platform (Donation Forms, Recurring Donations & Fundraising Campaigns) 1.8.11, at assets/js/campaign-builder/drag-fields.js

911 lines 24.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* global charitable_builder, wpchar, CharitableCampaignBuilder, CharitableUtils */
2
3 /**
4 * Campaign Builder Builder Fields Drag-n-Drop module.
5 *
6 * @since 1.8.0
7 */
8
9 'use strict';
10
11 var Charitable = window.Charitable || {};
12
13 Charitable.Admin = Charitable.Admin || {};
14 Charitable.Admin.Builder = Charitable.Admin.Builder || {};
15
16 Charitable.Admin.Builder.DragFields = Charitable.Admin.Builder.DragFields || ( function( document, window, $ ) {
17
18 /**
19 * Elements holder.
20 *
21 * @since 1.8.0
22 *
23 * @type {object}
24 */
25 let el = {};
26
27 /**
28 * Runtime variables.
29 *
30 * @since 1.8.0
31 *
32 * @type {object}
33 */
34 let vars = {};
35
36 /**
37 * Layout field functions wrapper.
38 *
39 * @since 1.8.0
40 *
41 * @type {object}
42 */
43 let fieldLayout;
44
45 /**
46 * Public functions and properties.
47 *
48 * @since 1.8.0
49 *
50 * @type {object}
51 */
52 const app = {
53
54 /**
55 * Start the engine.
56 *
57 * @since 1.8.0
58 */
59 init: function() {
60
61 $( app.ready );
62 },
63
64 /**
65 * DOM is fully loaded.
66 *
67 * @since 1.8.0
68 */
69 ready: function() {
70
71 app.setup();
72 app.initSortableFields();
73
74 app.events();
75 },
76
77 /**
78 * Setup. Prepare some variables.
79 *
80 * @since 1.8.0
81 */
82 setup: function() {
83
84 // Cache DOM elements.
85 el = {
86 $builder: $( '#charitable-builder' ),
87 $sortableFieldsWrap: $( '.charitable-panel-fields .charitable-field-wrap' ),
88 $sortableTabsWrap: $( '.charitable-panel-fields .charitable-tab-wrap' ),
89 $addFieldsButtons: $( '.charitable-add-fields-button' ).not( '.not-draggable' ).not( '.warning-modal' ).not( '.charitable-not-available' ).not( '.charitable-not-installed' ),
90 $preview: $( '.charitable-preview' )
91 };
92
93 wpchar.debug('setup drag-fields'), 'drag-fields';
94 wpchar.debug( el , 'drag-fields' );
95 },
96
97 /**
98 * Bind events.
99 *
100 * @since 1.8.0
101 */
102 events: function() {
103
104 el.$builder
105 .on( 'charitableFieldDragToggle', app.fieldDragToggleEvent );
106
107 el.$builder
108 .on( 'charitableAddNewTab', app.initAfterNewTab );
109
110 // el.$builder
111 // .on( 'charitableFieldPreviewSwitchTabs', app.charitableFieldPreviewSwitchTabs );
112 },
113
114 initAfterNewTab: function( $field, groupID = false ) {
115
116 wpchar.debug('groupID'), 'drag-fields';
117 wpchar.debug( $field , 'drag-fields' );
118 wpchar.debug( groupID , 'drag-fields' );
119 wpchar.debug( el.$sortableTabsWrap , 'drag-fields' );
120
121 el.$sortableTabsWrap = $( '.charitable-panel-fields .charitable-tab-wrap' );
122
123 wpchar.debug( el.$sortableTabsWrap , 'drag-fields' );
124
125 app.initSortableFields();
126
127 CharitableCampaignBuilder.setCampaignNotSaved();
128
129 },
130
131 /**
132 * Disable drag & drop.
133 *
134 * @since 1.7.1
135 * @since 1.8.0 Moved from admin-builder.js.
136 */
137 disableDragAndDrop: function() {
138 wpchar.debug('disableDragAndDrop'), 'drag-fields';
139 el.$addFieldsButtons.filter( '.ui-draggable' ).draggable( 'disable' );
140 el.$sortableFieldsWrap.sortable( 'disable' );
141 el.$sortableFieldsWrap.find( '.charitable-layout-section.ui-sortable' ).sortable( 'disable' ); // was layout-column
142 },
143
144 /**
145 * Enable drag & drop.
146 *
147 * @since 1.7.1
148 * @since 1.8.0 Moved from admin-builder.js.
149 */
150 enableDragAndDrop: function() {
151 wpchar.debug('enableDragAndDrop'), 'drag-fields';
152 el.$addFieldsButtons.filter( '.ui-draggable' ).draggable( 'enable' );
153 el.$sortableFieldsWrap.sortable( 'enable' );
154 el.$sortableFieldsWrap.find( '.charitable-layout-section.ui-sortable' ).sortable( 'enable' ); // was layout-column
155 },
156
157 /**
158 * Show popup in case if field is not draggable, and cancel moving.
159 *
160 * @since 1.7.5
161 * @since 1.8.0 Moved from admin-builder.js.
162 *
163 * @param {jQuery} $field A field or list of fields.
164 * @param {boolean} showPopUp Whether the pop-up should be displayed on dragging attempt.
165 */
166 fieldDragDisable: function( $field, showPopUp = true ) {
167
168 if ( $field.hasClass( 'ui-draggable-disabled' ) ) {
169 $field.draggable( 'enable' );
170
171 return;
172 }
173
174 let startTopPosition;
175
176 $field.draggable( {
177 revert: true,
178 axis: 'y',
179 delay: 100,
180 opacity: 0.75,
181 cursor: 'move',
182 start: function( event, ui ) {
183
184 startTopPosition = ui.position.top;
185 },
186 drag: function( event, ui ) {
187
188 if ( Math.abs( ui.position.top ) - Math.abs( startTopPosition ) > 15 ) {
189
190 if ( showPopUp ) {
191 app.youCantReorderFieldPopup();
192 }
193
194 return false;
195 }
196 }
197 } );
198 },
199
200 /**
201 * Allow field dragging.
202 *
203 * @since 1.7.5
204 * @since 1.8.0 Moved from admin-builder.js.
205 *
206 * @param {jQuery} $field A field or list of fields.
207 */
208 fieldDragEnable: function( $field ) {
209
210 if ( $field.hasClass( 'ui-draggable' ) ) {
211 return;
212 }
213
214 wpchar.debug('fieldDragEnable'), 'drag-fields';
215
216 $field.draggable( 'disable' );
217 },
218
219 /**
220 * Show the error message in the popup that you cannot reorder the field.
221 *
222 * @since 1.7.1
223 * @since 1.8.0 Moved from admin-builder.js.
224 */
225 youCantReorderFieldPopup: function() {
226
227 $.confirm( {
228 title: charitable_builder.heads_up,
229 content: charitable_builder.field_cannot_be_reordered,
230 icon: 'fa fa-exclamation-circle',
231 type: 'red',
232 buttons: {
233 confirm: {
234 text: charitable_builder.ok,
235 btnClass: 'btn-confirm',
236 keys: [ 'enter' ]
237 },
238 },
239 } );
240 },
241
242 /**
243 * Event handler for `charitableFieldDragToggle` event.
244 *
245 * @since 1.8.0
246 *
247 * @param {object} e Event object.
248 * @param {numeric} id Field ID.
249 */
250 fieldDragToggleEvent: function( e, id ) {
251
252 const $field = $( `#charitable-field-${id}` );
253
254 if (
255 $field.hasClass( 'charitable-field-not-draggable' ) ||
256 $field.hasClass( 'charitable-field-stick' )
257 ) {
258 app.fieldDragDisable( $field );
259 wpchar.debug('fieldDragToggleEvent fieldDragDisable'), 'drag-fields';
260 return;
261 }
262
263 app.fieldDragEnable( $field );
264
265 CharitableCampaignBuilder.setCampaignNotSaved();
266
267 },
268
269 /**
270 * Initialize sortable fields in the builder form preview area.
271 *
272 * @since 1.8.0
273 */
274 initSortableFields: function() {
275
276 wpchar.debug( 'initSortableFields' , 'drag-fields' );
277 wpchar.debug( el.$sortableFieldsWrap , 'drag-fields' );
278 wpchar.debug( el.$sortableTabsWrap , 'drag-fields' );
279
280 // app.initSortableContainer( el.$sortableFieldsWrap );
281
282 app.initSortableContainer( el.$sortableTabsWrap );
283
284 el.$builder.find( '.charitable-panel-fields .charitable-field-wrap' ).each( function() {
285 app.initSortableContainer( $( this ) );
286 } );
287
288 //app.fieldDragDisable( $( '.charitable-field-not-draggable, .charitable-field-stick' ) );
289 app.initDraggableFields();
290 },
291
292 /**
293 * Initialize sortable container with fields.
294 *
295 * @since 1.8.0
296 *
297 * @param {jQuery} $sortable Container to make sortable.
298 */
299 initSortableContainer: function( $sortable ) { // eslint-disable-line max-lines-per-function
300
301 wpchar.debug('initSortableContainer'), 'drag-fields';
302
303 let fieldId,
304 fieldType,
305 isNewField;
306
307 $sortable.sortable( {
308 items: '> .charitable-field:not(.charitable-field-stick):not(.no-fields-preview)',
309 connectWith: '.charitable-field-wrap, .charitable-tab-wrap', // , .charitable-layout-column was in here
310 delay: 100,
311 opacity: 0.75,
312 cursor: 'move',
313 cancel: '.charitable-field-not-draggable',
314 placeholder: 'charitable-field-drag-placeholder',
315 appendTo: '.charitable-design-wrap',
316 zindex: 10000,
317 tolerance: 'pointer',
318 distance: 1,
319 start: function( e, ui ) {
320
321 wpchar.debug( 'vars' , 'drag-fields' );
322 wpchar.debug( vars , 'drag-fields' );
323 wpchar.debug('start sortable via drag-fields.js'), 'drag-fields';
324 wpchar.debug( 'ui' , 'drag-fields' );
325 wpchar.debug( ui , 'drag-fields' );
326 wpchar.debug( 'ui.item' , 'drag-fields' );
327 wpchar.debug( ui.item , 'drag-fields' );
328 fieldId = ui.item.data( 'field-id' );
329 fieldType = ui.item.data( 'field-type' ) || vars.fieldType;
330 // fieldType = $field.data( 'field-type' )
331
332 if ( ! isNewField ) {
333 vars.section = ui.item.closest('.charitable-field-section');
334 } else {
335 vars.section = false;
336 }
337
338 isNewField = typeof fieldId === 'undefined';
339 wpchar.debug(' fieldId: ' + fieldId + ' - fieldType: ' + fieldType + ' - newField: ' + isNewField + ' - section: ' + vars.section), 'drag-fields';
340 // $fieldOption = $( '#charitable-field-option-' + fieldId );
341
342 vars.fieldReceived = false;
343 vars.fieldRejected = false;
344 vars.$sortableStart = $sortable;
345 vars.fieldType = fieldType;
346 vars.startPosition = ui.item.first().index();
347
348 $(this).attr('data-previndex', ui.item.index());
349
350
351 },
352 beforeStop: function( e, ui ) { // eslint-disable-line
353
354 wpchar.debug('beforeStop ==== sortable via drag-fields.js'), 'drag-fields';
355
356 },
357 stop: function( e, ui ) {
358
359 wpchar.debug('stop ==== sortable via drag-fields.js'), 'drag-fields';
360
361 wpchar.debug ( ui , 'drag-fields' );
362
363 const $field = ui.item.first();
364
365 ui.placeholder.removeClass( 'charitable-field-drag-not-allowed' );
366 $field.removeClass( 'charitable-field-drag-not-allowed' );
367
368 $field
369 .removeClass( 'charitable-field-dragging' )
370 .removeClass( 'charitable-field-drag-over' )
371 .attr( 'style', '' );
372
373 el.$builder.trigger( 'charitableFieldMove', ui );
374
375
376 },
377 over: function( e, ui ) { // eslint-disable-line complexity
378
379 wpchar.debug('over ==== sortable via drag-fields.js'), 'drag-fields';
380
381 const $field = ui.item.first(),
382 $target = $(e.target),
383 $placeholder = $target.find('.charitable-field-drag-placeholder'),
384 isColumn = $target.hasClass('charitable-layout-column'),
385 targetClass = isColumn ? ' charitable-field-drag-to-column' : '',
386 helper = {
387 width: $target.outerWidth(),
388 height: $field.outerHeight()
389 };
390
391
392 fieldId = $field.data( 'field-id' );
393 fieldType = $field.data( 'field-type' ) || vars.fieldType;
394 isNewField = typeof fieldId === 'undefined';
395
396 // Adjust helper size according to the placeholder size.
397 $field
398 .addClass( 'charitable-field-dragging' + targetClass )
399 .css( {
400 'width': isColumn ? helper.width - 5 : helper.width,
401 'height': 'auto',
402 } );
403
404 // Adjust placeholder height according to the height of the helper.
405 $placeholder
406 .removeClass( 'charitable-field-drag-not-allowed' )
407 .css( {
408 'height': isNewField ? helper.height + 18 : helper.height,
409 } );
410
411 // Drop to this place is not allowed.
412 if (
413 ! fieldLayout.isFieldAllowedInColum( fieldType ) &&
414 isColumn
415 ) {
416 $placeholder.addClass( 'charitable-field-drag-not-allowed' );
417 $field.addClass( 'charitable-field-drag-not-allowed' );
418 }
419
420 // Skip if it is the existing field.
421 if ( ! isNewField ) {
422 return;
423 }
424
425 $field
426 .addClass( 'charitable-field-drag-over' )
427 .removeClass( 'charitable-field-drag-out' );
428
429
430 },
431 out: function( e, ui ) { // eslint-disable-line
432
433 wpchar.debug('out ==== sortable via drag-fields.js'), 'drag-fields';
434
435
436 },
437 receive: function( e, ui ) { // eslint-disable-line complexity
438
439 wpchar.debug('receive ==== sortable via drag-fields.js'), 'drag-fields';
440
441 wpchar.debug ( ui , 'drag-fields' );
442 wpchar.debug ( ui.helper , 'drag-fields' );
443 wpchar.debug ( ui.item , 'drag-fields' );
444 wpchar.debug ( ui.position , 'drag-fields' );
445 wpchar.debug ( ui.originalPosition , 'drag-fields' );
446 wpchar.debug ( ui.sender , 'drag-fields' );
447 wpchar.debug ( ui.placeholder , 'drag-fields' );
448
449
450
451 },
452 update: function( e, ui ) { // eslint-disable-line
453
454 wpchar.debug('update ==== sortable via drag-fields.js'), 'drag-fields';
455
456 var newIndex = ui.item.index();
457 var oldIndex = $(this).attr('data-previndex');
458 var element_id = ui.item.attr('class');
459
460 $(this).attr('data-current-index', ui.item.index());
461 wpchar.debug ( $( this ) );
462
463
464 $(this).removeAttr('data-previndex');
465
466 // decalare a bunch of variables.
467
468 const $field = $( ui.helper || ui.item );
469
470 var area = $sortable.hasClass('charitable-field-wrap') ? 'fields' : 'tabs',
471 column_id = 'fields' === area ? parseInt($field.closest('.charitable-field-column').data('column-id')) : false,
472 section_id = 'fields' === area ? parseInt($field.closest('.charitable-field-section').data('section-id')) : false,
473 tab_id = 'tabs' === area ? parseInt($field.closest('.tab_content_item').data('tab-id')) : false,
474 fieldId = $field.data('field-id'),
475 fieldType = $field.data('field-type') || vars.fieldType;
476
477 const isNewField = typeof fieldId === 'undefined',
478 isColumn = $sortable.hasClass('charitable-layout-column'),
479 numfieldsDonateButton = el.$preview.find('.charitable-field.charitable-field-donate-button').length,
480 numfieldsDonationForm = el.$preview.find('.charitable-field.charitable-field-donation-form').length;
481
482 wpchar.debug( $sortable );
483 wpchar.debug( $sortable.data( 'ui-sortable' ) );
484 wpchar.debug( $sortable.data( 'ui-sortable' ).currentItem );
485
486 var currentIndex = $(this).attr('data-current-index');
487
488 wpchar.debug ( currentIndex, 'currentIndex' );
489 wpchar.debug ( $( this ) );
490 let position = typeof currentIndex === 'undefined' ? -1 : currentIndex;
491 // let position = typeof $sortable.data( 'ui-sortable' ).currentItem === 'undefined' ? -1 : $sortable.data( 'ui-sortable' ).currentItem.index();
492
493 // disable any add field buttons until this is finished.
494 el.$builder.find( '.charitable-add-fields .charitable-add-fields-button' ).prop( 'disabled', true );
495
496 // you shouldn't try to add a donation form if a donation button is already added.
497 if ( fieldType === 'donation-form' ) {
498
499 if ( numfieldsDonateButton > 0 ) {
500
501 $('.ui-draggable-dragging').css('opacity', '0');
502
503 $.confirm( {
504 title: charitable_builder.heads_up,
505 content: charitable_builder.donation_form_donation_button,
506 icon: 'fa fa-exclamation-circle',
507 type: 'red',
508 buttons: {
509 confirm: {
510 text: charitable_builder.remove_donation_button,
511 btnClass: 'btn-confirm',
512 keys: [ 'enter' ],
513 action: function() {
514 el.$preview.find('.charitable-field.charitable-field-donate-button').each( function() {
515 var fieldDeleteId = $( this ).data('field-id');
516 if ( parseInt( fieldDeleteId ) > 0 ) {
517 CharitableCampaignBuilder.fieldDelete( fieldDeleteId, false );
518 }
519 } );
520 $('.ui-draggable-dragging').css('opacity', '1.0');
521 app.addFieldAfterDrag( $field, isNewField, isColumn, position, area, column_id, tab_id, section_id, fieldId, fieldType, $sortable )
522 },
523 },
524 cancel: {
525 text: charitable_builder.cancel,
526 keys: [ 'esc' ],
527 action: function() {
528 el.$builder.find( '.charitable-add-fields .charitable-add-fields-button' ).prop( 'disabled', false );
529 $field.remove();
530 return;
531 },
532 },
533 },
534 } );
535
536 } else if ( numfieldsDonationForm > 1 ) {
537
538 $('.ui-draggable-dragging').css('opacity', '0');
539
540 $.confirm( {
541 title: charitable_builder.heads_up,
542 content: charitable_builder.only_one_donation_form,
543 icon: 'fa fa-exclamation-circle',
544 type: 'red',
545 buttons: {
546 confirm: {
547 text: charitable_builder.remove_donation_form,
548 btnClass: 'btn-confirm',
549 keys: [ 'enter' ],
550 action: function() {
551 el.$preview.find('.charitable-field.charitable-field-donation-form').each( function() {
552 var fieldDeleteId = $( this ).data('field-id');
553 if ( parseInt( fieldDeleteId ) > 0 ) {
554 CharitableCampaignBuilder.fieldDelete( fieldDeleteId, false );
555 }
556 } );
557 $('.ui-draggable-dragging').css('opacity', '1.0');
558 app.addFieldAfterDrag( $field, isNewField, isColumn, position, area, column_id, tab_id, section_id, fieldId, fieldType, $sortable )
559 },
560 },
561 cancel: {
562 text: charitable_builder.cancel,
563 keys: [ 'esc' ],
564 action: function() {
565 el.$builder.find( '.charitable-add-fields .charitable-add-fields-button' ).prop( 'disabled', false );
566 $field.remove();
567 return;
568 },
569 },
570 },
571 } );
572
573 } else {
574
575 app.addFieldAfterDrag( $field, isNewField, isColumn, position, area, column_id, tab_id, section_id, fieldId, fieldType, $sortable, vars.section )
576
577 }
578
579 } else if ( fieldType === 'donate-button' && numfieldsDonationForm > 0 ) {
580
581 $('.ui-draggable-dragging').css('opacity', '0');
582
583 $.confirm( {
584 title: charitable_builder.heads_up,
585 content: charitable_builder.donation_button_donation_form,
586 icon: 'fa fa-exclamation-circle',
587 type: 'red',
588 buttons: {
589 confirm: {
590 text: charitable_builder.remove_donation_form,
591 btnClass: 'btn-confirm',
592 keys: [ 'enter' ],
593 action: function() {
594 el.$preview.find('.charitable-field.charitable-field-donation-form').each( function() {
595 var fieldDeleteId = $( this ).data('field-id');
596 if ( parseInt( fieldDeleteId ) > 0 ) {
597 CharitableCampaignBuilder.fieldDelete( fieldDeleteId, false );
598 }
599 } );
600 $('.ui-draggable-dragging').css('opacity', '1.0');
601 app.addFieldAfterDrag( $field, isNewField, isColumn, position, area, column_id, tab_id, section_id, fieldId, fieldType, $sortable, vars.section )
602 },
603 },
604 cancel: {
605 text: charitable_builder.cancel,
606 keys: [ 'esc' ],
607 action: function() {
608 el.$builder.find( '.charitable-add-fields .charitable-add-fields-button' ).prop( 'disabled', false );
609 $field.remove();
610 return;
611 },
612 },
613 },
614 } );
615
616 } else {
617
618 app.addFieldAfterDrag( $field, isNewField, isColumn, position, area, column_id, tab_id, section_id, fieldId, fieldType, $sortable, vars.section );
619
620 }
621
622
623 },
624 change: function( e, ui ) { // eslint-disable-line
625
626 wpchar.debug('change ==== sortable via drag-fields.js'), 'drag-fields';
627
628
629 },
630 sort: function( e, ui ) { // eslint-disable-line
631
632 wpchar.debug('sort ==== sortable via drag-fields.js'), 'drag-fields';
633 CharitableCampaignBuilder.setCampaignNotSaved();
634
635
636 },
637 } );
638 },
639
640 addFieldAfterDrag( $field, isNewField, isColumn, position, area, column_id, tab_id, section_id, fieldId, fieldType, $sortable, $section ) {
641
642 if ( isNewField ) {
643
644 // add the spinning loader icon to the field (because this requires an ajax call and there might be a delay)
645 $field
646 .addClass( 'charitable-field-drag-over charitable-field-drag-pending' )
647 .removeClass( 'charitable-field-drag-out' )
648 .append( CharitableCampaignBuilder.settings.spinnerInline )
649 .css( 'width', '100%' );
650
651 wpchar.debug( 'addFieldAfterDrag' );
652 wpchar.debug( isColumn );
653 wpchar.debug( position );
654
655 CharitableCampaignBuilder.fieldAdd(
656 vars.fieldType,
657 {
658 position: isColumn ? position - 1 : position,
659 placeholder: $field,
660 $sortable: $sortable,
661 column_id: column_id,
662 tab_id: tab_id,
663 section_id: section_id,
664 area: area,
665 section: false,
666 }
667 );
668
669 } else {
670
671 CharitableCampaignBuilder.fieldMove(
672 vars.fieldType,
673 {
674 // position: isColumn ? position - 1 : position,
675 field: $field,
676 fieldId: fieldId,
677 $sortable: $sortable,
678 column_id: column_id,
679 tab_id: tab_id,
680 section_id: section_id,
681 area: area,
682 section: $section,
683 }
684 );
685
686 }
687
688 CharitableCampaignBuilder.setCampaignNotSaved();
689
690 },
691
692 getChildIndex(childDiv) {
693 // Find the parent div of the given child div
694 var parentDiv = childDiv.parent();
695
696 // Find all the child divs within the parent div
697 var childDivs = parentDiv.children();
698
699 // Loop through the child divs to find the index of the given child div
700 for (var i = 0; i < childDivs.length; i++) {
701 if (childDivs[i] === childDiv[0]) {
702 // Return the index (1-based) if found
703 return i + 1;
704 }
705 }
706
707 // If the given child div is not found, return -1
708 return -1;
709 },
710
711 /**
712 * Initialize draggable fields buttons.
713 *
714 * @since 1.8.0
715 */
716 initDraggableFields: function() {
717
718 el.$addFieldsButtons.draggable( {
719 connectToSortable: '.charitable-field-wrap, .charitable-tab-wrap', // .charitable-layout-column was in there
720 delay: 200,
721 cancel: false,
722 scroll: false,
723 opacity: 0.75,
724 appendTo: '.charitable-design-wrap',
725 zindex: 10000,
726 helper: function() {
727
728 let $this = $( this ),
729 $el = $( '<div class="charitable-field-drag-out charitable-field-drag">' );
730
731 vars.fieldType = $this.data( 'field-type' );
732
733
734
735 wpchar.debug ('initDraggableFields start '), 'drag-fields';
736 wpchar.debug( vars , 'drag-fields' );
737 wpchar.debug( $el.html( $this.html(), 'drag-fields' ) );
738 wpchar.debug ('initDraggableFields end'), 'drag-fields';
739
740 return $el.html( $this.html() );
741 },
742
743 start: function( e, ui ) {
744
745 let event = CharitableUtils.triggerEvent(
746 el.$builder,
747 'charitableFieldAddDragStart',
748 [ vars.fieldType, ui ]
749 );
750
751 // wpchar.debug('event'), 'drag-fields';
752 // wpchar.debug(event), 'drag-fields';
753 // wpchar.debug(event.isDefaultPrevented), 'drag-fields';
754
755 // Allow callbacks on `charitableFieldAddDragStart` to cancel dragging the field
756 // by triggering `event.preventDefault()`.
757 if ( event.isDefaultPrevented() ) {
758 return false;
759 }
760 },
761 } );
762 },
763
764 /**
765 * Revert moving the field to the column.
766 *
767 * @since 1.8.0
768 *
769 * @param {jQuery} $field Field object.
770 */
771 revertMoveFieldToColumn: function( $field ) {
772
773 const isNewField = $field.data( 'field-id' ) === undefined;
774
775 if ( isNewField ) {
776
777 // Remove the field.
778 $field.remove();
779
780 return;
781 }
782
783 // Restore existing field on the previous position.
784 $field = $field.detach();
785
786 const $fieldInStartPosition = vars.$sortableStart
787 .find( '> .charitable-field' )
788 .eq( vars.startPosition );
789
790 $field
791 .removeClass( 'charitable-field-dragging' )
792 .removeClass( 'charitable-field-drag-over' )
793 .attr( 'style', '' );
794
795 if ( $fieldInStartPosition.length ) {
796 $fieldInStartPosition.before( $field );
797
798 return;
799 }
800
801 vars.$sortableStart.append( $field );
802 },
803 };
804
805 /**
806 * Layout field functions holder.
807 *
808 * @since 1.8.0
809 *
810 * @type {object}
811 */
812 fieldLayout = {
813
814 /**
815 * Position field in the column inside the Layout Field.
816 *
817 * @since 1.8.0
818 *
819 * @param {number} fieldId Field Id.
820 * @param {number} position The new position of the field inside the column.
821 * @param {jQuery} $sortable Sortable column container.
822 **/
823 positionFieldInColumn: function( fieldId, position, $sortable ) {
824
825 if ( ! Charitable.Admin.Builder.FieldLayout ) {
826 return;
827 }
828
829 Charitable.Admin.Builder.FieldLayout.positionFieldInColumn( fieldId, position, $sortable );
830 },
831
832 /**
833 * Receive field to column inside the Layout Field.
834 *
835 * @since 1.8.0
836 *
837 * @param {number} fieldId Field Id.
838 * @param {number} position Field position inside the column.
839 * @param {jQuery} $sortable Sortable column container.
840 **/
841 receiveFieldToColumn: function( fieldId, position, $sortable ) {
842
843 if ( ! Charitable.Admin.Builder.FieldLayout ) {
844 return;
845 }
846
847 Charitable.Admin.Builder.FieldLayout.receiveFieldToColumn( fieldId, position, $sortable );
848 },
849
850 /**
851 * Update field options according to the position of the field.
852 * Event `charitableFieldOptionTabToggle` handler.
853 *
854 * @since 1.8.0
855 *
856 * @param {Event} e Event.
857 * @param {int} fieldId Field id.
858 */
859 fieldOptionsUpdate: function( e, fieldId ) {
860
861 if ( ! Charitable.Admin.Builder.FieldLayout ) {
862 return;
863 }
864
865 Charitable.Admin.Builder.FieldLayout.fieldOptionsUpdate( e, fieldId );
866 },
867
868 /**
869 * Reorder fields options of the fields in columns.
870 * It is not critical, but it's better to keep some order in the `fields` data array.
871 *
872 * @since 1.8.0
873 *
874 * @param {jQuery} $layoutField Layout field object.
875 */
876 reorderLayoutFieldsOptions: function( $layoutField ) {
877
878 if ( ! Charitable.Admin.Builder.FieldLayout ) {
879 return;
880 }
881
882 Charitable.Admin.Builder.FieldLayout.reorderLayoutFieldsOptions( $layoutField );
883 },
884
885 /**
886 * Whether the field type is allowed to be in column.
887 *
888 * @since 1.8.0
889 *
890 * @param {string} fieldType Field ty to check.
891 *
892 * @returns {boolean} True if allowed.
893 */
894 isFieldAllowedInColum: function( fieldType ) {
895
896 if ( ! Charitable.Admin.Builder.FieldLayout ) {
897 return true;
898 }
899
900 return Charitable.Admin.Builder.FieldLayout.isFieldAllowedInColum( fieldType );
901 },
902 };
903
904 // Provide access to public functions/properties.
905 return app;
906
907 }( document, window, jQuery ) ); // eslint-disable-line
908
909 // Initialize.
910 Charitable.Admin.Builder.DragFields.init();
911