PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / 6.5.4
Secure Custom Fields v6.5.4
6.9.5 6.9.4 6.9.3 6.9.2 6.9.1 6.9.0 6.8.9 6.8.7 6.8.8 6.8.6 6.8.4 6.8.5 trunk 6.4.0-beta1 6.4.0-beta2 6.4.1 6.4.1-beta3 6.4.1-beta4 6.4.1-beta5 6.4.1-beta6 6.4.1-beta7 6.4.2 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.5.5 6.5.6 6.5.7 6.6.0 6.7.0 6.7.1 6.8.0 6.8.1 6.8.2 6.8.3
secure-custom-fields / assets / build / js / pro / acf-pro-input.js
secure-custom-fields / assets / build / js / pro Last commit date
acf-pro-blocks.asset.php 1 year ago acf-pro-blocks.js 1 year ago acf-pro-blocks.js.map 1 year ago acf-pro-blocks.min.asset.php 1 year ago acf-pro-blocks.min.js 1 year ago acf-pro-field-group.asset.php 1 year ago acf-pro-field-group.js 1 year ago acf-pro-field-group.js.map 1 year ago acf-pro-field-group.min.asset.php 1 year ago acf-pro-field-group.min.js 1 year ago acf-pro-input.asset.php 1 year ago acf-pro-input.js 1 year ago acf-pro-input.js.map 1 year ago acf-pro-input.min.asset.php 1 year ago acf-pro-input.min.js 1 year ago acf-pro-ui-options-page.asset.php 1 year ago acf-pro-ui-options-page.js 1 year ago acf-pro-ui-options-page.js.map 1 year ago acf-pro-ui-options-page.min.asset.php 1 year ago acf-pro-ui-options-page.min.js 1 year ago index.php 1 year ago
acf-pro-input.js
2120 lines
1 /******/ (() => { // webpackBootstrap
2 /******/ var __webpack_modules__ = ({
3
4 /***/ "./assets/src/js/pro/_acf-field-flexible-content.js":
5 /*!**********************************************************!*\
6 !*** ./assets/src/js/pro/_acf-field-flexible-content.js ***!
7 \**********************************************************/
8 /***/ (() => {
9
10 (function ($) {
11 var Field = acf.Field.extend({
12 type: 'flexible_content',
13 wait: '',
14 events: {
15 'click [data-name="add-layout"]': 'onClickAdd',
16 'click [data-name="duplicate-layout"]': 'onClickDuplicate',
17 'click [data-name="remove-layout"]': 'onClickRemove',
18 'click [data-name="collapse-layout"]': 'onClickCollapse',
19 showField: 'onShow',
20 unloadField: 'onUnload',
21 mouseover: 'onHover'
22 },
23 $control: function () {
24 return this.$('.acf-flexible-content:first');
25 },
26 $layoutsWrap: function () {
27 return this.$('.acf-flexible-content:first > .values');
28 },
29 $layouts: function () {
30 return this.$('.acf-flexible-content:first > .values > .layout');
31 },
32 $layout: function (index) {
33 return this.$('.acf-flexible-content:first > .values > .layout:eq(' + index + ')');
34 },
35 $clonesWrap: function () {
36 return this.$('.acf-flexible-content:first > .clones');
37 },
38 $clones: function () {
39 return this.$('.acf-flexible-content:first > .clones > .layout');
40 },
41 $clone: function (name) {
42 return this.$('.acf-flexible-content:first > .clones > .layout[data-layout="' + name + '"]');
43 },
44 $actions: function () {
45 return this.$('.acf-actions:last');
46 },
47 $button: function () {
48 return this.$('.acf-actions:last .button');
49 },
50 $popup: function () {
51 return this.$('.tmpl-popup:last');
52 },
53 getPopupHTML: function () {
54 var html = this.$popup().html();
55 var $html = $(html);
56 var self = this;
57
58 // modify popup
59 $html.find('[data-layout]').each(function () {
60 var $a = $(this);
61 var min = $a.data('min') || 0;
62 var max = $a.data('max') || 0;
63 var name = $a.data('layout') || '';
64 var count = self.countLayouts(name);
65
66 // max
67 if (max && count >= max) {
68 $a.addClass('disabled');
69 return;
70 }
71
72 // min
73 if (min && count < min) {
74 var required = min - count;
75 var title = acf.__('{required} {label} {identifier} required (min {min})');
76 var identifier = acf._n('layout', 'layouts', required);
77
78 // translate
79 title = title.replace('{required}', required);
80 title = title.replace('{label}', name); // 5.5.0
81 title = title.replace('{identifier}', identifier);
82 title = title.replace('{min}', min);
83
84 // badge
85 $a.append('<span class="badge" title="' + title + '">' + required + '</span>');
86 }
87 });
88
89 // update
90 html = $html.outerHTML();
91 return html;
92 },
93 getValue: function () {
94 return this.$layouts().length;
95 },
96 allowRemove: function () {
97 var min = parseInt(this.get('min'));
98 return !min || min < this.val();
99 },
100 allowAdd: function () {
101 var max = parseInt(this.get('max'));
102 return !max || max > this.val();
103 },
104 isFull: function () {
105 var max = parseInt(this.get('max'));
106 return max && this.val() >= max;
107 },
108 addSortable: function (self) {
109 // bail early if max 1 row
110 if (this.get('max') == 1) {
111 return;
112 }
113
114 // add sortable
115 this.$layoutsWrap().sortable({
116 items: '> .layout',
117 handle: '> .acf-fc-layout-handle',
118 forceHelperSize: true,
119 forcePlaceholderSize: true,
120 scroll: true,
121 stop: function (event, ui) {
122 self.render();
123 },
124 update: function (event, ui) {
125 self.$input().trigger('change');
126 }
127 });
128 },
129 addCollapsed: function () {
130 var indexes = preference.load(this.get('key'));
131
132 // bail early if no collapsed
133 if (!indexes) {
134 return false;
135 }
136
137 // loop
138 this.$layouts().each(function (i) {
139 if (indexes.indexOf(i) > -1) {
140 $(this).addClass('-collapsed');
141 }
142 });
143 },
144 addUnscopedEvents: function (self) {
145 // invalidField
146 this.on('invalidField', '.layout', function (e) {
147 self.onInvalidField(e, $(this));
148 });
149 },
150 initialize: function () {
151 // add unscoped events
152 this.addUnscopedEvents(this);
153
154 // add collapsed
155 this.addCollapsed();
156
157 // disable clone
158 acf.disable(this.$clonesWrap(), this.cid);
159
160 // render
161 this.render();
162 },
163 render: function () {
164 // update order number
165 this.$layouts().each(function (i) {
166 $(this).find('.acf-fc-layout-order:first').html(i + 1);
167 });
168
169 // empty
170 if (this.val() == 0) {
171 this.$control().addClass('-empty');
172 } else {
173 this.$control().removeClass('-empty');
174 }
175
176 // max
177 if (this.isFull()) {
178 this.$button().addClass('disabled');
179 } else {
180 this.$button().removeClass('disabled');
181 }
182 },
183 onShow: function (e, $el, context) {
184 // get sub fields
185 var fields = acf.getFields({
186 is: ':visible',
187 parent: this.$el
188 });
189
190 // trigger action
191 // - ignore context, no need to pass through 'conditional_logic'
192 // - this is just for fields like google_map to render itself
193 acf.doAction('show_fields', fields);
194 },
195 countLayouts: function (name) {
196 return this.$layouts().filter(function () {
197 return $(this).data('layout') === name;
198 }).length;
199 },
200 countLayoutsByName: function (currentLayout) {
201 const layoutMax = currentLayout.data('max');
202 if (!layoutMax) {
203 return true;
204 }
205 const name = currentLayout.data('layout') || '';
206 const count = this.countLayouts(name);
207 if (count >= layoutMax) {
208 let text = acf.__('This field has a limit of {max} {label} {identifier}');
209 const identifier = acf._n('layout', 'layouts', layoutMax);
210 const layoutLabel = '"' + currentLayout.data('label') + '"';
211 text = text.replace('{max}', layoutMax);
212 text = text.replace('{label}', layoutLabel);
213 text = text.replace('{identifier}', identifier);
214 this.showNotice({
215 text: text,
216 type: 'warning'
217 });
218 return false;
219 }
220 return true;
221 },
222 validateAdd: function () {
223 // return true if allowed
224 if (this.allowAdd()) {
225 return true;
226 }
227 var max = this.get('max');
228 var text = acf.__('This field has a limit of {max} {label} {identifier}');
229 var identifier = acf._n('layout', 'layouts', max);
230 text = text.replace('{max}', max);
231 text = text.replace('{label}', '');
232 text = text.replace('{identifier}', identifier);
233 this.showNotice({
234 text: text,
235 type: 'warning'
236 });
237 return false;
238 },
239 onClickAdd: function (e, $el) {
240 // validate
241 if (!this.validateAdd()) {
242 return false;
243 }
244
245 // within layout
246 var $layout = null;
247 if ($el.hasClass('acf-icon')) {
248 $layout = $el.closest('.layout');
249 $layout.addClass('-hover');
250 }
251
252 // new popup
253 var popup = new Popup({
254 target: $el,
255 targetConfirm: false,
256 text: this.getPopupHTML(),
257 context: this,
258 confirm: function (e, $el) {
259 // check disabled
260 if ($el.hasClass('disabled')) {
261 return;
262 }
263
264 // add
265 this.add({
266 layout: $el.data('layout'),
267 before: $layout
268 });
269 },
270 cancel: function () {
271 if ($layout) {
272 $layout.removeClass('-hover');
273 }
274 }
275 });
276
277 // add extra event
278 popup.on('click', '[data-layout]', 'onConfirm');
279 },
280 add: function (args) {
281 // defaults
282 args = acf.parseArgs(args, {
283 layout: '',
284 before: false
285 });
286
287 // validate
288 if (!this.allowAdd()) {
289 return false;
290 }
291
292 // add row
293 var $el = acf.duplicate({
294 target: this.$clone(args.layout),
295 append: this.proxy(function ($el, $el2) {
296 // append
297 if (args.before) {
298 args.before.before($el2);
299 } else {
300 this.$layoutsWrap().append($el2);
301 }
302
303 // enable
304 acf.enable($el2, this.cid);
305
306 // render
307 this.render();
308 })
309 });
310
311 // trigger change for validation errors
312 this.$input().trigger('change');
313 return $el;
314 },
315 onClickDuplicate: function (e, $el) {
316 var $layout = $el.closest('.layout');
317 // Validate each layout's max count.
318 if (!this.countLayoutsByName($layout.first())) {
319 return false;
320 }
321
322 // Validate with warning.
323 if (!this.validateAdd()) {
324 return false;
325 }
326
327 // get layout and duplicate it.
328 this.duplicateLayout($layout);
329 },
330 duplicateLayout: function ($layout) {
331 // Validate without warning.
332 if (!this.allowAdd()) {
333 return false;
334 }
335 var fieldKey = this.get('key');
336
337 // Duplicate layout.
338 var $el = acf.duplicate({
339 target: $layout,
340 // Provide a custom renaming callback to avoid renaming parent row attributes.
341 rename: function (name, value, search, replace) {
342 // Rename id attributes from "field_1-search" to "field_1-replace".
343 if (name === 'id' || name === 'for') {
344 return value.replace(fieldKey + '-' + search, fieldKey + '-' + replace);
345
346 // Rename name and for attributes from "[field_1][search]" to "[field_1][replace]".
347 } else {
348 return value.replace(fieldKey + '][' + search, fieldKey + '][' + replace);
349 }
350 },
351 before: function ($el) {
352 acf.doAction('unmount', $el);
353 },
354 after: function ($el, $el2) {
355 acf.doAction('remount', $el);
356 }
357 });
358
359 // trigger change for validation errors
360 this.$input().trigger('change');
361
362 // Update order numbers.
363 this.render();
364
365 // Draw focus to layout.
366 acf.focusAttention($el);
367
368 // Return new layout.
369 return $el;
370 },
371 validateRemove: function () {
372 // return true if allowed
373 if (this.allowRemove()) {
374 return true;
375 }
376 var min = this.get('min');
377 var text = acf.__('This field requires at least {min} {label} {identifier}');
378 var identifier = acf._n('layout', 'layouts', min);
379
380 // replace
381 text = text.replace('{min}', min);
382 text = text.replace('{label}', '');
383 text = text.replace('{identifier}', identifier);
384
385 // add notice
386 this.showNotice({
387 text: text,
388 type: 'warning'
389 });
390 return false;
391 },
392 onClickRemove: function (e, $el) {
393 var $layout = $el.closest('.layout');
394
395 // Bypass confirmation when holding down "shift" key.
396 if (e.shiftKey) {
397 return this.removeLayout($layout);
398 }
399
400 // add class
401 $layout.addClass('-hover');
402
403 // add tooltip
404 var tooltip = acf.newTooltip({
405 confirmRemove: true,
406 target: $el,
407 context: this,
408 confirm: function () {
409 this.removeLayout($layout);
410 },
411 cancel: function () {
412 $layout.removeClass('-hover');
413 }
414 });
415 },
416 removeLayout: function ($layout) {
417 // reference
418 var self = this;
419 var endHeight = this.getValue() == 1 ? 60 : 0;
420
421 // remove
422 acf.remove({
423 target: $layout,
424 endHeight: endHeight,
425 complete: function () {
426 // trigger change to allow attachment save
427 self.$input().trigger('change');
428
429 // render
430 self.render();
431 }
432 });
433 },
434 onClickCollapse: function (e, $el) {
435 var $layout = $el.closest('.layout');
436
437 // toggle
438 if (this.isLayoutClosed($layout)) {
439 this.openLayout($layout);
440 } else {
441 this.closeLayout($layout);
442 }
443 },
444 isLayoutClosed: function ($layout) {
445 return $layout.hasClass('-collapsed');
446 },
447 openLayout: function ($layout) {
448 $layout.removeClass('-collapsed');
449 acf.doAction('show', $layout, 'collapse');
450 },
451 closeLayout: function ($layout) {
452 $layout.addClass('-collapsed');
453 acf.doAction('hide', $layout, 'collapse');
454
455 // render
456 // - no change could happen if layout was already closed. Only render when closing
457 this.renderLayout($layout);
458 },
459 renderLayout: function ($layout) {
460 var $input = $layout.children('input');
461 var prefix = $input.attr('name').replace('[acf_fc_layout]', '');
462
463 // ajax data
464 var ajaxData = {
465 action: 'acf/fields/flexible_content/layout_title',
466 field_key: this.get('key'),
467 i: $layout.index(),
468 layout: $layout.data('layout'),
469 value: acf.serialize($layout, prefix)
470 };
471
472 // ajax
473 $.ajax({
474 url: acf.get('ajaxurl'),
475 data: acf.prepareForAjax(ajaxData),
476 dataType: 'html',
477 type: 'post',
478 success: function (html) {
479 if (html) {
480 $layout.children('.acf-fc-layout-handle').html(html);
481 }
482 }
483 });
484 },
485 onUnload: function () {
486 var indexes = [];
487
488 // loop
489 this.$layouts().each(function (i) {
490 if ($(this).hasClass('-collapsed')) {
491 indexes.push(i);
492 }
493 });
494
495 // allow null
496 indexes = indexes.length ? indexes : null;
497
498 // set
499 preference.save(this.get('key'), indexes);
500 },
501 onInvalidField: function (e, $layout) {
502 // open if is collapsed
503 if (this.isLayoutClosed($layout)) {
504 this.openLayout($layout);
505 }
506 },
507 onHover: function () {
508 // add sortable
509 this.addSortable(this);
510
511 // remove event
512 this.off('mouseover');
513 }
514 });
515 acf.registerFieldType(Field);
516
517 /**
518 * Popup
519 *
520 * description
521 *
522 * @date 7/4/18
523 * @since ACF 5.6.9
524 *
525 * @param type $var Description. Default.
526 * @return type Description.
527 */
528
529 var Popup = acf.models.TooltipConfirm.extend({
530 events: {
531 'click [data-layout]': 'onConfirm',
532 'click [data-event="cancel"]': 'onCancel'
533 },
534 render: function () {
535 // set HTML
536 this.html(this.get('text'));
537
538 // add class
539 this.$el.addClass('acf-fc-popup');
540 }
541 });
542
543 /**
544 * conditions
545 *
546 * description
547 *
548 * @date 9/4/18
549 * @since ACF 5.6.9
550 *
551 * @param type $var Description. Default.
552 * @return type Description.
553 */
554
555 // register existing conditions
556 acf.registerConditionForFieldType('hasValue', 'flexible_content');
557 acf.registerConditionForFieldType('hasNoValue', 'flexible_content');
558 acf.registerConditionForFieldType('lessThan', 'flexible_content');
559 acf.registerConditionForFieldType('greaterThan', 'flexible_content');
560
561 // state
562 var preference = new acf.Model({
563 name: 'this.collapsedLayouts',
564 key: function (key, context) {
565 var count = this.get(key + context) || 0;
566
567 // update
568 count++;
569 this.set(key + context, count, true);
570
571 // modify fieldKey
572 if (count > 1) {
573 key += '-' + count;
574 }
575 return key;
576 },
577 load: function (key) {
578 var key = this.key(key, 'load');
579 var data = acf.getPreference(this.name);
580 if (data && data[key]) {
581 return data[key];
582 } else {
583 return false;
584 }
585 },
586 save: function (key, value) {
587 var key = this.key(key, 'save');
588 var data = acf.getPreference(this.name) || {};
589
590 // delete
591 if (value === null) {
592 delete data[key];
593
594 // append
595 } else {
596 data[key] = value;
597 }
598
599 // allow null
600 if ($.isEmptyObject(data)) {
601 data = null;
602 }
603
604 // save
605 acf.setPreference(this.name, data);
606 }
607 });
608 })(jQuery);
609
610 /***/ }),
611
612 /***/ "./assets/src/js/pro/_acf-field-gallery.js":
613 /*!*************************************************!*\
614 !*** ./assets/src/js/pro/_acf-field-gallery.js ***!
615 \*************************************************/
616 /***/ (() => {
617
618 (function ($) {
619 var Field = acf.Field.extend({
620 type: 'gallery',
621 events: {
622 'click .acf-gallery-add': 'onClickAdd',
623 'click .acf-gallery-edit': 'onClickEdit',
624 'click .acf-gallery-remove': 'onClickRemove',
625 'click .acf-gallery-attachment': 'onClickSelect',
626 'click .acf-gallery-close': 'onClickClose',
627 'change .acf-gallery-sort': 'onChangeSort',
628 'click .acf-gallery-update': 'onUpdate',
629 mouseover: 'onHover',
630 showField: 'render'
631 },
632 actions: {
633 validation_begin: 'onValidationBegin',
634 validation_failure: 'onValidationFailure',
635 resize: 'onResize'
636 },
637 onValidationBegin: function () {
638 acf.disable(this.$sideData(), this.cid);
639 },
640 onValidationFailure: function () {
641 acf.enable(this.$sideData(), this.cid);
642 },
643 $control: function () {
644 return this.$('.acf-gallery');
645 },
646 $collection: function () {
647 return this.$('.acf-gallery-attachments');
648 },
649 $attachments: function () {
650 return this.$('.acf-gallery-attachment');
651 },
652 $attachment: function (id) {
653 return this.$('.acf-gallery-attachment[data-id="' + id + '"]');
654 },
655 $active: function () {
656 return this.$('.acf-gallery-attachment.active');
657 },
658 $main: function () {
659 return this.$('.acf-gallery-main');
660 },
661 $side: function () {
662 return this.$('.acf-gallery-side');
663 },
664 $sideData: function () {
665 return this.$('.acf-gallery-side-data');
666 },
667 isFull: function () {
668 var max = parseInt(this.get('max'));
669 var count = this.$attachments().length;
670 return max && count >= max;
671 },
672 getValue: function () {
673 // vars
674 var val = [];
675
676 // loop
677 this.$attachments().each(function () {
678 val.push($(this).data('id'));
679 });
680
681 // return
682 return val.length ? val : false;
683 },
684 addUnscopedEvents: function (self) {
685 // invalidField
686 this.on('change', '.acf-gallery-side', function (e) {
687 self.onUpdate(e, $(this));
688 });
689 },
690 addSortable: function (self) {
691 // add sortable
692 this.$collection().sortable({
693 items: '.acf-gallery-attachment',
694 forceHelperSize: true,
695 forcePlaceholderSize: true,
696 scroll: true,
697 start: function (event, ui) {
698 ui.placeholder.html(ui.item.html());
699 ui.placeholder.removeAttr('style');
700 },
701 update: function (event, ui) {
702 self.$input().trigger('change');
703 }
704 });
705
706 // resizable
707 this.$control().resizable({
708 handles: 's',
709 minHeight: 200,
710 stop: function (event, ui) {
711 acf.update_user_setting('gallery_height', ui.size.height);
712 }
713 });
714 },
715 initialize: function () {
716 // add unscoped events
717 this.addUnscopedEvents(this);
718
719 // render
720 this.render();
721 },
722 render: function () {
723 // vars
724 var $sort = this.$('.acf-gallery-sort');
725 var $add = this.$('.acf-gallery-add');
726 var count = this.$attachments().length;
727
728 // disable add
729 if (this.isFull()) {
730 $add.addClass('disabled');
731 } else {
732 $add.removeClass('disabled');
733 }
734
735 // disable select
736 if (!count) {
737 $sort.addClass('disabled');
738 } else {
739 $sort.removeClass('disabled');
740 }
741
742 // resize
743 this.resize();
744 },
745 resize: function () {
746 // vars
747 var width = this.$control().width();
748 var target = 150;
749 var columns = Math.round(width / target);
750
751 // max columns = 8
752 columns = Math.min(columns, 8);
753
754 // update data
755 this.$control().attr('data-columns', columns);
756 },
757 onResize: function () {
758 this.resize();
759 },
760 openSidebar: function () {
761 // add class
762 this.$control().addClass('-open');
763
764 // hide bulk actions
765 // should be done with CSS
766 //this.$main().find('.acf-gallery-sort').hide();
767
768 // vars
769 var width = this.$control().width() / 3;
770 width = parseInt(width);
771 width = Math.max(width, 350);
772
773 // animate
774 this.$('.acf-gallery-side-inner').css({
775 width: width - 1
776 });
777 this.$side().animate({
778 width: width - 1
779 }, 250);
780 this.$main().animate({
781 right: width
782 }, 250);
783 },
784 closeSidebar: function () {
785 // remove class
786 this.$control().removeClass('-open');
787
788 // clear selection
789 this.$active().removeClass('active');
790
791 // disable sidebar
792 acf.disable(this.$side());
793
794 // animate
795 var $sideData = this.$('.acf-gallery-side-data');
796 this.$main().animate({
797 right: 0
798 }, 250);
799 this.$side().animate({
800 width: 0
801 }, 250, function () {
802 $sideData.html('');
803 });
804 },
805 onClickAdd: function (e, $el) {
806 // validate
807 if (this.isFull()) {
808 this.showNotice({
809 text: acf.__('Maximum selection reached'),
810 type: 'warning'
811 });
812 return;
813 }
814
815 // new frame
816 var frame = acf.newMediaPopup({
817 mode: 'select',
818 title: acf.__('Add Image to Gallery'),
819 field: this.get('key'),
820 multiple: 'add',
821 library: this.get('library'),
822 allowedTypes: this.get('mime_types'),
823 selected: this.val(),
824 select: $.proxy(function (attachment, i) {
825 this.appendAttachment(attachment, i);
826 }, this)
827 });
828 },
829 appendAttachment: function (attachment, i) {
830 // vars
831 attachment = this.validateAttachment(attachment);
832
833 // bail early if is full
834 if (this.isFull()) {
835 return;
836 }
837
838 // bail early if already exists
839 if (this.$attachment(attachment.id).length) {
840 return;
841 }
842
843 // html
844 var html = ['<div class="acf-gallery-attachment" data-id="' + attachment.id + '">', '<input type="hidden" value="' + attachment.id + '" name="' + this.getInputName() + '[]">', '<div class="margin" title="">', '<div class="thumbnail">', '<img src="" alt="">', '</div>', '<div class="filename"></div>', '</div>', '<div class="actions">', '<a href="#" class="acf-icon -cancel dark acf-gallery-remove" data-id="' + attachment.id + '"></a>', '</div>', '</div>'].join('');
845 var $html = $(html);
846
847 // append
848 this.$collection().append($html);
849
850 // move to beginning
851 if (this.get('insert') === 'prepend') {
852 var $before = this.$attachments().eq(i);
853 if ($before.length) {
854 $before.before($html);
855 }
856 }
857
858 // render attachment
859 this.renderAttachment(attachment);
860
861 // render
862 this.render();
863
864 // trigger change
865 this.$input().trigger('change');
866 },
867 validateAttachment: function (attachment) {
868 // defaults
869 attachment = acf.parseArgs(attachment, {
870 id: '',
871 url: '',
872 alt: '',
873 title: '',
874 filename: '',
875 type: 'image'
876 });
877
878 // WP attachment
879 if (attachment.attributes) {
880 attachment = attachment.attributes;
881
882 // preview size
883 var url = acf.isget(attachment, 'sizes', this.get('preview_size'), 'url');
884 if (url !== null) {
885 attachment.url = url;
886 }
887 }
888
889 // return
890 return attachment;
891 },
892 renderAttachment: function (attachment) {
893 // vars
894 attachment = this.validateAttachment(attachment);
895
896 // vars
897 var $el = this.$attachment(attachment.id);
898
899 // Image type.
900 if (attachment.type == 'image') {
901 // Remove filename.
902 $el.find('.filename').remove();
903
904 // Other file type.
905 } else {
906 // Check for attachment featured image.
907 var image = acf.isget(attachment, 'image', 'src');
908 if (image !== null) {
909 attachment.url = image;
910 }
911
912 // Update filename text.
913 $el.find('.filename').text(attachment.filename);
914 }
915
916 // Default to mimetype icon.
917 if (!attachment.url) {
918 attachment.url = acf.get('mimeTypeIcon');
919 $el.addClass('-icon');
920 }
921
922 // update els
923 $el.find('img').attr({
924 src: attachment.url,
925 alt: attachment.alt,
926 title: attachment.title
927 });
928
929 // update val
930 acf.val($el.find('input'), attachment.id);
931 },
932 editAttachment: function (id) {
933 // new frame
934 var frame = acf.newMediaPopup({
935 mode: 'edit',
936 title: acf.__('Edit Image'),
937 button: acf.__('Update Image'),
938 attachment: id,
939 field: this.get('key'),
940 select: $.proxy(function (attachment, i) {
941 this.renderAttachment(attachment);
942 // todo - render sidebar
943 }, this)
944 });
945 },
946 onClickEdit: function (e, $el) {
947 var id = $el.data('id');
948 if (id) {
949 this.editAttachment(id);
950 }
951 },
952 removeAttachment: function (id) {
953 // close sidebar (if open)
954 this.closeSidebar();
955
956 // remove attachment
957 this.$attachment(id).remove();
958
959 // render
960 this.render();
961
962 // trigger change
963 this.$input().trigger('change');
964 },
965 onClickRemove: function (e, $el) {
966 // prevent event from triggering click on attachment
967 e.preventDefault();
968 e.stopPropagation();
969
970 //remove
971 var id = $el.data('id');
972 if (id) {
973 this.removeAttachment(id);
974 }
975 },
976 selectAttachment: function (id) {
977 // vars
978 var $el = this.$attachment(id);
979
980 // bail early if already active
981 if ($el.hasClass('active')) {
982 return;
983 }
984
985 // step 1
986 var step1 = this.proxy(function () {
987 // save any changes in sidebar
988 this.$side().find(':focus').trigger('blur');
989
990 // clear selection
991 this.$active().removeClass('active');
992
993 // add selection
994 $el.addClass('active');
995
996 // open sidebar
997 this.openSidebar();
998
999 // call step 2
1000 step2();
1001 });
1002
1003 // step 2
1004 var step2 = this.proxy(function () {
1005 const ajaxData = {
1006 action: 'acf/fields/gallery/get_attachment',
1007 nonce: this.get('nonce'),
1008 field_key: this.get('key'),
1009 id: id
1010 };
1011
1012 // abort prev ajax call
1013 if (this.has('xhr')) {
1014 this.get('xhr').abort();
1015 }
1016
1017 // loading
1018 acf.showLoading(this.$sideData());
1019
1020 // get HTML
1021 var xhr = $.ajax({
1022 url: acf.get('ajaxurl'),
1023 data: acf.prepareForAjax(ajaxData),
1024 type: 'post',
1025 dataType: 'html',
1026 cache: false,
1027 success: step3
1028 });
1029
1030 // update
1031 this.set('xhr', xhr);
1032 });
1033
1034 // step 3
1035 var step3 = this.proxy(function (html) {
1036 // bail early if no html
1037 if (!html) {
1038 return;
1039 }
1040
1041 // vars
1042 var $side = this.$sideData();
1043
1044 // render
1045 $side.html(html);
1046
1047 // remove acf form data
1048 $side.find('.compat-field-acf-form-data').remove();
1049
1050 // merge tables
1051 $side.find('> table.form-table > tbody').append($side.find('> .compat-attachment-fields > tbody > tr'));
1052
1053 // setup fields
1054 acf.doAction('append', $side);
1055 });
1056
1057 // run step 1
1058 step1();
1059 },
1060 onClickSelect: function (e, $el) {
1061 var id = $el.data('id');
1062 if (id) {
1063 this.selectAttachment(id);
1064 }
1065 },
1066 onClickClose: function (e, $el) {
1067 this.closeSidebar();
1068 },
1069 onChangeSort: function (e, $el) {
1070 // Bail early if is disabled.
1071 if ($el.hasClass('disabled')) {
1072 return;
1073 }
1074
1075 // Get sort val.
1076 var val = $el.val();
1077 if (!val) {
1078 return;
1079 }
1080
1081 // find ids
1082 var ids = [];
1083 this.$attachments().each(function () {
1084 ids.push($(this).data('id'));
1085 });
1086
1087 // step 1
1088 var step1 = this.proxy(function () {
1089 const ajaxData = {
1090 action: 'acf/fields/gallery/get_sort_order',
1091 nonce: this.get('nonce'),
1092 field_key: this.get('key'),
1093 ids: ids,
1094 sort: val
1095 };
1096
1097 // get results
1098 var xhr = $.ajax({
1099 url: acf.get('ajaxurl'),
1100 dataType: 'json',
1101 type: 'post',
1102 cache: false,
1103 data: acf.prepareForAjax(ajaxData),
1104 success: step2
1105 });
1106 });
1107
1108 // step 2
1109 var step2 = this.proxy(function (json) {
1110 // validate
1111 if (!acf.isAjaxSuccess(json)) {
1112 return;
1113 }
1114
1115 // reverse order
1116 json.data.reverse();
1117
1118 // loop
1119 json.data.map(function (id) {
1120 this.$collection().prepend(this.$attachment(id));
1121 }, this);
1122 });
1123
1124 // call step 1
1125 step1();
1126 },
1127 onUpdate: function (e, $el) {
1128 // vars
1129 var $submit = this.$('.acf-gallery-update');
1130
1131 // validate
1132 if ($submit.hasClass('disabled')) {
1133 return;
1134 }
1135
1136 // serialize data
1137 const ajaxData = acf.serialize(this.$sideData());
1138
1139 // loading
1140 $submit.addClass('disabled');
1141 $submit.before('<i class="acf-loading"></i> ');
1142
1143 // Append AJAX action and nonce.
1144 ajaxData.action = 'acf/fields/gallery/update_attachment';
1145 ajaxData.nonce = this.get('nonce');
1146 ajaxData.field_key = this.get('key');
1147
1148 // ajax
1149 $.ajax({
1150 url: acf.get('ajaxurl'),
1151 data: acf.prepareForAjax(ajaxData),
1152 type: 'post',
1153 dataType: 'json',
1154 complete: function () {
1155 $submit.removeClass('disabled');
1156 $submit.prev('.acf-loading').remove();
1157 }
1158 });
1159 },
1160 onHover: function () {
1161 // add sortable
1162 this.addSortable(this);
1163
1164 // remove event
1165 this.off('mouseover');
1166 }
1167 });
1168 acf.registerFieldType(Field);
1169
1170 // register existing conditions
1171 acf.registerConditionForFieldType('hasValue', 'gallery');
1172 acf.registerConditionForFieldType('hasNoValue', 'gallery');
1173 acf.registerConditionForFieldType('selectionLessThan', 'gallery');
1174 acf.registerConditionForFieldType('selectionGreaterThan', 'gallery');
1175 })(jQuery);
1176
1177 /***/ }),
1178
1179 /***/ "./assets/src/js/pro/_acf-field-repeater.js":
1180 /*!**************************************************!*\
1181 !*** ./assets/src/js/pro/_acf-field-repeater.js ***!
1182 \**************************************************/
1183 /***/ (() => {
1184
1185 (function ($) {
1186 var Field = acf.Field.extend({
1187 type: 'repeater',
1188 wait: '',
1189 page: 1,
1190 nextRowNum: 0,
1191 events: {
1192 'click a[data-event="add-row"]': 'onClickAdd',
1193 'click a[data-event="duplicate-row"]': 'onClickDuplicate',
1194 'click a[data-event="remove-row"]': 'onClickRemove',
1195 'click a[data-event="collapse-row"]': 'onClickCollapse',
1196 'click a[data-event="first-page"]:not(.disabled)': 'onClickFirstPage',
1197 'click a[data-event="last-page"]:not(.disabled)': 'onClickLastPage',
1198 'click a[data-event="prev-page"]:not(.disabled)': 'onClickPrevPage',
1199 'click a[data-event="next-page"]:not(.disabled)': 'onClickNextPage',
1200 'change .current-page': 'onChangeCurrentPage',
1201 'click .acf-order-input-wrap': 'onClickRowOrder',
1202 'blur .acf-order-input': 'onBlurRowOrder',
1203 'change .acf-order-input': 'onChangeRowOrder',
1204 'changed:total_rows': 'onChangeTotalRows',
1205 showField: 'onShow',
1206 unloadField: 'onUnload',
1207 mouseover: 'onHover',
1208 change: 'onChangeField'
1209 },
1210 $control: function () {
1211 return this.$('.acf-repeater:first');
1212 },
1213 $table: function () {
1214 return this.$('table:first');
1215 },
1216 $tbody: function () {
1217 return this.$('tbody:first');
1218 },
1219 $rows: function () {
1220 return this.$('tbody:first > tr').not('.acf-clone, .acf-deleted');
1221 },
1222 $row: function (index) {
1223 return this.$('tbody:first > tr:eq(' + index + ')');
1224 },
1225 $clone: function () {
1226 return this.$('tbody:first > tr.acf-clone');
1227 },
1228 $actions: function () {
1229 return this.$('.acf-actions:last');
1230 },
1231 $button: function () {
1232 return this.$('.acf-actions:last .button');
1233 },
1234 $firstPageButton: function () {
1235 return this.$('.acf-tablenav:last .first-page');
1236 },
1237 $prevPageButton: function () {
1238 return this.$('.acf-tablenav:last .prev-page');
1239 },
1240 $nextPageButton: function () {
1241 return this.$('.acf-tablenav:last .next-page');
1242 },
1243 $lastPageButton: function () {
1244 return this.$('.acf-tablenav:last .last-page');
1245 },
1246 $pageInput: function () {
1247 return this.$('.current-page:last');
1248 },
1249 totalPages: function () {
1250 const totalPages = this.$('.acf-total-pages:last').text();
1251 return parseInt(totalPages);
1252 },
1253 getValue: function () {
1254 return this.$rows().length;
1255 },
1256 allowRemove: function () {
1257 let numRows = this.val();
1258 let minRows = parseInt(this.get('min'));
1259 if (this.get('pagination')) {
1260 numRows = this.get('total_rows');
1261 }
1262 return !minRows || minRows < numRows;
1263 },
1264 allowAdd: function () {
1265 let numRows = this.val();
1266 let maxRows = parseInt(this.get('max'));
1267 if (this.get('pagination')) {
1268 numRows = this.get('total_rows');
1269 }
1270 return !maxRows || maxRows > numRows;
1271 },
1272 addSortable: function (self) {
1273 // bail early if max 1 row
1274 if (this.get('max') == 1) {
1275 return;
1276 }
1277
1278 // Bail early if using pagination.
1279 if (this.get('pagination')) {
1280 return;
1281 }
1282
1283 // add sortable
1284 this.$tbody().sortable({
1285 items: '> tr',
1286 handle: '> td.order',
1287 forceHelperSize: true,
1288 forcePlaceholderSize: true,
1289 scroll: true,
1290 stop: function (event, ui) {
1291 self.render();
1292 },
1293 update: function (event, ui) {
1294 self.$input().trigger('change');
1295 }
1296 });
1297 },
1298 addCollapsed: function () {
1299 // vars
1300 var indexes = preference.load(this.get('key'));
1301
1302 // bail early if no collapsed
1303 if (!indexes) {
1304 return false;
1305 }
1306
1307 // loop
1308 this.$rows().each(function (i) {
1309 if (indexes.indexOf(i) > -1) {
1310 if ($(this).find('.-collapsed-target').length) {
1311 $(this).addClass('-collapsed');
1312 }
1313 }
1314 });
1315 },
1316 addUnscopedEvents: function (self) {
1317 // invalidField
1318 this.on('invalidField', '.acf-row', function (e) {
1319 var $row = $(this);
1320 if (self.isCollapsed($row)) {
1321 self.expand($row);
1322 }
1323 });
1324
1325 // Listen for changes to fields, so we can persist them in the DOM.
1326 if (this.get('pagination')) {
1327 this.on('change', 'input, select, textarea', function (e) {
1328 const $changed = $(e.currentTarget);
1329 if (!$changed.hasClass('acf-order-input') && !$changed.hasClass('acf-row-status')) {
1330 self.onChangeField(e, $(this));
1331 }
1332 });
1333 }
1334 this.listenForSavedMetaBoxes();
1335 },
1336 initialize: function () {
1337 // add unscoped events
1338 this.addUnscopedEvents(this);
1339
1340 // add collapsed
1341 this.addCollapsed();
1342
1343 // disable clone
1344 acf.disable(this.$clone(), this.cid);
1345
1346 // Set up the next row number.
1347 if (this.get('pagination')) {
1348 this.nextRowNum = this.get('total_rows');
1349 }
1350
1351 // render
1352 this.render();
1353 },
1354 render: function (update_order_numbers = true) {
1355 // Update order number.
1356 if (update_order_numbers) {
1357 this.$rows().each(function (i) {
1358 $(this).find('> .order > span').html(i + 1);
1359 });
1360 }
1361
1362 // Extract vars.
1363 var $control = this.$control();
1364 var $button = this.$button();
1365
1366 // empty
1367 if (this.val() == 0) {
1368 $control.addClass('-empty');
1369 } else {
1370 $control.removeClass('-empty');
1371 }
1372
1373 // Reached max rows.
1374 if (!this.allowAdd()) {
1375 $control.addClass('-max');
1376 $button.addClass('disabled');
1377 } else {
1378 $control.removeClass('-max');
1379 $button.removeClass('disabled');
1380 }
1381 if (this.get('pagination')) {
1382 this.maybeDisablePagination();
1383 }
1384
1385 // Reached min rows (not used).
1386 //if( !this.allowRemove() ) {
1387 // $control.addClass('-min');
1388 //} else {
1389 // $control.removeClass('-min');
1390 //}
1391 },
1392 listenForSavedMetaBoxes: function () {
1393 if (!acf.isGutenbergPostEditor() || !this.get('pagination')) {
1394 return;
1395 }
1396 let checkedMetaBoxes = true;
1397 wp.data.subscribe(() => {
1398 if (wp.data.select('core/edit-post').isSavingMetaBoxes()) {
1399 checkedMetaBoxes = false;
1400 } else {
1401 if (!checkedMetaBoxes) {
1402 checkedMetaBoxes = true;
1403 this.set('total_rows', 0, true);
1404 this.ajaxLoadPage(true);
1405 }
1406 }
1407 });
1408 },
1409 incrementTotalRows: function () {
1410 let totalRows = this.get('total_rows');
1411 this.set('total_rows', ++totalRows, true);
1412 },
1413 decrementTotalRows: function () {
1414 let totalRows = this.get('total_rows');
1415 this.set('total_rows', --totalRows, true);
1416 },
1417 validateAdd: function () {
1418 // return true if allowed
1419 if (this.allowAdd()) {
1420 return true;
1421 }
1422
1423 // vars
1424 var max = this.get('max');
1425 var text = acf.__('Maximum rows reached ({max} rows)');
1426
1427 // replace
1428 text = text.replace('{max}', max);
1429
1430 // add notice
1431 this.showNotice({
1432 text: text,
1433 type: 'warning'
1434 });
1435
1436 // return
1437 return false;
1438 },
1439 onClickAdd: function (e, $el) {
1440 // validate
1441 if (!this.validateAdd()) {
1442 return false;
1443 }
1444
1445 // add above row
1446 if ($el.hasClass('acf-icon')) {
1447 this.add({
1448 before: $el.closest('.acf-row')
1449 });
1450
1451 // default
1452 } else {
1453 this.add();
1454 }
1455 },
1456 add: function (args) {
1457 // validate
1458 if (!this.allowAdd()) {
1459 return false;
1460 }
1461
1462 // defaults
1463 args = acf.parseArgs(args, {
1464 before: false
1465 });
1466
1467 // add row
1468 var $el = acf.duplicate({
1469 target: this.$clone(),
1470 append: this.proxy(function ($el, $el2) {
1471 // append
1472 if (args.before) {
1473 args.before.before($el2);
1474 } else {
1475 $el.before($el2);
1476 }
1477
1478 // remove clone class
1479 $el2.removeClass('acf-clone');
1480
1481 // enable
1482 acf.enable($el2, this.cid);
1483 })
1484 });
1485 if (this.get('pagination')) {
1486 this.incrementTotalRows();
1487 if (false !== args.before) {
1488 // If the row was inserted above an existing row, try to keep that order.
1489 const prevRowNum = parseInt(args.before.find('.acf-row-number').first().text()) || 0;
1490 let newRowNum = prevRowNum;
1491 if (newRowNum && !args.before.hasClass('acf-inserted') && !args.before.hasClass('acf-added')) {
1492 --newRowNum;
1493 }
1494 if (args.before.hasClass('acf-divider')) {
1495 args.before.removeClass('acf-divider');
1496 $el.addClass('acf-divider');
1497 }
1498 this.updateRowStatus($el, 'inserted');
1499 this.updateRowStatus($el, 'reordered', newRowNum);
1500
1501 // Hide the row numbers to avoid confusion with existing rows.
1502 $el.find('.acf-row-number').first().hide().text(newRowNum);
1503 if (!$el.find('.acf-order-input-wrap').hasClass('disabled')) {
1504 let message = acf.__('Order will be assigned upon save');
1505 $el.find('.acf-order-input-wrap').addClass('disabled');
1506 $el.find('.acf-row-number').first().after('<span title="' + message + '">-</span>');
1507 }
1508 $el.find('.acf-order-input').first().hide();
1509 $el.attr('data-inserted', newRowNum);
1510 } else {
1511 this.nextRowNum++;
1512 $el.find('.acf-order-input').first().val(this.nextRowNum);
1513 $el.find('.acf-row-number').first().text(this.nextRowNum);
1514 this.updateRowStatus($el, 'added');
1515 if (!this.$tbody().find('.acf-divider').length) {
1516 $el.addClass('acf-divider');
1517 }
1518 }
1519 $el.find('.acf-input:first').find('input:not([type=hidden]), select, textarea').first().trigger('focus');
1520 }
1521
1522 // Render and trigger change for validation errors.
1523 this.render();
1524 this.$input().trigger('change');
1525 return $el;
1526 },
1527 onClickDuplicate: function (e, $el) {
1528 // Validate with warning.
1529 if (!this.validateAdd()) {
1530 return false;
1531 }
1532
1533 // get layout and duplicate it.
1534 var $row = $el.closest('.acf-row');
1535 this.duplicateRow($row);
1536 },
1537 duplicateRow: function ($row) {
1538 // Validate without warning.
1539 if (!this.allowAdd()) {
1540 return false;
1541 }
1542
1543 // Vars.
1544 var fieldKey = this.get('key');
1545
1546 // Duplicate row.
1547 var $el = acf.duplicate({
1548 target: $row,
1549 // Provide a custom renaming callback to avoid renaming parent row attributes.
1550 rename: function (name, value, search, replace) {
1551 // Rename id attributes from "field_1-search" to "field_1-replace".
1552 if (name === 'id' || name === 'for') {
1553 return value.replace(fieldKey + '-' + search, fieldKey + '-' + replace);
1554
1555 // Rename name and for attributes from "[field_1][search]" to "[field_1][replace]".
1556 } else {
1557 return value.replace(fieldKey + '][' + search, fieldKey + '][' + replace);
1558 }
1559 },
1560 before: function ($el) {
1561 acf.doAction('unmount', $el);
1562 },
1563 after: function ($el, $el2) {
1564 acf.doAction('remount', $el);
1565 }
1566 });
1567 if (this.get('pagination')) {
1568 this.incrementTotalRows();
1569
1570 // If the row was inserted above an existing row, try to keep that order.
1571 const prevRowNum = parseInt($row.find('.acf-row-number').first().text()) || 0;
1572 this.updateRowStatus($el, 'inserted');
1573 this.updateRowStatus($el, 'reordered', prevRowNum);
1574
1575 // Hide the row numbers to avoid confusion with existing rows.
1576 $el.find('.acf-row-number').first().hide();
1577 if (!$el.find('.acf-order-input-wrap').hasClass('disabled')) {
1578 let message = acf.__('Order will be assigned upon save');
1579 $el.find('.acf-order-input-wrap').addClass('disabled');
1580 $el.find('.acf-row-number').first().after('<span title="' + message + '">-</span>');
1581 }
1582 $el.find('.acf-order-input').first().hide();
1583 $el.attr('data-inserted', prevRowNum);
1584 $el.removeClass('acf-divider');
1585 }
1586
1587 // trigger change for validation errors
1588 this.$input().trigger('change');
1589
1590 // Update order numbers.
1591 this.render();
1592
1593 // Focus on new row.
1594 acf.focusAttention($el);
1595
1596 // Return new layout.
1597 return $el;
1598 },
1599 validateRemove: function () {
1600 // return true if allowed
1601 if (this.allowRemove()) {
1602 return true;
1603 }
1604
1605 // vars
1606 var min = this.get('min');
1607 var text = acf.__('Minimum rows not reached ({min} rows)');
1608
1609 // replace
1610 text = text.replace('{min}', min);
1611
1612 // add notice
1613 this.showNotice({
1614 text: text,
1615 type: 'warning'
1616 });
1617
1618 // return
1619 return false;
1620 },
1621 onClickRemove: function (e, $el) {
1622 var $row = $el.closest('.acf-row');
1623
1624 // Bypass confirmation when holding down "shift" key.
1625 if (e.shiftKey) {
1626 return this.remove($row);
1627 }
1628
1629 // add class
1630 $row.addClass('-hover');
1631
1632 // add tooltip
1633 var tooltip = acf.newTooltip({
1634 confirmRemove: true,
1635 target: $el,
1636 context: this,
1637 confirm: function () {
1638 this.remove($row);
1639 },
1640 cancel: function () {
1641 $row.removeClass('-hover');
1642 }
1643 });
1644 },
1645 onClickRowOrder: function (e, $el) {
1646 if (!this.get('pagination')) {
1647 return;
1648 }
1649 if ($el.hasClass('disabled')) {
1650 return;
1651 }
1652 $el.find('.acf-row-number').hide();
1653 $el.find('.acf-order-input').show().trigger('select');
1654 },
1655 onBlurRowOrder: function (e, $el) {
1656 this.onChangeRowOrder(e, $el, false);
1657 },
1658 onChangeRowOrder: function (e, $el, update = true) {
1659 if (!this.get('pagination')) {
1660 return;
1661 }
1662 const $row = $el.closest('.acf-row');
1663 const $orderSpan = $row.find('.acf-row-number').first();
1664 let hrOrder = $el.val();
1665 $row.find('.acf-order-input').first().hide();
1666 if (!acf.isNumeric(hrOrder) || parseFloat(hrOrder) < 0) {
1667 $orderSpan.show();
1668 return;
1669 }
1670 hrOrder = Math.round(hrOrder);
1671 const newOrder = hrOrder - 1;
1672 $el.val(hrOrder);
1673 $orderSpan.text(hrOrder).show();
1674 if (update) {
1675 this.updateRowStatus($row, 'reordered', newOrder);
1676 }
1677 },
1678 onChangeTotalRows: function () {
1679 const perPage = parseInt(this.get('per_page')) || 20;
1680 const totalRows = parseInt(this.get('total_rows')) || 0;
1681 const totalPages = Math.ceil(totalRows / perPage);
1682
1683 // Update the total pages in pagination.
1684 this.$('.acf-total-pages:last').text(totalPages);
1685 this.nextRowNum = totalRows;
1686
1687 // If the current page no longer exists, load the last page.
1688 if (this.page > totalPages) {
1689 this.page = totalPages;
1690 this.ajaxLoadPage();
1691 }
1692 },
1693 remove: function ($row) {
1694 const self = this;
1695 if (this.get('pagination')) {
1696 this.decrementTotalRows();
1697
1698 // If using pagination and the row had already been saved, just hide the row instead of deleting it.
1699 if ($row.data('id').includes('row-')) {
1700 this.updateRowStatus($row, 'deleted');
1701 $row.hide();
1702 self.$input().trigger('change');
1703 self.render(false);
1704 return;
1705 } else if ($row.hasClass('acf-divider')) {
1706 $row.next('.acf-added').addClass('acf-divider');
1707 }
1708 }
1709
1710 // If not using pagination, delete the actual row.
1711 acf.remove({
1712 target: $row,
1713 endHeight: 0,
1714 complete: function () {
1715 // trigger change to allow attachment save
1716 self.$input().trigger('change');
1717
1718 // render
1719 self.render();
1720
1721 // sync collapsed order
1722 //self.sync();
1723 }
1724 });
1725 },
1726 isCollapsed: function ($row) {
1727 return $row.hasClass('-collapsed');
1728 },
1729 collapse: function ($row) {
1730 $row.addClass('-collapsed');
1731 acf.doAction('hide', $row, 'collapse');
1732 },
1733 expand: function ($row) {
1734 $row.removeClass('-collapsed');
1735 acf.doAction('show', $row, 'collapse');
1736 },
1737 onClickCollapse: function (e, $el) {
1738 // vars
1739 var $row = $el.closest('.acf-row');
1740 var isCollpased = this.isCollapsed($row);
1741
1742 // shift
1743 if (e.shiftKey) {
1744 $row = this.$rows();
1745 }
1746
1747 // toggle
1748 if (isCollpased) {
1749 this.expand($row);
1750 } else {
1751 this.collapse($row);
1752 }
1753 },
1754 onShow: function (e, $el, context) {
1755 // get sub fields
1756 var fields = acf.getFields({
1757 is: ':visible',
1758 parent: this.$el
1759 });
1760
1761 // trigger action
1762 // - ignore context, no need to pass through 'conditional_logic'
1763 // - this is just for fields like google_map to render itself
1764 acf.doAction('show_fields', fields);
1765 },
1766 onUnload: function () {
1767 // vars
1768 var indexes = [];
1769
1770 // loop
1771 this.$rows().each(function (i) {
1772 if ($(this).hasClass('-collapsed')) {
1773 indexes.push(i);
1774 }
1775 });
1776
1777 // allow null
1778 indexes = indexes.length ? indexes : null;
1779
1780 // set
1781 preference.save(this.get('key'), indexes);
1782 },
1783 onHover: function () {
1784 // add sortable
1785 this.addSortable(this);
1786
1787 // remove event
1788 this.off('mouseover');
1789 },
1790 onChangeField: function (e, $el) {
1791 const $target = $(e.delegateTarget);
1792 let $row = $el.closest('.acf-row');
1793 if ($row.closest('.acf-field-repeater').data('key') !== $target.data('key')) {
1794 $row = $row.parent().closest('.acf-row');
1795 }
1796 this.updateRowStatus($row, 'changed');
1797 },
1798 updateRowStatus: function ($row, status, data = true) {
1799 if (!this.get('pagination')) {
1800 return;
1801 }
1802 const parent_key = $row.parents('.acf-field-repeater').data('key');
1803 if (this.parent() && parent_key !== this.get('key')) {
1804 return;
1805 }
1806 const row_id = $row.data('id');
1807 const input_name = this.$el.find('.acf-repeater-hidden-input:first').attr('name');
1808 const status_name = `${input_name}[${row_id}][acf_${status}]`;
1809 const status_input = `<input type="hidden" class="acf-row-status" name="${status_name}" value="${data}" />`;
1810 if (!$row.hasClass('acf-' + status)) {
1811 $row.addClass('acf-' + status);
1812 }
1813
1814 // TODO: Update so that this doesn't get messed up with repeater subfields.
1815 const $existing_status = $row.find(`input[name='${status_name}']`);
1816 if (!$existing_status.length) {
1817 $row.find('td').first().append(status_input);
1818 } else {
1819 $existing_status.val(data);
1820 }
1821 },
1822 onClickFirstPage: function () {
1823 this.validatePage(1);
1824 },
1825 onClickPrevPage: function () {
1826 this.validatePage(this.page - 1);
1827 },
1828 onClickNextPage: function (e) {
1829 this.validatePage(this.page + 1);
1830 },
1831 onClickLastPage: function () {
1832 this.validatePage(this.totalPages());
1833 },
1834 onChangeCurrentPage: function () {
1835 this.validatePage(this.$pageInput().val());
1836 },
1837 maybeDisablePagination: function () {
1838 this.$actions().find('.acf-nav').removeClass('disabled');
1839 if (this.page <= 1) {
1840 this.$firstPageButton().addClass('disabled');
1841 this.$prevPageButton().addClass('disabled');
1842 }
1843 if (this.page >= this.totalPages()) {
1844 this.$nextPageButton().addClass('disabled');
1845 this.$lastPageButton().addClass('disabled');
1846 }
1847 },
1848 validatePage: function (nextPage) {
1849 const self = this;
1850
1851 // Validate the current page.
1852 acf.validateForm({
1853 form: this.$control(),
1854 event: '',
1855 reset: true,
1856 success: function ($form) {
1857 self.page = nextPage;
1858
1859 // Set up some sane defaults.
1860 if (self.page <= 1) {
1861 self.page = 1;
1862 }
1863 if (self.page >= self.totalPages()) {
1864 self.page = self.totalPages();
1865 }
1866 self.ajaxLoadPage();
1867 },
1868 failure: function ($form) {
1869 self.$pageInput().val(self.page);
1870 return false;
1871 }
1872 });
1873 },
1874 ajaxLoadPage: function (clearChanged = false) {
1875 const ajaxData = acf.prepareForAjax({
1876 action: 'acf/ajax/query_repeater',
1877 paged: this.page,
1878 field_key: this.get('key'),
1879 field_name: this.get('orig_name'),
1880 rows_per_page: parseInt(this.get('per_page')),
1881 refresh: clearChanged,
1882 nonce: this.get('nonce')
1883 });
1884 $.ajax({
1885 url: ajaxurl,
1886 method: 'POST',
1887 dataType: 'json',
1888 data: ajaxData,
1889 context: this
1890 }).done(function (response) {
1891 const {
1892 rows
1893 } = response.data;
1894 const $existingRows = this.$tbody().find('> tr');
1895 $existingRows.not('.acf-clone').hide();
1896 if (clearChanged) {
1897 // Remove any existing rows since we are refreshing from the server.
1898 $existingRows.not('.acf-clone').remove();
1899
1900 // Trigger a change in total rows, so we can update pagination.
1901 this.set('total_rows', response.data.total_rows, false);
1902 } else {
1903 $existingRows.not('.acf-changed, .acf-deleted, .acf-reordered, .acf-added, .acf-inserted, .acf-clone').remove();
1904 }
1905 Object.keys(rows).forEach(index => {
1906 let $row = false;
1907 let $unsavedRow = this.$tbody().find('> *[data-id=row-' + index + ']');
1908 let $insertedRow = this.$tbody().find('> *[data-inserted=' + index + ']');
1909
1910 // Unsaved new rows that are inserted into this specific position.
1911 if ($insertedRow.length) {
1912 $insertedRow.appendTo(this.$tbody()).show();
1913 acf.doAction('remount', $insertedRow);
1914 }
1915
1916 // Skip unsaved deleted rows; we don't want to show them again.
1917 if ($unsavedRow.hasClass('acf-deleted')) {
1918 return;
1919 }
1920
1921 // Unsaved edited rows should be moved to correct position.
1922 if ($unsavedRow.length) {
1923 acf.doAction('unmount', $unsavedRow);
1924 $unsavedRow.appendTo(this.$tbody()).show();
1925 acf.doAction('remount', $unsavedRow);
1926 return;
1927 }
1928
1929 // Rows from the server (that haven't been changed or deleted) should be appended and shown.
1930 $row = $(rows[index]);
1931 this.$tbody().append($row).show();
1932 acf.doAction('remount', $row);
1933
1934 // Move clone field back to the right spot.
1935 this.$clone().appendTo(this.$tbody());
1936 });
1937 const $addedRows = this.$tbody().find('.acf-added:hidden');
1938
1939 // If there are any new rows that are still hidden, append them to the bottom.
1940 if ($addedRows.length) {
1941 const self = this;
1942 $addedRows.each(function () {
1943 const $addedRow = $(this);
1944 $addedRow.insertBefore(self.$clone()).show();
1945 acf.doAction('remount', $addedRow);
1946 });
1947 }
1948
1949 // Update the page input.
1950 this.$pageInput().val(this.page);
1951 this.maybeDisablePagination();
1952 }).fail(function (jqXHR, textStatus, errorThrown) {
1953 const error = acf.getXhrError(jqXHR);
1954 let message = acf.__('Error loading page');
1955 if ('' !== error) {
1956 message = `${message}: ${error}`;
1957 }
1958 this.showNotice({
1959 text: message,
1960 type: 'warning'
1961 });
1962 });
1963 }
1964 });
1965 acf.registerFieldType(Field);
1966
1967 // register existing conditions
1968 acf.registerConditionForFieldType('hasValue', 'repeater');
1969 acf.registerConditionForFieldType('hasNoValue', 'repeater');
1970 acf.registerConditionForFieldType('lessThan', 'repeater');
1971 acf.registerConditionForFieldType('greaterThan', 'repeater');
1972
1973 // state
1974 var preference = new acf.Model({
1975 name: 'this.collapsedRows',
1976 key: function (key, context) {
1977 // vars
1978 var count = this.get(key + context) || 0;
1979
1980 // update
1981 count++;
1982 this.set(key + context, count, true);
1983
1984 // modify fieldKey
1985 if (count > 1) {
1986 key += '-' + count;
1987 }
1988
1989 // return
1990 return key;
1991 },
1992 load: function (key) {
1993 // vars
1994 var key = this.key(key, 'load');
1995 var data = acf.getPreference(this.name);
1996
1997 // return
1998 if (data && data[key]) {
1999 return data[key];
2000 } else {
2001 return false;
2002 }
2003 },
2004 save: function (key, value) {
2005 // vars
2006 var key = this.key(key, 'save');
2007 var data = acf.getPreference(this.name) || {};
2008
2009 // delete
2010 if (value === null) {
2011 delete data[key];
2012
2013 // append
2014 } else {
2015 data[key] = value;
2016 }
2017
2018 // allow null
2019 if ($.isEmptyObject(data)) {
2020 data = null;
2021 }
2022
2023 // save
2024 acf.setPreference(this.name, data);
2025 }
2026 });
2027 })(jQuery);
2028
2029 /***/ })
2030
2031 /******/ });
2032 /************************************************************************/
2033 /******/ // The module cache
2034 /******/ var __webpack_module_cache__ = {};
2035 /******/
2036 /******/ // The require function
2037 /******/ function __webpack_require__(moduleId) {
2038 /******/ // Check if module is in cache
2039 /******/ var cachedModule = __webpack_module_cache__[moduleId];
2040 /******/ if (cachedModule !== undefined) {
2041 /******/ return cachedModule.exports;
2042 /******/ }
2043 /******/ // Create a new module (and put it into the cache)
2044 /******/ var module = __webpack_module_cache__[moduleId] = {
2045 /******/ // no module.id needed
2046 /******/ // no module.loaded needed
2047 /******/ exports: {}
2048 /******/ };
2049 /******/
2050 /******/ // Execute the module function
2051 /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
2052 /******/
2053 /******/ // Return the exports of the module
2054 /******/ return module.exports;
2055 /******/ }
2056 /******/
2057 /************************************************************************/
2058 /******/ /* webpack/runtime/compat get default export */
2059 /******/ (() => {
2060 /******/ // getDefaultExport function for compatibility with non-harmony modules
2061 /******/ __webpack_require__.n = (module) => {
2062 /******/ var getter = module && module.__esModule ?
2063 /******/ () => (module['default']) :
2064 /******/ () => (module);
2065 /******/ __webpack_require__.d(getter, { a: getter });
2066 /******/ return getter;
2067 /******/ };
2068 /******/ })();
2069 /******/
2070 /******/ /* webpack/runtime/define property getters */
2071 /******/ (() => {
2072 /******/ // define getter functions for harmony exports
2073 /******/ __webpack_require__.d = (exports, definition) => {
2074 /******/ for(var key in definition) {
2075 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
2076 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
2077 /******/ }
2078 /******/ }
2079 /******/ };
2080 /******/ })();
2081 /******/
2082 /******/ /* webpack/runtime/hasOwnProperty shorthand */
2083 /******/ (() => {
2084 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
2085 /******/ })();
2086 /******/
2087 /******/ /* webpack/runtime/make namespace object */
2088 /******/ (() => {
2089 /******/ // define __esModule on exports
2090 /******/ __webpack_require__.r = (exports) => {
2091 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
2092 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2093 /******/ }
2094 /******/ Object.defineProperty(exports, '__esModule', { value: true });
2095 /******/ };
2096 /******/ })();
2097 /******/
2098 /************************************************************************/
2099 var __webpack_exports__ = {};
2100 // This entry needs to be wrapped in an IIFE because it needs to be in strict mode.
2101 (() => {
2102 "use strict";
2103 /*!********************************************!*\
2104 !*** ./assets/src/js/pro/acf-pro-input.js ***!
2105 \********************************************/
2106 __webpack_require__.r(__webpack_exports__);
2107 /* harmony import */ var _acf_field_repeater_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_acf-field-repeater.js */ "./assets/src/js/pro/_acf-field-repeater.js");
2108 /* harmony import */ var _acf_field_repeater_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_acf_field_repeater_js__WEBPACK_IMPORTED_MODULE_0__);
2109 /* harmony import */ var _acf_field_flexible_content_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_acf-field-flexible-content.js */ "./assets/src/js/pro/_acf-field-flexible-content.js");
2110 /* harmony import */ var _acf_field_flexible_content_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_acf_field_flexible_content_js__WEBPACK_IMPORTED_MODULE_1__);
2111 /* harmony import */ var _acf_field_gallery_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_acf-field-gallery.js */ "./assets/src/js/pro/_acf-field-gallery.js");
2112 /* harmony import */ var _acf_field_gallery_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_acf_field_gallery_js__WEBPACK_IMPORTED_MODULE_2__);
2113
2114
2115
2116 })();
2117
2118 /******/ })()
2119 ;
2120 //# sourceMappingURL=acf-pro-input.js.map