web/wp-content/plugins/acf-extended/assets/js/acfe-input.js (3,118 lines of code) (raw):

(function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * acf.newCondition * * Allows field conditions to work between two field groups */ acf.newCondition = function(rule, conditions) { // currently setting up conditions for fieldX, this field is the 'target' var target = conditions.get('field'); // use the 'target' to find the 'trigger' field. // - this field is used to setup the conditional logic events var field = target.getField(rule.field); // acfe: found target, but not the field to check value against if (target && !field) { // acfe: find the field in the whole page // we must add this step because acf.getField('do_not_exists') will instantiate an empty field var findField = acf.findField(rule.field); // instatiate field once found if (findField.length) { field = acf.getField(rule.field); } } // bail ealry if no target or no field (possible if field doesn't exist due to HTML error) if (!target || !field) { return false; } // vars var args = { rule: rule, target: target, conditions: conditions, field: field }; // vars var fieldType = field.get('type'); var operator = rule.operator; // get avaibale conditions var conditionTypes = acf.getConditionTypes({ fieldType: fieldType, operator: operator, }); // instantiate var model = conditionTypes[0] || acf.Condition; // instantiate var condition = new model(args); // return return condition; }; })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Checkbox & Radio */ acf.registerConditionForFieldType('contains', 'checkbox'); acf.registerConditionForFieldType('contains', 'radio'); /** * Code Editor */ acf.registerConditionForFieldType('equalTo', 'acfe_code_editor'); acf.registerConditionForFieldType('notEqualTo', 'acfe_code_editor'); acf.registerConditionForFieldType('patternMatch', 'acfe_code_editor'); acf.registerConditionForFieldType('contains', 'acfe_code_editor'); acf.registerConditionForFieldType('hasValue', 'acfe_code_editor'); acf.registerConditionForFieldType('hasNoValue', 'acfe_code_editor'); /** * Date Picker */ acf.registerConditionForFieldType('equalTo', 'date_picker'); acf.registerConditionForFieldType('notEqualTo', 'date_picker'); acf.registerConditionForFieldType('patternMatch', 'date_picker'); acf.registerConditionForFieldType('contains', 'date_picker'); acf.registerConditionForFieldType('greaterThan', 'date_picker'); acf.registerConditionForFieldType('lessThan', 'date_picker'); /** * Date Time Picker */ acf.registerConditionForFieldType('equalTo', 'date_time_picker'); acf.registerConditionForFieldType('notEqualTo', 'date_time_picker'); acf.registerConditionForFieldType('patternMatch', 'date_time_picker'); acf.registerConditionForFieldType('contains', 'date_time_picker'); /** * Forms */ acf.registerConditionForFieldType('equalTo', 'acfe_forms'); acf.registerConditionForFieldType('notEqualTo', 'acfe_forms'); acf.registerConditionForFieldType('patternMatch', 'acfe_forms'); acf.registerConditionForFieldType('contains', 'acfe_forms'); acf.registerConditionForFieldType('hasValue', 'acfe_forms'); acf.registerConditionForFieldType('hasNoValue', 'acfe_forms'); /** * Hidden */ acf.registerConditionForFieldType('equalTo', 'acfe_hidden'); acf.registerConditionForFieldType('notEqualTo', 'acfe_hidden'); acf.registerConditionForFieldType('patternMatch', 'acfe_hidden'); acf.registerConditionForFieldType('contains', 'acfe_hidden'); acf.registerConditionForFieldType('hasValue', 'acfe_hidden'); acf.registerConditionForFieldType('hasNoValue', 'acfe_hidden'); /** * Post Status */ acf.registerConditionForFieldType('equalTo', 'acfe_post_statuses'); acf.registerConditionForFieldType('notEqualTo', 'acfe_post_statuses'); acf.registerConditionForFieldType('patternMatch', 'acfe_post_statuses'); acf.registerConditionForFieldType('contains', 'acfe_post_statuses'); acf.registerConditionForFieldType('hasValue', 'acfe_post_statuses'); acf.registerConditionForFieldType('hasNoValue', 'acfe_post_statuses'); /** * Post Types */ acf.registerConditionForFieldType('equalTo', 'acfe_post_types'); acf.registerConditionForFieldType('notEqualTo', 'acfe_post_types'); acf.registerConditionForFieldType('patternMatch', 'acfe_post_types'); acf.registerConditionForFieldType('contains', 'acfe_post_types'); acf.registerConditionForFieldType('hasValue', 'acfe_post_types'); acf.registerConditionForFieldType('hasNoValue', 'acfe_post_types'); /** * Slug */ acf.registerConditionForFieldType('equalTo', 'acfe_slug'); acf.registerConditionForFieldType('notEqualTo', 'acfe_slug'); acf.registerConditionForFieldType('patternMatch', 'acfe_slug'); acf.registerConditionForFieldType('contains', 'acfe_slug'); acf.registerConditionForFieldType('hasValue', 'acfe_slug'); acf.registerConditionForFieldType('hasNoValue', 'acfe_slug'); /** * Taxonomies */ acf.registerConditionForFieldType('equalTo', 'acfe_taxonomies'); acf.registerConditionForFieldType('notEqualTo', 'acfe_taxonomies'); acf.registerConditionForFieldType('patternMatch', 'acfe_taxonomies'); acf.registerConditionForFieldType('contains', 'acfe_taxonomies'); acf.registerConditionForFieldType('hasValue', 'acfe_taxonomies'); acf.registerConditionForFieldType('hasNoValue', 'acfe_taxonomies'); /** * Taxonomy */ acf.registerConditionForFieldType('equalTo', 'taxonomy'); acf.registerConditionForFieldType('notEqualTo', 'taxonomy'); acf.registerConditionForFieldType('patternMatch', 'taxonomy'); acf.registerConditionForFieldType('contains', 'taxonomy'); acf.registerConditionForFieldType('hasValue', 'taxonomy'); acf.registerConditionForFieldType('hasNoValue', 'taxonomy'); /** * Taxonomy Terms */ acf.registerConditionForFieldType('equalTo', 'acfe_taxonomy_terms'); acf.registerConditionForFieldType('notEqualTo', 'acfe_taxonomy_terms'); acf.registerConditionForFieldType('patternMatch', 'acfe_taxonomy_terms'); acf.registerConditionForFieldType('contains', 'acfe_taxonomy_terms'); acf.registerConditionForFieldType('hasValue', 'acfe_taxonomy_terms'); acf.registerConditionForFieldType('hasNoValue', 'acfe_taxonomy_terms'); /** * Time Picker */ acf.registerConditionForFieldType('equalTo', 'time_picker'); acf.registerConditionForFieldType('notEqualTo', 'time_picker'); acf.registerConditionForFieldType('patternMatch', 'time_picker'); acf.registerConditionForFieldType('contains', 'time_picker'); /** * User Roles */ acf.registerConditionForFieldType('equalTo', 'acfe_user_roles'); acf.registerConditionForFieldType('notEqualTo', 'acfe_user_roles'); acf.registerConditionForFieldType('patternMatch', 'acfe_user_roles'); acf.registerConditionForFieldType('contains', 'acfe_user_roles'); acf.registerConditionForFieldType('hasValue', 'acfe_user_roles'); acf.registerConditionForFieldType('hasNoValue', 'acfe_user_roles'); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } var storage = []; acfe.registerEventForFieldType = function(fieldType, events, callback) { // force events to array if (typeof events === 'string') { events = [events]; } // add to storage storage.push({ fieldType: fieldType, events: events, callback: callback || false }) }; acfe.getEvents = function(args) { // defaults args = acf.parseArgs(args, { fieldType: '', }); var items = []; // loop storage.map(function(item) { // check args if (args.fieldType && item.fieldType.indexOf(args.fieldType) === -1) { return; } // push items.push(item); }); // return return items; }; var FieldEvent = new acf.Model({ actions: { 'new_field': 'newField' }, priority: 20, data: {}, parseEvent: function(event) { return event.match(/^(\S+)\s*(.*)$/); }, newField: function(field) { // set previous val this.set(field.cid, field.val()); // get items var items = acfe.getEvents({ fieldType: field.get('type') }); // loop items items.map(function(item) { // loop events item.events.map(function(event) { // match event "change input" var match = this.parseEvent(event); // add event listener field.on(match[1], match[2], this.proxy(function(e) { var val = field.val(); var prevVal = this.get(field.cid); var $el = $(e.currentTarget); var callback = item.callback || this.proxy(function(val, prevVal, field, e, $el) { // vars var _val = val; var _prevVal = prevVal; // compare object/array values if (typeof _val === 'object') { _val = JSON.stringify(_val); } if (typeof _prevVal === 'object') { _prevVal = JSON.stringify(_prevVal); } // avoid multiple trigger for the same value if (_prevVal !== _val) { this.set(field.cid, val); // actions acf.doAction('acfe/change_field', val, prevVal, field, e, $el); acf.doAction('acfe/change_field/type=' + field.get('type'), val, prevVal, field, e, $el); acf.doAction('acfe/change_field/name=' + field.get('name'), val, prevVal, field, e, $el); acf.doAction('acfe/change_field/key=' + field.get('key'), val, prevVal, field, e, $el); } }); callback(val, prevVal, field, e, $el); })); }, this); }, this); } }); // ACF acfe.registerEventForFieldType('button_group', 'change'); acfe.registerEventForFieldType('checkbox', 'change'); acfe.registerEventForFieldType('color_picker', 'change'); acfe.registerEventForFieldType('date_picker', 'change'); acfe.registerEventForFieldType('date_time_picker', 'change'); acfe.registerEventForFieldType('email', ['input', 'change']); acfe.registerEventForFieldType('file', 'change'); acfe.registerEventForFieldType('flexible_content', 'change'); acfe.registerEventForFieldType('gallery', 'change'); acfe.registerEventForFieldType('google_map', 'change'); acfe.registerEventForFieldType('image', 'change'); acfe.registerEventForFieldType('link', 'change'); acfe.registerEventForFieldType('number', ['input', 'change']); acfe.registerEventForFieldType('oembed', 'change'); acfe.registerEventForFieldType('page_link', 'change'); acfe.registerEventForFieldType('post_object', 'change'); acfe.registerEventForFieldType('relationship', 'change'); acfe.registerEventForFieldType('password', ['input', 'change']); acfe.registerEventForFieldType('radio', 'change'); acfe.registerEventForFieldType('range', ['input', 'change']); acfe.registerEventForFieldType('repeater', 'change'); acfe.registerEventForFieldType('select', 'change'); acfe.registerEventForFieldType('taxonomy', 'change'); acfe.registerEventForFieldType('text', ['input', 'change']); acfe.registerEventForFieldType('textarea', ['input', 'change']); acfe.registerEventForFieldType('time_picker', 'change'); acfe.registerEventForFieldType('true_false', 'change'); acfe.registerEventForFieldType('url', ['input', 'change']); acfe.registerEventForFieldType('user', 'change'); acfe.registerEventForFieldType('wysiwyg', 'change'); // ACFE acfe.registerEventForFieldType('acfe_advanced_link', 'change'); acfe.registerEventForFieldType('acfe_block_types', 'change'); acfe.registerEventForFieldType('acfe_countries', 'change'); acfe.registerEventForFieldType('acfe_currencies', 'change'); acfe.registerEventForFieldType('acfe_code_editor', 'change'); acfe.registerEventForFieldType('acfe_date_range_picker', 'change'); acfe.registerEventForFieldType('acfe_field_groups', 'change'); acfe.registerEventForFieldType('acfe_field_types', 'change'); acfe.registerEventForFieldType('acfe_fields', 'change'); acfe.registerEventForFieldType('acfe_forms', 'change'); acfe.registerEventForFieldType('acfe_hidden', 'change'); acfe.registerEventForFieldType('acfe_image_selector', 'change'); acfe.registerEventForFieldType('acfe_image_sizes', 'change'); acfe.registerEventForFieldType('acfe_languages', 'change'); acfe.registerEventForFieldType('acfe_menu_locations', 'change'); acfe.registerEventForFieldType('acfe_options_pages', 'change'); acfe.registerEventForFieldType('acfe_payment', 'change'); acfe.registerEventForFieldType('acfe_payment_cart', 'change'); acfe.registerEventForFieldType('acfe_payment_selector', 'change'); acfe.registerEventForFieldType('acfe_phone_number', 'change'); acfe.registerEventForFieldType('acfe_post_formats', 'change'); acfe.registerEventForFieldType('acfe_post_statuses', 'change'); acfe.registerEventForFieldType('acfe_post_types', 'change'); acfe.registerEventForFieldType('acfe_recaptcha', 'change'); acfe.registerEventForFieldType('acfe_taxonomies', 'change'); acfe.registerEventForFieldType('acfe_taxonomy_terms', 'change'); acfe.registerEventForFieldType('acfe_templates', 'change'); acfe.registerEventForFieldType('acfe_user_roles', 'change'); acfe.registerEventForFieldType('acfe_slug', ['input', 'change']); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * acfe.FieldExtender * * @param protoProps * @returns {*} * @constructor */ var storage = []; acfe.FieldExtender = function(protoProps) { // vars var id = acfe.extractVar(protoProps, 'id', acf.uniqueId('extender')); // validate protoProps.type = acfe.getArray(protoProps.type); protoProps.dependencies = acfe.getArray(protoProps.dependencies); protoProps.extender = id; // push to storage storage.push(protoProps); // return extender return id; } /** * acf.Field.setup * * @type {acf.Field.setup} */ var setup = acf.Field.prototype.setup; acf.Field.prototype.setup = function(props) { // parent setup setup.apply(this, arguments); var extenders = getFieldExtenders(this); if (!extenders.length) { return; } // vars var prototype = Object.getPrototypeOf(this); this.extenders = []; // loop extenders for (var model of extenders) { // append extender this.extenders.push(model.extender); // clone model var protoProps = $.extend(true, {}, model); var events = acfe.extractVar(protoProps, 'events'); // cleanup acfe.extractVars(protoProps, 'type', 'condition', 'dependencies'); // apply setup method if any if (protoProps.hasOwnProperty('setup')) { protoProps.setup.apply(this, arguments); } // generate child var Child = function() {}; // create proto Child.prototype = Object.create(prototype); // extend $.extend(Child.prototype, protoProps); // assign events if (events) { Child.prototype.events = $.extend(true, {}, Child.prototype.events, events); } // assign parent Child.prototype.__parent__ = prototype; // assign prototype for next loop prototype = Child.prototype; } // getParent function this.getParent = function(extender) { var prototype = Object.getPrototypeOf(this); while (prototype) { if (prototype.extender === extender) { return prototype.__parent__; } if (!prototype.__parent__) { return prototype; } prototype = prototype.__parent__; } return prototype; } // assign prototype Object.setPrototypeOf(this, prototype); } /** * getFieldExtenders * * @param field * @returns {*[]} */ var getFieldExtenders = function(field) { var extenders = []; for (var extender of getValidExtenders(field)) { extenders.push(getExtender(extender)); } return extenders; }; /** * getExtender * * @param extender * @returns {boolean|*} */ var getExtender = function(extender) { for (var model of storage) { if (model.extender === extender) { return model; } } return false; }; /** * getValidExtenders * * @param field * @returns {*|*[]} */ var getValidExtenders = function(field) { var rules = {}; for (var model of storage) { // validate type if (!acfe.inArray(field.get('type'), model.type)) { continue; } // validate condition if (model.hasOwnProperty('condition') && !model.condition.apply(field, arguments)) { continue; } // append rule rules[model.extender] = model.dependencies; } // return array return sortExtenders(rules); }; /** * sortExtenders * * https://stackoverflow.com/a/54347328 * * @param names * @param obj * @param start * @param depth * @returns {*|*[]} */ var sortExtenders = function(names, obj = names, start = [], depth = 0) { if (typeof names === 'object' && !Array.isArray(names)) { names = Object.keys(names) } const processed = names.reduce(function(a, b, i) { if (obj[b].every(Array.prototype.includes, a)) { a.push(b) } return a; }, start); const nextNames = names.filter(function(n) { return !processed.includes(n) }); const goAgain = nextNames.length && depth <= names.length; return goAgain ? sortExtenders(nextNames, obj, processed, depth + 1) : processed; }; })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } new acf.Model({ actions: { 'new_field': 'newField' }, priority: 1, validateField: function(field) { // check data correctly set if (!field.has('ftype')) { return false; } // check if prototype doesn't already have ftype (acf taxonomy field) return !acf.getFieldType(field.get('type')).prototype.get('ftype'); }, newField: function(field) { // validate if (!this.validateField(field)) { return; } // real type (checkbox, radio...) field.set('rtype', field.get('type'), true); // field type (acfe_post_types, acfe_post_formats...) field.set('type', field.get('ftype'), true); // assign attribute field.$el.attr('data-type', field.get('ftype')); // cleanup attribute field.$el.removeAttr('data-ftype'); // cleanup data delete field.data['ftype']; } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Instructions */ new acf.Model({ field: false, placement: false, actions: { 'new_field': 'newField', }, newField: function(field) { this.field = field; if (field.has('instructionTooltip')) { this.setTooltip(); } if (field.has('instructionAboveField')) { this.setAboveField(); } if (field.has('instructionPlacement')) { this.overridePlacement(field.get('instructionPlacement')); } }, setTooltip: function() { var icon = acfe.versionCompare(acf.get('wp_version'), '>=', '5.5') ? 'dashicons-info-outline' : 'dashicons-info'; this.field.$labelWrap().prepend('<span class="acfe-field-tooltip acf-js-tooltip dashicons ' + icon + '" title="' + acf.escHtml(this.field.get('instructionTooltip')) + '"></span>'); this.field.$labelWrap().find('.description').remove(); }, setAboveField: function() { this.field.$inputWrap().prepend('<p class="description">' + this.field.get('instructionAboveField') + '</p>'); this.field.$labelWrap().find('.description').remove(); }, overridePlacement: function(target) { var current = this.getPlacement(); // No instruction if (!current) return; // Placement is correct if (current === target) return; this.setPlacement(target); }, getPlacement: function() { var placement = false; if (this.field.$labelWrap().find('>.description').length) placement = 'label'; else if (this.field.$inputWrap().find('>.description:first-child').length) placement = 'above_field'; else if (this.field.$inputWrap().find('>.description:last-child').length) placement = 'field'; else if (this.field.$labelWrap().find('>.acfe-field-tooltip').length) placement = 'tooltip'; this.placement = placement; return this.placement; }, $getInstruction: function() { var placement = this.getPlacement(); if (placement === 'label') { return this.field.$labelWrap().find('>.description'); } else if (placement === 'above_field') { return this.field.$inputWrap().find('>.description:first-child'); } else if (placement === 'field') { return this.field.$inputWrap().find('>.description:last-child'); } else if (placement === 'tooltip') { return this.field.$labelWrap().find('>.acfe-field-tooltip'); } return false; }, setPlacement: function(target) { var $instruction = this.$getInstruction(); if (this.placement === 'tooltip') { var text = $instruction.attr('title'); $instruction.remove(); $instruction = $('<p class="description">' + text + '</p>'); } if (target === 'label') { this.field.$labelWrap().append($instruction); } else if (target === 'above_field') { this.field.$inputWrap().prepend($instruction); } else if (target === 'field') { this.field.$inputWrap().append($instruction); } else if (target === 'tooltip') { var icon = acfe.versionCompare(acf.get('wp_version'), '>=', '5.5') ? 'dashicons-info-outline' : 'dashicons-info'; this.field.$labelWrap().prepend($('<span class="acfe-field-tooltip acf-js-tooltip dashicons ' + icon + '" title="' + acf.escHtml($instruction.html()) + '"></span>')); $instruction.remove(); } } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Labels */ new acf.Model({ actions: { 'new_field': 'newField', }, getFieldType: function(field) { return field.get('rtype', field.get('type')); }, validateField: function(field) { // check setting if (!field.has('acfeLabels')) { return false; } // check type & real type return this.getFieldType(field) === 'checkbox' || this.getFieldType(field) === 'radio'; }, newField: function(field) { // bail early if (!this.validateField(field)) { return; } // vars var label, item; var labels = field.get('acfeLabels'); switch (this.getFieldType(field)) { case 'checkbox': { // loop for (label in labels) { item = labels[label]; field.$control().find('input[type=checkbox][value="' + item + '"]').closest('ul').before('<strong>' + label + '</strong>'); } break; } case 'radio': { // loop for (label in labels) { item = labels[label]; field.$control().find('input[type=radio][value="' + item + '"]').closest('li').addClass('parent').prepend('<strong>' + label + '</strong>'); } // horizontal rule if (field.$control().hasClass('acf-hl')) { field.$control().find('li.parent').each(function() { $(this).nextUntil('li.parent').addBack().wrapAll('<li><ul></ul></li>'); }); } break; } } } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } acf.Field.prototype.getModal = function(args) { var $modal = acfe.findModal('', this.$inputWrap()); if (!$modal.length) { return false; } return acfe.getModal($modal, args); }; })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Select Hooks */ new acf.Model({ actions: { 'select2_init': 'init', }, filters: { 'select2_args': 'args', 'select2_ajax_data': 'ajaxData', }, init: function($select, options, data, field, instance) { // bail early if (!field) { return; } // actions acf.doAction('select2_init/type=' + field.get('type'), $select, options, data, field, instance); acf.doAction('select2_init/name=' + field.get('name'), $select, options, data, field, instance); acf.doAction('select2_init/key=' + field.get('key'), $select, options, data, field, instance); }, args: function(options, $select, data, field, instance) { // bail early if (!field) { return options; } // filters options = acf.applyFilters('select2_args/type=' + field.get('type'), options, $select, data, field, instance); options = acf.applyFilters('select2_args/name=' + field.get('name'), options, $select, data, field, instance); options = acf.applyFilters('select2_args/key=' + field.get('key'), options, $select, data, field, instance); // only on pages without woocommerce if (!acf.isset(window, 'jQuery', 'fn', 'selectWoo')) { options.templateSelection = function(selection) { var text = selection.text; text = acf.applyFilters('select2_template_selection', text, selection, $select, data, field, instance); text = acf.applyFilters('select2_template_selection/type=' + field.get('type'), text, selection, $select, data, field, instance); text = acf.applyFilters('select2_template_selection/name=' + field.get('name'), text, selection, $select, data, field, instance); text = acf.applyFilters('select2_template_selection/key=' + field.get('key'), text, selection, $select, data, field, instance); var $selection = $('<span class="acf-selection"></span>'); $selection.html(acf.escHtml(text)); $selection.data('element', selection.element); return $selection; }; options.templateResult = function(selection) { var text = selection.text; text = acf.applyFilters('select2_template_result', text, selection, $select, data, field, instance); text = acf.applyFilters('select2_template_result/type=' + field.get('type'), text, selection, $select, data, field, instance); text = acf.applyFilters('select2_template_result/name=' + field.get('name'), text, selection, $select, data, field, instance); text = acf.applyFilters('select2_template_result/key=' + field.get('key'), text, selection, $select, data, field, instance); var $selection = $('<span class="acf-selection"></span>'); $selection.html(acf.escHtml(text)); $selection.data('element', selection.element); return $selection; }; // fix old ACF 5.9 version which doesn't escape markup if (acfe.versionCompare(acf.get('acf_version'), '<', '5.10')) { options.escapeMarkup = function(markup) { if (typeof markup !== 'string') { return markup; } return acf.escHtml(markup); } } } return options; }, ajaxData: function(ajaxData, data, $el, field, instance) { // bail early if (!field) { return ajaxData; } // filters ajaxData = acf.applyFilters('select2_ajax_data/type=' + field.get('type'), ajaxData, data, $el, field, instance); ajaxData = acf.applyFilters('select2_ajax_data/name=' + field.get('name'), ajaxData, data, $el, field, instance); ajaxData = acf.applyFilters('select2_ajax_data/key=' + field.get('key'), ajaxData, data, $el, field, instance); if (ajaxData.action) { ajaxData = acf.applyFilters('select2_ajax_data/action=' + ajaxData.action, ajaxData, data, $el, field, instance); } return ajaxData; } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * acfe.Form model */ acfe.Form = acf.Model.extend({ notice: false, validator: false, events: { 'click .button': 'onClickSubmit', 'click [type="submit"]': 'onClickSubmit', 'invalidField': 'onInvalidField', // inherited from fields 'changed:status': 'onChangeStatus', // inherited from validator 'showErrors': 'onShowErrors', // inherited from validator }, setup: function($el) { this.$el = $el; var cid = $el.data('cid'); $.extend(this.data, acfe.getFormData(cid)); this.$el.data('acfe_form', this); }, initialize: function() { // compatibility for acf validator this.$el.removeData('acf'); // hide unload if (this.get('hide_unload')) { acf.unload.disable(); } }, onClickSubmit: function(e, $el) { // prevent submit spam if ($el.hasClass('disabled')) { e.preventDefault(); } }, onInvalidField: function(e, $el) { // get field var field = acf.getField($(e.target)); // make sure notice is an error if (!field.notice || field.notice.get('type') !== 'error') { return; } // error class if (this.get('error_class')) { field.notice.$el.addClass(this.get('error_class')); } // error position switch (this.get('error_position')) { case 'hide': { field.notice.remove(); break; } case 'below': { if (field.$control().length) { field.notice.$el.insertAfter(field.$control()); } else if (field.$inputWrap().length) { field.notice.$el.appendTo(field.$inputWrap()); } field.notice.$el.addClass('-below'); break; } case 'group': { // vars var label = acfe.getTextNode(field.$labelWrap().find('label')).trim(); var placeholder = field.$('.acf-input-wrap [placeholder!=""]').attr('placeholder'); var message = field.notice.$el.text().trim(); // remove acf notice field.notice.remove(); // try get label if (label && label.length && label !== '*') { message = `${label}: ${message}`; // otherwise placeholder } else if (placeholder && placeholder.length && placeholder !== '') { message = `${placeholder}: ${message}`; // otherwise field name } else { var name = acfe.ucFirst(field.get('name')).replace(/_/g, ' '); message = `${name}: ${message}`; } // append notice error if (this.notice) { this.notice.$el.append(acf.escHtml(`<p>${message}</p>`)); } break; } } }, onChangeStatus: function(e, $el, status, prevStatus) { switch (status) { // validating case 'validating': { // already has validator if (this.validator) { return; } // vars var validator = this.$el.data('acf'); var prototype = Object.getPrototypeOf(validator); // methods var showErrors = prototype.showErrors; // showErrors validator.showErrors = function() { showErrors.apply(this, arguments); validator.trigger('showErrors'); } this.validator = validator; break; } // invalid case 'invalid': { if (this.get('error_position') === 'group') { // no field errors, probably a global error // remove grouped notice if (!this.validator.getFieldErrors().length) { if (this.notice) { this.notice.remove(); this.notice = false; } break; } // notice exists if (this.notice) { // reset this.notice.update({ type: 'error', html: '', }); // new notice } else { this.notice = acf.newNotice({ type: 'error', target: this.$el }); } // error class if (this.get('error_class')) { this.notice.$el.addClass(this.get('error_class')); } // remove empty <p></p> added by "html: ''" this.notice.$el.find('p:empty').remove(); // timeout this.setTimeout(function() { acfe.scrollTo(this.notice.$el); }, 20); } break; } // valid case 'valid': { if (this.get('error_position') === 'group') { if (this.notice) { this.notice.remove(); this.notice = false; } } if (this.get('hide_revalidation')) { if (this.validator.has('notice')) { this.validator.get('notice').remove(); this.validator.set('notice', null); // remove notice from data } } break; } } }, onShowErrors: function(e, $el) { if (this.get('hide_error')) { if (this.validator.has('notice')) { this.validator.get('notice').remove(); this.validator.set('notice', null); // remove notice from data } } else { if (this.validator.has('notice')) { var fieldErrors = this.validator.getFieldErrors(); var globalErrors = this.validator.getGlobalErrors(); var errorCount = 0; // loop fieldErrors.map(function(error) { // get input var $input = this.validator.$('[name="' + error.input + '"]').first(); // if $_POST value was an array, this $input may not exist if (!$input.length) { $input = this.validator.$('[name^="' + error.input + '"]').first(); } if ($input.length) { errorCount++; } }, this); // errorMessage var errorMessage = this.get('messages.failure'); // global error globalErrors.map(function(error) { errorMessage += errorMessage.length ? '. ' : ''; errorMessage += error.message; }); // single error if (errorCount === 1 && this.get('messages.error')) { errorMessage += errorMessage.length ? '. ' : ''; errorMessage += this.get('messages.error'); // multiple errors } else if (errorCount > 1 && this.get('messages.errors')) { errorMessage += errorMessage.length ? '. ' : ''; errorMessage += this.get('messages.errors').replace('%d', errorCount); } // update notice text this.validator.get('notice').update({ text: errorMessage }); } } }, set: function(name, value, silent) { // bail if unchanged var prevValue = this.get(name); if (prevValue === value) { return this; } // nameRoot // dot notation, ie: 'path.to.key' var nameArray = name.split('.'); var nameRoot = nameArray.shift(); var prevValueRoot = this.get(nameRoot); // set data acfe.arraySet(this.data, name, value); // update formData acfe.setFormData(this.get('cid'), name, value); // valueRoot var valueRoot = this.get(nameRoot); // trigger events if (!silent) { this.changed = true; if (nameArray.length > 1) { this.trigger(`changedData:${nameRoot}`, [valueRoot, prevValueRoot]); } this.trigger('changedData:' + name, [value, prevValue]); this.trigger('changedData', [name, value, prevValue]); } // return return this; }, }); acf.addAction('acfe/form/validation_success', function($form, validator, form) { if (validator.has('notice')) { validator.get('notice').update({ type: 'success', text: form.get('messages.success'), timeout: 1000 }); } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * spawner */ new acf.Model({ wait: 'prepare', priority: 1, initialize: function() { if (!acfe.get('is_admin')) { new formFields(); } } }); /** * formFields */ var formFields = acf.Model.extend({ actions: { 'new_field/type=date_picker': 'datePicker', 'new_field/type=date_time_picker': 'datePicker', 'new_field/type=time_picker': 'datePicker', 'new_field/type=acfe_date_range_picker': 'datePicker', 'new_field/type=google_map': 'googleMap', }, datePicker: function(field) { var form = field.getForm(); if (form && form.get('field_class')) { field.$inputText().addClass(form.get('field_class')); } }, googleMap: function(field) { var form = field.getForm(); if (form && form.get('field_class')) { field.$search().addClass(form.get('field_class')); } }, }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * acf.Field.prototype.getForm * * Allows to retrieve the front-end form instance from a field * * @returns {*|jQuery} */ acf.Field.prototype.getForm = function() { return acfe.getForm(this.$el.closest('.acfe-form')); }; /** * acfe.findForms * * @returns {jQuery|HTMLElement|*} */ acfe.findForms = function(args) { // string / array if (!acfe.isObject(args)) { args = { name: args, }; } // vars var selector = '.acfe-form'; var $forms = false; // args args = acf.parseArgs(args, { cid: [], name: [], parent: false, limit: false, }); // force array args.cid = acfe.getArray(args.cid); args.name = acfe.getArray(args.name); // name if (args.name.length) { for (var name of args.name) { acfe.getFormsData({ name: name }).map(function(form) { args.cid.push(form.cid); }); } // no data found if (!args.cid.length) { return $(); } } // cid if (args.cid.length) { // vars var array = []; // loop for (var cid of args.cid) { array.push(selector + '[data-cid="' + cid + '"]'); } selector = array.join(','); } // query if (args.parent) { $forms = args.parent.find(selector); } else { $forms = $(selector); } // limit if (args.limit) { $forms = $forms.slice(0, args.limit); } return $forms; }; /** * acfe.getForms * * @param $forms * @returns {*[]} */ acfe.getForms = function($forms) { // allow jQuery if ($forms instanceof jQuery) { // find forms } else { $forms = acfe.findForms($forms); } // loop var forms = []; $forms.each(function() { var form = acfe.getForm($(this)); if (form) { forms.push(form); } }); // return return forms; }; /** * acfe.getForm * * @param $form * @returns {*|jQuery} */ acfe.getForm = function($form) { // allow jQuery if ($form instanceof jQuery) { if (!$form.hasClass('acfe-form')) { return false; } // find form } else { $form = acfe.findForm($form); } // found form if ($form.length) { // instantiate var form = $form.data('acfe_form'); if (!form) { form = acfe.newForm($form); } // return return form; } return false; }; /** * acfe.findForm * * @param args * @returns {*} */ acfe.findForm = function(args) { // if string / array // use form name as default if (!acfe.isObject(args)) { args = { name: args, }; } args = acf.parseArgs(args, { limit: 1, }); return acfe.findForms(args); }; /** * acfe.newForm * * @param $form * @returns {*} */ acfe.newForm = function($form) { // instantiate var form = new acfe.Form($form); // actions acf.doAction(`acfe/new_form`, form); acf.doAction(`acfe/new_form/form=${form.get('name')}`, form); // return return form; }; /** * acfe.getFormsData * * @param args * @returns {*[]} */ acfe.getFormsData = function(args) { // acfe.Form instance if (args instanceof acfe.Form) { args = { form: args, }; // string } else if (!acfe.isObject(args)) { args = { cid: args, }; } // args args = acf.parseArgs(args, { form: '', cid: '', name: '', success: '', }); if (args.form && args.form instanceof acfe.Form) { args.cid = args.form.get('cid'); } // get data var forms = []; var data = acfe.get('forms', {}); // empty data if (!Object.keys(data).length) { return forms; } for (var cid in data) { if (data[cid]) { var matchCid = true; var matchName = true; var matchSuccess = true; if (args.cid.length) { matchCid = args.cid === cid; } if (args.name.length) { matchName = args.name === data[cid].name; } if (args.success !== '') { matchSuccess = args.success === data[cid].success; } if (matchCid && matchName && matchSuccess) { forms.push(data[cid]); } } } return forms; }; /** * acfe.getFormData * * @param args * @returns {*|boolean} */ acfe.getFormData = function(args) { var forms = acfe.getFormsData(args); if (forms.length) { return forms.shift(); } return false; }; /** * acfe.setFormData * * @param cid * @param path * @param value */ acfe.setFormData = function(cid, path, value) { acfe.set(`forms.${cid}.${path}`, value); }; /** * acfe.loadForm * * @param $parent */ acfe.renderForm = function($parent) { // form is passed instead of parent if ($parent && $parent.length && $parent.hasClass('acfe-form')) { $parent = $parent.parent(); } // initialize fields and forms acf.doAction('append', $parent); }; /** * acfe.renderFormAjax * * @param args */ acfe.renderFormAjax = function(args) { args = acf.parseArgs(args, { url: acf.get('ajaxurl'), data: acf.prepareForAjax({ action: 'acfe/form/render_form_ajax', }), type: 'post', dataType: 'html', success: function() {}, replace: 'html', form: '', target: '', }); // form if (args.form) { args.data.form = args.form; } // target if (args.target) { // backup success var success = args.success; // replace success args.success = function(response) { // string selector if (acfe.isString(args.target)) { args.target = $(args.target); } args.target[args.replace]($(response)); acfe.renderForm(args.target); // original success success(response); } } $.ajax(args); }; })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } new acf.Model({ wait: 'prepare', priority: 5, initialize: function() { if (!acfe.get('is_admin')) { new renderHooks(); } } }); /** * renderHooks */ var renderHooks = acf.Model.extend({ actions: { 'validation_begin': 'validationBegin', 'validation_failure': 'validationFailure', 'validation_success': 'validationSuccess', 'submit': 'submit', }, filters: { 'validation_complete': 'validationComplete', }, validationBegin: function($el) { var form = acfe.getForm($el); if (form) { var validator = $el.data('acf'); acf.doAction('acfe/form/validation_begin', $el, validator, form); acf.doAction(`acfe/form/validation_begin/form=${form.get('name')}`, $el, validator, form); } }, validationFailure: function($el, validator) { var form = acfe.getForm($el); if (form) { acf.doAction('acfe/form/validation_failure', $el, validator, form); acf.doAction(`acfe/form/validation_failure/form=${form.get('name')}`, $el, validator, form); } }, validationSuccess: function($el, validator) { var form = acfe.getForm($el); if (form) { acf.doAction('acfe/form/validation_success', $el, validator, form); acf.doAction(`acfe/form/validation_success/form=${form.get('name')}`, $el, validator, form); } }, submit: function($el) { var form = acfe.getForm($el); if (form) { var validator = $el.data('acf'); acf.doAction('acfe/form/submit', $el, validator, form); acf.doAction(`acfe/form/submit/form=${form.get('name')}`, $el, validator, form); } }, validationComplete: function(data, $el, validator) { var form = acfe.getForm($el); if (form) { data = acf.applyFilters('acfe/form/validation_complete', data, $el, validator, form); data = acf.applyFilters(`acfe/form/validation_complete/form=${form.get('name')}`, data, $el, validator, form); } return data; }, }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * form initializer * * @type {string[]} */ var actions = ['prepare', 'ready', 'load', 'append']; actions.map(function(action) { acf.addAction(action, function($el) { // initialize front-end forms if (!acfe.get('is_admin')) { acfe.getForms({ parent: $el }); } }, 1); }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * spawner */ new acf.Model({ wait: 'prepare', priority: 5, initialize: function() { if (!acfe.get('is_admin')) { new renderMedia(); new overridePrototypes(); } } }); /** * renderMedia */ var renderMedia = acf.Model.extend({ actions: { 'new_media_popup': 'newMediaPopup', }, initialize: function() { this.resetMedia(); }, newMediaPopup: function(popup) { // check post id was set in prototypes if (popup.get('post_id')) { if (acf.isset(window, 'wp', 'media', 'view', 'settings', 'post')) { wp.media.view.settings.post = { id: popup.get('post_id') }; } } // reset media modal on close popup.frame.on('close', this.proxy(this.resetMedia)); }, resetMedia: function() { // fix image/file/gallery media upload // avoid acf to use current post to determine if the user can upload a file if (acf.isset(window, 'wp', 'media', 'view', 'settings', 'post')) { wp.media.view.settings.post = false; } }, }); /** * overridePrototypes */ var overridePrototypes = acf.Model.extend({ initialize: function() { /** * Image/File selectAttachment */ var selectAttachment = function() { // vars var parent = this.parent(); var multiple = parent && parent.get('type') === 'repeater'; // default args var args = { mode: 'select', field: this.get('key'), multiple: multiple, library: this.get('library'), allowedTypes: this.get('mime_types'), select: $.proxy(function(attachment, i) { if (i > 0) { this.append(attachment, parent); } else { this.render(attachment); } }, this) }; // field type switch (this.get('type')) { // image args case 'image': { args.type = 'image'; args.title = acf.__('Select Image'); break; } // file args case 'file': { args.title = acf.__('Select File'); break; } } // get form var form = this.getForm(); if (form && form.get('media.fields') && form.get('media.post_id')) { if (acfe.inArray(this.get('key'), form.get('media.fields'))) { args.post_id = form.get('media.post_id'); } } // new frame var frame = acf.newMediaPopup(args); }; // assign new function acf.models.ImageField.prototype.selectAttachment = selectAttachment; acf.models.FileField.prototype.selectAttachment = selectAttachment; /** * Gallery onClickAdd */ var onClickAdd = function(e, $el) { // validate if (this.isFull()) { this.showNotice({ text: acf.__('Maximum selection reached'), type: 'warning' }); return; } // args var args = { mode: 'select', title: acf.__('Add Image to Gallery'), field: this.get('key'), multiple: 'add', library: this.get('library'), allowedTypes: this.get('mime_types'), selected: this.val(), select: $.proxy(function(attachment, i) { this.appendAttachment(attachment, i); }, this) }; // get form var form = this.getForm(); if (form && form.get('media.fields') && form.get('media.post_id')) { if (acfe.inArray(this.get('key'), form.get('media.fields'))) { args.post_id = form.get('media.post_id'); } } // new frame var frame = acf.newMediaPopup(args); }; acf.models.GalleryField.prototype.onClickAdd = onClickAdd; /** * MediaPopup getFrameOptions * * @type {function(): *} */ var getFrameOptions = acf.models.SelectMediaPopup.prototype.getFrameOptions; acf.models.SelectMediaPopup.prototype.getFrameOptions = function() { // call original function var options = getFrameOptions.apply(this, arguments); // custom library if (this.get('library') === 'uploadedTo' && this.get('post_id')) { options.library.uploadedTo = this.get('post_id'); } return options; } }, }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } new acf.Model({ wait: 'prepare', priority: 5, initialize: function() { if (!acfe.get('is_admin')) { new renderSuccess(); } } }); /** * renderSuccess */ var renderSuccess = acf.Model.extend({ initialize: function() { // get form success var object = this.getFormSuccess(); // validate form success if (!object) { return; } // vars // form instance might not exist if form is hidden on success var data = object.data; var $el = object.form ? object.form.$el : false; var form = object.form ? object.form : false; var formData = object.form ? object.form.get('success_data') : object.data.success_data; // hooks acf.doAction(`acfe/form/submit_success`, $el, form, formData); acf.doAction(`acfe/form/submit_success/form=${data.name}`, $el, form, formData); // deprecated acfe.doActionDeprecated(`acfe/form/success`, [$el], '0.9.0.3', `acfe/form/submit_success`); acfe.doActionDeprecated(`acfe/form/success/id=${data.id}`, [$el], '0.9.0.3', `acfe/form/submit_success/form=${data.name}`); acfe.doActionDeprecated(`acfe/form/success/form=${data.name}`, [$el], '0.9.0.3', `acfe/form/submit_success/form=${data.name}`); acfe.doActionDeprecated(`acfe/form/success/name=${data.name}`, [$el], '0.9.0.3', `acfe/form/submit_success/form=${data.name}`); // deprecated acfe.doActionDeprecated(`acfe/form/submit/success`, [$el], '0.9.0.3', `acfe/form/submit_success`); acfe.doActionDeprecated(`acfe/form/submit/success/id=${data.id}`, [$el], '0.9.0.3', `acfe/form/submit_success/form=${data.name}`); acfe.doActionDeprecated(`acfe/form/submit/success/name=${data.name}`, [$el], '0.9.0.3', `acfe/form/submit_success/form=${data.name}`); // should scroll if (data.scroll) { // scroll to message if (data.selector) { acfe.scrollTo($(data.selector)); // scroll to previous element } else if ($el) { acfe.scrollTo($el.prev()); } } }, getFormSuccess: function() { var formData = acfe.getFormData({ success: true }); if (formData) { return { form: acfe.getForm({ cid: formData.cid }), data: formData, }; } return false; }, }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * acf.validation.onClickSubmit * * Fix front-end form triggering validation for all forms is there are multiple forms on the page * This function is untouched. We just pass the $el to ensureInvalidFieldVisibility($el) * * @param e * @param $el * * @since ACF 5.11 */ acf.validation.onClickSubmit = function(e, $el) { // some browsers (safari) force their browser validation before our AJAX validation, // so we need to make sure fields are visible earlier than showErrors() ensureInvalidFieldVisibility($el); // store the "click event" for later use in this.onSubmit() this.set('originalEvent', e); } /** * ensureInvalidFieldVisibility * * Add current element as argument * * @param $el * * @since ACF 5.11.4 */ var ensureInvalidFieldVisibility = function($el) { // load each ACF input field and check it's browser validation state. var $inputs = $('.acf-field input'); // acfe: retrieve the current element parents form var $form = $el.closest('form'); // acfe: find fields inside the current form only if ($form.length) { $inputs = $form.find('.acf-field input'); } $inputs.each(function() { if (!this.checkValidity()) { // field is invalid, so we need to make sure it's metabox is visible. ensureFieldPostBoxIsVisible($(this)); } }); }; /** * ensureFieldPostBoxIsVisible * * @param $el * * @since ACF 5.11.4 */ var ensureFieldPostBoxIsVisible = function($el) { // Find the postbox element containing this field. var $postbox = $el.parents('.acf-postbox'); if ($postbox.length) { var acf_postbox = acf.getPostbox($postbox); // ACFE: use class check instead of isHiddenByScreenOptions() for older ACF versions if (acf_postbox && (acf_postbox.$el.hasClass('hide-if-js') || acf_postbox.$el.css('display') == 'none')) { // Rather than using .show() here, we don't want the field to appear next reload. // So just temporarily show the field group so validation can complete. acf_postbox.$el.removeClass('hide-if-js'); acf_postbox.$el.css('display', ''); } } }; })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Advanced Link */ var ACFE_Advanced_Link = acf.Field.extend({ type: 'acfe_advanced_link', events: { 'click a[data-name="add"]': 'onClickEdit', 'click a[data-name="edit"]': 'onClickEdit', 'click a[data-name="remove"]': 'onClickRemove', }, $control: function() { return this.$('.acf-link'); }, getSubField: function(key) { return acf.getFields({ key: key, parent: this.$el }).shift(); }, getSubFields: function() { return acf.getFields({ parent: this.$el }); }, getValue: function() { // return var data = { type: this.getSubField('type').val(), title: this.getSubField('title').val(), value: '', name: '', target: Boolean(this.getSubField('target').val()) }; // assign value data.value = this.getSubField(data.type).val(); data.name = data.value; // post / term value if (data.type === 'post' || data.type === 'term') { data.name = this.getSubField(data.type).$input().find(':selected').text(); } // return return data; }, setValue: function(val) { // clear value if (!val) { return this.clearValue(); } // allow val to be a string if (acfe.isString(val)) { val = { type: 'url', title: '', value: val, target: false }; } val = acf.parseArgs(val, { type: 'url', value: '', title: '', target: false }); // set sub fields this.getSubField('type').val(val.type); this.getSubField(val.type).val(val.value); // post / term value this.getSubField('title').val(val.title); this.getSubField('target').val(val.target); // render value this.renderValue(); }, clearValue: function() { // clear subfields values this.getSubFields().map(function(field) { field.val(''); }); }, renderValue: function() { // vars var val = this.val(); var $control = this.$control(); // remove class $control.removeClass('-value -external'); // add class if (val.value || val.title) { $control.addClass('-value'); } // target if (val.target) { $control.addClass('-external'); } // update text var url = val.type === 'url' ? val.value : '#'; this.$('.link-title').html(val.title); this.$('.link-url').attr('href', url).html(val.name); }, onClickEdit: function(e, $el) { // vars this.getModal({ open: true, onClose: this.proxy(function() { this.renderValue(); }) }); }, onClickRemove: function(e, $el) { this.clearValue(); this.renderValue(); }, }); acf.registerFieldType(ACFE_Advanced_Link); /** * Field: Advanced Link Ajax Manager */ new acf.Model({ filters: { 'select2_ajax_data/action=acfe/fields/advanced_link/post_query': 'ajaxData', }, ajaxData: function(ajaxData, data, $el, field, select) { // get advanced link field var parentField = field.parent(); // assign parent field key if (parentField) { ajaxData.field_key = parentField.get('key'); } return ajaxData; }, }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Button */ var ACFE_Button = acf.Field.extend({ type: 'acfe_button', events: { 'click input': 'onClick', 'click button': 'onClick', }, $input: function() { if (this.$('input').length) { return this.$('input'); } else if (this.$('button').length) { return this.$('button'); } }, initialize: function() { // vars var $button = this.$input(); // inherit data this.inherit($button); }, onClick: function(e, $el) { if (!this.get('ajax')) return; e.preventDefault(); // serialize form data var data = { action: 'acfe/fields/button', field_key: this.get('key'), acf: acf.serialize(this.$el.closest('form'), 'acf') }; data = acf.applyFilters('acfe/fields/button/data', data, this.$el); data = acf.applyFilters('acfe/fields/button/data/name=' + this.get('name'), data, this.$el); data = acf.applyFilters('acfe/fields/button/data/key=' + this.get('key'), data, this.$el); // Deprecated acf.doAction('acfe/fields/button/before_ajax', this.$el, data); // Actions acf.doAction('acfe/fields/button/before', this.$el, data); acf.doAction('acfe/fields/button/before/name=' + this.get('name'), this.$el, data); acf.doAction('acfe/fields/button/before/key=' + this.get('key'), this.$el, data); // ajax $.ajax({ url: acf.get('ajaxurl'), data: acf.prepareForAjax(data), type: 'post', dataType: 'json', context: this, // Success success: function(response) { // Deprecated acf.doAction('acfe/fields/button/ajax_success', response, this.$el, data); // Actions acf.doAction('acfe/fields/button/success', response, this.$el, data); acf.doAction('acfe/fields/button/success/name=' + this.get('name'), response, this.$el, data); acf.doAction('acfe/fields/button/success/key=' + this.get('key'), response, this.$el, data); }, // Complete complete: function(xhr) { var response = xhr.responseText; // Actions acf.doAction('acfe/fields/button/complete', response, this.$el, data); acf.doAction('acfe/fields/button/complete/name=' + this.get('name'), response, this.$el, data); acf.doAction('acfe/fields/button/complete/key=' + this.get('key'), response, this.$el, data); } }); } }); acf.registerFieldType(ACFE_Button); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Checkbox */ var Checkbox = acf.models.CheckboxField; acf.models.CheckboxField = Checkbox.extend({ // add setValue method // this allows to use field.val('new_value') to assign a new value to the field setValue: function(val) { // clear value if (!val) { return this.clearValue(); } // force value as array var vals = acfe.getArray(val); // map values vals.map(function(val) { // get option with value var $option = this.$(':checkbox[value="' + val + '"]'); // option exists and is not already selected if ($option.length && !$option.is(':checked')) { // select the option $option.prop('checked', true).trigger('change'); } }, this); }, // add clearValue method // this allows to set the value to the first radio or if allow_null is enabled, to null clearValue: function() { var $inputs = this.$inputs(); var $labels = this.$('label'); // update "checked" state. $inputs.prop('checked', false); // remove "selected" class. $labels.removeClass('selected'); } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Clone */ var Clone = acf.Field.extend({ wait: false, type: 'clone', events: { 'duplicateField': 'onDuplicate' }, initialize: function() { if (this.has('acfeCloneModal')) { this.$el.find('> .acf-input > .acf-fields, > .acf-input > .acf-table').wrapAll('<div class="acfe-modal"><div class="acfe-modal-wrapper"><div class="acfe-modal-content"></div></div></div>'); this.$el.find('> .acf-input').append('<a href="#" class="acf-button button" data-modal>' + this.get('acfeCloneModalButton') + '</a>'); this.initializeModal(); } }, initializeModal: function() { // normal title var title = this.$labelWrap().find('label').text().trim(); // inside table if (this.$el.is('td')) { title = this.get('acfeCloneModalButton'); var $th = this.$el.closest('table').find(' > thead th[data-key="' + this.get('key') + '"]'); if ($th.length) { title = acfe.getTextNode($th); } } // fallback to button text if (!title.length) { title = this.get('acfeCloneModalButton'); } // modal this.getModal({ title: title, size: this.has('acfeCloneModalSize') ? this.get('acfeCloneModalSize') : 'large', footer: this.has('acfeCloneModalClose') ? acf.__('Close') : false, class: 'acfe-modal-edit-' + this.get('name') + ' acfe-modal-edit-' + this.get('key') }); }, onDuplicate: function(e, $el, $duplicate) { $duplicate.find('.acf-input:first > a[data-modal]').remove(); } }); acf.registerFieldType(Clone); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Code Editor */ var CodeEditor = acf.Field.extend({ wait: false, type: 'acfe_code_editor', editor: {}, events: { 'showField': 'onShow', 'duplicateField': 'onDuplicate' }, $control: function() { return this.$('> .acf-input > .acf-input-wrap'); }, $input: function() { return this.$control().find('> textarea'); }, initialize: function() { // bail early if (!acf.isset(wp, 'codeEditor')) { return; } // args var args = { lineNumbers: this.get('lines'), lineWrapping: true, styleActiveLine: false, continueComments: true, indentUnit: this.get('indentUnit'), tabSize: 1, indentWithTabs: false, autoRefresh: true, // needed for gutenberg metabox mode: this.get('mode'), extraKeys: { 'Tab': function(cm) { cm.execCommand('indentMore') }, 'Shift-Tab': function(cm) { cm.execCommand('indentLess') }, }, } // filter args args = acf.applyFilters('acfe/fields/code_editor/args', args, this); args = acf.applyFilters('acfe/fields/code_editor/args/name=' + this.get('name'), args, this); args = acf.applyFilters('acfe/fields/code_editor/args/key=' + this.get('key'), args, this); // initialize wp editor this.editor = wp.codeEditor.initialize(this.$input().get(0), { codemirror: $.extend(wp.codeEditor.defaultSettings.codemirror, args) }); if (this.get('rows')) { this.editor.codemirror.getScrollerElement().style.minHeight = this.get('rows') * 18.5 + 'px'; } if (this.get('maxRows')) { this.editor.codemirror.getScrollerElement().style.maxHeight = this.get('maxRows') * 18.5 + 'px'; } this.editor.codemirror.on('change', this.proxy(this.onEditorChange)); acf.doAction('acfe/fields/code_editor/init', this.editor, this); acf.doAction('acfe/fields/code_editor/init/name=' + this.get('name'), this.editor, this); acf.doAction('acfe/fields/code_editor/init/key=' + this.get('key'), this.editor, this); }, onEditorChange: function(e, $el) { this.editor.codemirror.save(); this.$input().change(); }, onShow: function() { if (this.editor.codemirror) { this.editor.codemirror.refresh(); } }, onDuplicate: function(e, $el, $duplicate) { $duplicate.find('.CodeMirror:last').remove(); }, }); acf.registerFieldType(CodeEditor); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Column */ var Column = acf.Field.extend({ wait: 'new_field', type: 'acfe_column', $control: function() { return this.$('.acf-fields:first'); }, initialize: function() { if (this.$el.is('td')) { this.$el.closest('.acf-table').find('th[data-type="acfe_column"]').remove(); this.remove(); } if (this.get('endpoint')) { this.$el.find('> .acf-label').remove(); this.$el.find('> .acf-input').remove(); return; } var $field = this.$el; var $label = this.$el.find('> .acf-label'); var $input = this.$inputWrap(); var $wrap = this.$control(); $label.remove(); var $parent = $field.parent(); $parent.addClass('acfe-column-wrapper'); $wrap.addClass($parent.hasClass('-left') ? '-left' : ''); $wrap.addClass($parent.hasClass('-clear') ? '-clear' : ''); $wrap.append($field.nextUntil('.acf-field-acfe-column', '.acf-field')); } }); acf.registerFieldType(Column); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: Overwrite */ var FlexibleContent = acf.models.FlexibleContentField; acf.models.FlexibleContentField = FlexibleContent.extend({ addSortable: function(self) { // bail early if max 1 row if (this.get('max') == 1) { return; } // add sortable this.$layoutsWrap().sortable({ items: ' > .layout', handle: '> .acf-fc-layout-handle', forceHelperSize: false, // changed to false forcePlaceholderSize: true, revert: 50, tolerance: 'pointer', // changed to pointer scroll: true, stop: function(event, ui) { self.render(); }, update: function(event, ui) { self.$input().trigger('change'); } }); }, add: function(args) { // get element var $el = FlexibleContent.prototype.add.apply(this, arguments); if ($el.length) { // used in append $el.data('added', true); } }, }); /** * Flexible Content: Validation */ new acf.Model({ actions: { 'invalid_field': 'onInvalidField', 'valid_field': 'onValidField', }, onInvalidField: function(field) { field.$el.parents('.layout').addClass('acfe-flexible-modal-edit-error'); }, onValidField: function(field) { field.$el.parents('.layout').each(function() { var $layout = $(this); if (!$layout.find('.acf-error').length) { $layout.removeClass('acfe-flexible-modal-edit-error'); } }); } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: Append */ var Field = acfe.FieldExtender({ id: 'fc_append', type: 'flexible_content', initialize: function() { // initialize this.getParent(Field).initialize.apply(this, arguments); // add events this.addEvents({ 'appendLayout': 'acfeAppendLayout', }); }, acfeAppendLayout: function(e, $el, $layout) { // only native acf duplicate // .acfe-layout-duplicated is old clone & copy/paste if (!$layout.is('.acfe-layout-duplicated')) { if (this.has('acfeFlexibleModalEdition')) { this.acfeModalEdit(null, $layout); } else { this.openLayout($layout); } } // check if inside modal var modal = acfe.getModal($layout.closest('.acfe-modal.-open')); // already inside another modal if (modal) { this.acfeScrollToLayout($layout, modal.$content()); // old clone + copy/paste } else if ($layout.is('.acfe-layout-duplicated')) { this.acfeScrollToLayout($layout); // added or duplicated } else { // we must set timeout to let data() being appended this.setTimeout(function() { if ($layout.data('added')) { this.acfeScrollToLayout($layout); } }, 10); } }, acfeScrollToLayout: function($layout, $parent) { // vars var hasParent = $parent || false; $parent = $parent || $('body, html'); // emulate acf.focusAttention if (!acf.isInView($layout)) { var scrollTop = hasParent ? $layout.position().top : $layout.offset().top - $(window).height() / 2; $parent.animate({ scrollTop: scrollTop }, 500); } }, }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: One Click */ var Field = acfe.FieldExtender({ id: 'fc_async', type: 'flexible_content', condition: function() { return this.has('acfeFlexibleAjax'); }, add: function(args) { // defaults args = acf.parseArgs(args, { layout: '', before: false }); // validate if (!this.allowAdd()) { return false; } // ajax data var ajaxData = { action: 'acfe/flexible/models', field_key: this.get('key'), layout: args.layout, }; // beforeSend callback var beforeSend = function() { $('body').addClass('-loading'); } // complete callback var complete = function() { $('body').removeClass('-loading'); } // success callback var success = this.proxy(function(html) { if (html) { var $layout = $(html); var uniqid = acf.uniqid(); var search = 'acf[' + this.get('key') + '][acfcloneindex]'; var replace = this.$control().find('> input[type=hidden]').attr('name') + '[' + uniqid + ']'; // add row var $el = acf.duplicate({ target: $layout, search: search, replace: replace, append: this.proxy(function($el, $el2) { // append if (args.before) { args.before.before($el2); } else { this.$layoutsWrap().append($el2); } // enable acf.enable($el2, this.cid); // render this.render(); }) }); // fix data-id $el.attr('data-id', uniqid); // trigger change for validation errors this.$input().trigger('change'); // return return $el; } }); // ajax $.ajax({ url: acf.get('ajaxurl'), data: acf.prepareForAjax(ajaxData), dataType: 'html', type: 'post', beforeSend: beforeSend, success: success, complete: complete }); } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Init */ var flexible = acf.getFieldType('flexible_content'); var model = flexible.prototype; // Layout: Clone model.events['click [data-acfe-flexible-control-clone]'] = 'acfeCloneLayout'; model.acfeCloneLayout = function(e, $el) { // Get Flexible var flexible = this; // Vars var $layout = $el.closest('.layout'); var layout_name = $layout.data('layout'); // Popup min/max var $popup = $(flexible.$popup().html()); var $layouts = flexible.$layouts(); var countLayouts = function(name) { return $layouts.filter(function() { return $(this).data('layout') === name; }).length; }; // vars var $a = $popup.find('[data-layout="' + layout_name + '"]'); var min = $a.data('min') || 0; var max = $a.data('max') || 0; var count = countLayouts(layout_name); // max if (max && count >= max) { $el.addClass('disabled'); return false; } else { $el.removeClass('disabled'); } // Fix inputs flexible.acfeFixInputs($layout); var $_layout = $layout.clone(); // Clean Layout flexible.acfeCleanLayouts($_layout); var parent = $el.closest('.acf-flexible-content').find('> input[type=hidden]').attr('name'); // Clone var $layout_added = flexible.acfeDuplicate({ layout: $_layout, before: $layout, parent: parent }); } // Layout: Copy model.events['click [data-acfe-flexible-control-copy]'] = 'acfeCopyLayout'; model.acfeCopyLayout = function(e, $el) { // Get Flexible var flexible = this; // Vars var $layout = $el.closest('.layout').clone(); var source = flexible.$control().find('> input[type=hidden]').attr('name'); // Fix inputs flexible.acfeFixInputs($layout); // Clean layout flexible.acfeCleanLayouts($layout); // Get layout data var data = JSON.stringify({ source: source, layouts: $layout[0].outerHTML }); acfe.copyClipboard(data, { auto: acf.__('Layout data has been copied to your clipboard.') + "\n" + acf.__('You can now paste it on another page, using the "Paste" button action.'), manual: acf.__('Please copy the following data to your clipboard.') + "\n" + acf.__('You can then paste it on another page, using the "Paste" button action.'), }); } // Flexible: Copy Layouts model.acfeCopyLayouts = function() { // Get Flexible var flexible = this; // Get layouts var $layouts = flexible.$layoutsWrap().clone(); var source = flexible.$control().find('> input[type=hidden]').attr('name'); // Fix inputs flexible.acfeFixInputs($layouts); // Clean layout flexible.acfeCleanLayouts($layouts); // Get layouts data var data = JSON.stringify({ source: source, layouts: $layouts.html() }); acfe.copyClipboard(data, { auto: acf.__('Layouts data have been copied to your clipboard.') + "\n" + acf.__('You can now paste it on another page, using the "Paste" button action.'), manual: acf.__('Please copy the following data to your clipboard.') + "\n" + acf.__('You can then paste it on another page, using the "Paste" button action.'), }); } // Flexible: Paste Layouts model.acfePasteLayouts = function() { // Get Flexible var flexible = this; var paste = prompt(acf.__('Please paste previously copied layout data in the following field:')); // No input if (paste == null || paste === '') return; try { // Paste HTML var data = JSON.parse(paste); var source = data.source; var $html = $(data.layouts); // Parsed layouts var $html_layouts = $html.closest('[data-layout]'); if (!$html_layouts.length) return alert('No layouts data available'); // Popup min/max var $popup = $(flexible.$popup().html()); var $layouts = flexible.$layouts(); var countLayouts = function(name) { return $layouts.filter(function() { return $(this).data('layout') === name; }).length; }; // init var validated_layouts = []; // Each first level layouts $html_layouts.each(function() { var $this = $(this); var layout_name = $this.data('layout'); // vars var $a = $popup.find('[data-layout="' + layout_name + '"]'); var min = $a.data('min') || 0; var max = $a.data('max') || 0; var count = countLayouts(layout_name); // max if (max && count >= max) return; // Validate layout against available layouts var get_clone_layout = flexible.$clone($this.attr('data-layout')); // Layout is invalid if (!get_clone_layout.length) return; // Add validated layout validated_layouts.push($this); }); // Nothing to add if (!validated_layouts.length) return alert('No layouts could be pasted'); // Add layouts $.each(validated_layouts, function() { var $layout = $(this); var search = source + '[' + $layout.attr('data-id') + ']'; var target = flexible.$control().find('> input[type=hidden]').attr('name'); flexible.acfeDuplicate({ layout: $layout, before: false, search: search, parent: target }); }); } catch (e) { console.log(e); alert('Invalid data'); } } // Flexible: Dropdown model.events['click [data-name="acfe-flexible-control-button"]'] = 'acfeControl'; model.acfeControl = function(e, $el) { // Get Flexible var flexible = this; // Vars var $dropdown = $el.next('.tmpl-acfe-flexible-control-popup').html(); // Init Popup var Popup = acf.models.TooltipConfirm.extend({ render: function() { this.html(this.get('text')); this.$el.addClass('acf-fc-popup'); } }); // New Popup var popup = new Popup({ target: $el, targetConfirm: false, text: $dropdown, context: flexible, confirm: function(e, $el) { if ($el.attr('data-acfe-flexible-control-action') === 'paste') flexible.acfePasteLayouts(); else if ($el.attr('data-acfe-flexible-control-action') === 'copy') flexible.acfeCopyLayouts(); } }); popup.on('click', 'a', 'onConfirm'); } // Flexible: Duplicate model.acfeDuplicate = function(args) { // Arguments args = acf.parseArgs(args, { layout: '', before: false, parent: false, search: '', replace: '', }); // Validate if (!this.allowAdd()) return false; var uniqid = acf.uniqid(); if (args.parent) { if (!args.search) { args.search = args.parent + '[' + args.layout.attr('data-id') + ']'; } args.replace = args.parent + '[' + uniqid + ']'; } var duplicate_args = { target: args.layout, search: args.search, replace: args.replace, append: this.proxy(function($el, $el2) { // Add class to duplicated layout $el2.addClass('acfe-layout-duplicated'); // Reset UniqID $el2.attr('data-id', uniqid); // append before if (args.before) { // Fix clone: Use after() instead of native before() args.before.after($el2); } // append end else { this.$layoutsWrap().append($el2); } // enable acf.enable($el2, this.cid); // render this.render(); }) } if (acfe.versionCompare(acf.get('acf_version'), '<', '5.9')) { // Add row var $el = acf.duplicate(duplicate_args); // Hotfix for ACF Pro 5.9 } else { // Add row var $el = model.acfeNewAcfDuplicate(duplicate_args); } // trigger change for validation errors this.$input().trigger('change'); // Fix tabs conditionally hidden var tabs = acf.getFields({ type: 'tab', parent: $el, }); if (tabs.length) { $.each(tabs, function() { if (this.$el.hasClass('acf-hidden')) { this.tab.$el.addClass('acf-hidden'); } }); } // return return $el; } /** * Based on acf.duplicate (5.9) * * doAction('duplicate) has been commented out * This fix an issue with the WYSIWYG editor field during copy/paste since ACF 5.9 */ model.acfeNewAcfDuplicate = function(args) { // allow jQuery if (args instanceof jQuery) { args = { target: args }; } // defaults args = acf.parseArgs(args, { target: false, search: '', replace: '', rename: true, before: function($el) {}, after: function($el, $el2) {}, append: function($el, $el2) { $el.after($el2); } }); // compatibility args.target = args.target || args.$el; // vars var $el = args.target; // search args.search = args.search || $el.attr('data-id'); args.replace = args.replace || acf.uniqid(); // before // - allow acf to modify DOM // - fixes bug where select field option is not selected args.before($el); acf.doAction('before_duplicate', $el); // clone var $el2 = $el.clone(); // rename if (args.rename) { acf.rename({ target: $el2, search: args.search, replace: args.replace, replacer: (typeof args.rename === 'function' ? args.rename : null) }); } // remove classes $el2.removeClass('acf-clone'); $el2.find('.ui-sortable').removeClass('ui-sortable'); // after // - allow acf to modify DOM args.after($el, $el2); acf.doAction('after_duplicate', $el, $el2); // append args.append($el, $el2); /** * Fires after an element has been duplicated and appended to the DOM. * * @date 30/10/19 * @since 5.8.7 * * @param jQuery $el The original element. * @param jQuery $el2 The duplicated element. */ //acf.doAction('duplicate', $el, $el2 ); // append acf.doAction('append', $el2); // return return $el2; }; // Flexible: Fix Inputs model.acfeFixInputs = function($layout) { $layout.find('input').each(function() { $(this).attr('value', this.value); }); $layout.find('textarea').each(function() { $(this).html(this.value); }); $layout.find('input:radio,input:checkbox').each(function() { if (this.checked) $(this).attr('checked', 'checked'); else $(this).attr('checked', false); }); $layout.find('option').each(function() { if (this.selected) $(this).attr('selected', 'selected'); else $(this).attr('selected', false); }); } // Flexible: Clean Layout model.acfeCleanLayouts = function($layout) { // Clean WP Editor $layout.find('.acf-editor-wrap').each(function() { var $input = $(this); $input.find('.wp-editor-container div').remove(); $input.find('.wp-editor-container textarea').css('display', ''); }); // Clean Block Editor $layout.find('.acfe-block-editor-wrapper').each(function() { var $editor = $(this); $editor.find('.editor').remove(); }); // Clean Date $layout.find('.acf-date-picker').each(function() { var $input = $(this); $input.find('input.input').removeClass('hasDatepicker').removeAttr('id'); }); // Clean Time $layout.find('.acf-time-picker').each(function() { var $input = $(this); $input.find('input.input').removeClass('hasDatepicker').removeAttr('id'); }); // Clean DateTime $layout.find('.acf-date-time-picker').each(function() { var $input = $(this); $input.find('input.input').removeClass('hasDatepicker').removeAttr('id'); }); // Clean Code Editor $layout.find('.acfe-field-code-editor').each(function() { var $input = $(this); $input.find('.CodeMirror').remove(); }); // Clean Color Picker $layout.find('.acf-color-picker').each(function() { var $input = $(this); var $color_picker = $input.find('> input'); var $color_picker_proxy = $input.find('.wp-picker-container input.wp-color-picker').clone(); $color_picker.after($color_picker_proxy); $input.find('.wp-picker-container').remove(); }); // Clean Post Object $layout.find('.acf-field-post-object').each(function() { var $input = $(this); $input.find('> .acf-input span').remove(); $input.find('> .acf-input select').removeAttr('tabindex aria-hidden').removeClass(); }); // Clean Page Link $layout.find('.acf-field-page-link').each(function() { var $input = $(this); $input.find('> .acf-input span').remove(); $input.find('> .acf-input select').removeAttr('tabindex aria-hidden').removeClass(); }); // Clean Select2 $layout.find('.acf-field-select').each(function() { var $input = $(this); $input.find('> .acf-input span').remove(); $input.find('> .acf-input select').removeAttr('tabindex aria-hidden').removeClass(); }); // Clean FontAwesome $layout.find('.acf-field-font-awesome').each(function() { var $input = $(this); $input.find('> .acf-input span').remove(); $input.find('> .acf-input select').removeAttr('tabindex aria-hidden'); }); // Clean Tab $layout.find('.acf-tab-wrap').each(function() { var $wrap = $(this); var $content = $wrap.closest('.acf-fields'); var tabs = []; $.each($wrap.find('li a'), function() { tabs.push($(this)); }); $content.find('> .acf-field-tab').each(function() { $current_tab = $(this); $.each(tabs, function() { var $this = $(this); if ($this.attr('data-key') !== $current_tab.attr('data-key')) return; $current_tab.find('> .acf-input').append($this); }); }); $wrap.remove(); }); // Clean Accordion $layout.find('.acf-field-accordion').each(function() { var $input = $(this); $input.find('> .acf-accordion-title > .acf-accordion-icon').remove(); // Append virtual endpoint after each accordion $input.after('<div class="acf-field acf-field-accordion" data-type="accordion"><div class="acf-input"><div class="acf-fields" data-endpoint="1"></div></div></div>'); }); } })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: Events */ var eventManager = new acf.Model({ actions: { 'new_field/type=flexible_content': 'newField', 'show': 'onShow', 'hide': 'onHide', 'append': 'onAppend', }, newField: function(field) { // placeholder field.addEvents({ 'click .acfe-fc-placeholder': 'onClickCollapse' }); // inline close button field.addEvents({ 'click .acfe-flexible-opened-actions > a': 'onClickCollapse' }); if (field.has('acfeFlexibleModalEdition') && (field.has('acfeFlexiblePlaceholder') || field.has('acfeFlexiblePreview'))) { // collapse action field.removeEvents({ 'click [data-name="collapse-layout"]': 'onClickCollapse' }); // placeholder collapse Action field.removeEvents({ 'click .acfe-fc-placeholder': 'onClickCollapse' }); } // lock if (field.has('acfeFlexibleLock')) { field.removeEvents({ 'mouseover': 'onHover' }); } field.$layouts().each(function() { field.trigger('newLayout', [$(this)]); }); }, onShow: function($el, context) { // validate if (context === 'collapse' && $el.is('.layout')) { // get field var field = acf.getClosestField($el); // trigger field.trigger('showLayout', [$el]); } }, onHide: function($el, context) { // validate if (context === 'collapse' && $el.is('.layout') && !$el.is('.acf-clone')) { // get field var field = acf.getClosestField($el); // trigger field.trigger('hideLayout', [$el]); } }, onAppend: function($el) { // check element is a jQuery object with .layout class if ($el?.[0]?.classList?.contains('layout')) { // get field var field = acf.getClosestField($el); // trigger field.trigger('newLayout', [$el]); field.trigger('appendLayout', [$el]); } }, }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: Modal Edit */ var Field = acfe.FieldExtender({ id: 'fc_modal_edit', type: 'flexible_content', events: { 'click [data-action="acfe-flexible-modal-edit"]': 'acfeModalEdit', }, acfeModalEdit: function(e, $el) { // layout var $layout = $el.closest('.layout'); // modal var $modal = $layout.find('> .acfe-modal.-fields'); // vars var $handle = $layout.find('> .acf-fc-layout-handle'); var order = $handle.find('> .acf-fc-layout-order').outerHTML(); var title = acfe.getTextNode($handle.find('.acfe-layout-title')); var modal = acfe.getModal($modal, { open: true, title: order + title, onOpen: this.proxy(function() { this.openLayout($layout); }), onClose: this.proxy(function() { this.closeLayout($layout); }), }); } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: Modal Select */ var Field = acfe.FieldExtender({ id: 'fc_modal_select', type: 'flexible_content', condition: function() { return this.has('acfeFlexibleModal') && this.$clones().length > 1; }, onClickAdd: function(e, $el) { // get flexible var flexible = this; // validate if (!flexible.validateAdd()) { return false; } // vars var layoutsCategories = this.getLayoutsCategories(); // retrieve original layout (if user clicked on the '+' icon) var $before = $el.hasClass('acf-icon') ? $el.closest('.layout') : null; // Open Modal acfe.newModal({ title: flexible.get('acfeFlexibleModalTitle', acf.__('Add Row')), class: 'acfe-modal-select-' + flexible.get('name') + ' acfe-modal-select-' + flexible.get('key'), size: flexible.get('acfeFlexibleModalSize'), destroy: true, events: { 'click .acfe-flexible-categories a': 'onClickCategory', 'click a[data-layout]': 'onClickLayout', }, content: function() { return '<div class="acfe-flex-container">' + flexible.getPopupHTML() + '</div>' }, onOpen: function() { // add categories tabs if (layoutsCategories) { this.$content().prepend(layoutsCategories); } // add columns class if (flexible.has('acfeFlexibleModalCol')) { this.$('.acfe-modal-content .acfe-flex-container').addClass('acfe-col-' + flexible.get('acfeFlexibleModalCol')); } // add thumbnails class if (flexible.has('acfeFlexibleThumbnails')) { this.$('.acfe-modal-content .acfe-flex-container').addClass('acfe-flex-thumbnails'); } // add icon info class var icon = acfe.versionCompare(acf.get('wp_version'), '>=', '5.5') ? 'dashicons-info-outline' : 'dashicons-info'; this.$('li a span.badge').addClass('acf-js-tooltip dashicons ' + icon); // autofocus fix this.$('li:first-of-type a').blur(); }, onClickCategory: function(e, $el) { // prevent default e.preventDefault(); // vars var $activeCategory = $el; var activeCategory = $activeCategory.data('acfe-flexible-category'); // remove all active $activeCategory.closest('.acfe-flexible-categories').find('a').removeClass('nav-tab-active'); // set active on current $activeCategory.addClass('nav-tab-active'); // show all layouts this.$('a[data-layout] span[data-acfe-flexible-category]').closest('li').show(); // active category is 'show all' if (activeCategory === 'acfe-all') { return; } // loop through layouts to check category this.$('a[data-layout] span[data-acfe-flexible-category]').each(function() { // vars var $span = $(this); var categories = $span.data('acfe-flexible-category'); // hide layout $span.closest('li').hide(); for (var category of categories) { if (acfe.slugify(activeCategory) === acfe.slugify(category)) { // show layout $span.closest('li').show(); break; } } }); }, onClickLayout: function(e, $el) { e.preventDefault(); // close modal this.close(); // Add layout flexible.add({ layout: $el.data('layout'), before: $before }); }, }); }, getLayoutsCategories: function() { // get layouts selection html var $layouts = $(this.getPopupHTML()); // categories vars var html = ''; var data = []; // check if categories exist if ($layouts.find('li a span[data-acfe-flexible-category]').exists()) { // loop $layouts.find('li a span[data-acfe-flexible-category]').each(function() { // get categories from data var categories = $(this).data('acfe-flexible-category'); // loop categories categories.map(function(label) { // generate slug var slug = acfe.slugify(label); // search for slug var search = data.filter(function(row) { return row.slug === slug; }); // slug not found, append if (acfe.isEmpty(search)) { data.push({ slug: slug, label: label }); } }); }); // prepare html if (data.length) { html += '<h2 class="acfe-flexible-categories nav-tab-wrapper">'; html += '<a href="#" data-acfe-flexible-category="acfe-all" class="nav-tab nav-tab-active"><span class="dashicons dashicons-menu"></span></a>'; data.sort(function(a, b) { return a.slug > b.slug ? 1 : -1; }); data.map(function(row) { html += '<a href="#" data-acfe-flexible-category="' + row.label + '" class="nav-tab">' + row.label + '</a>'; }); html += '</h2>'; } } return html; }, }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: Modal Settings */ var Field = acfe.FieldExtender({ id: 'fc_modal_settings', type: 'flexible_content', events: { 'click [data-acfe-flexible-settings]': 'acfeLayoutSettings', }, acfeLayoutSettings: function(e, $el) { // layout var $layout = $el.closest('.layout'); // modal var $modal = $layout.find('> .acfe-modal.-settings'); // vars var $handle = $layout.find('> .acf-fc-layout-handle'); var order = $handle.find('> .acf-fc-layout-order').outerHTML(); var title = acfe.getTextNode($handle.find('.acfe-layout-title')); var modal = acfe.getModal($modal, { open: true, title: order + title, onClose: this.proxy(function() { if (this.has('acfeFlexiblePreview')) { this.closeLayout($layout); } }) }); } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: One Click */ var Field = acfe.FieldExtender({ id: 'fc_one_click', type: 'flexible_content', condition: function() { return this.$clones().length === 1; }, onClickAdd: function(e, $el) { // validate if (!this.validateAdd()) { return false; } // vars var $clones = this.$clones(); var layout = $($clones[0]).data('layout'); // within layout var $before = null; if ($el.hasClass('acf-icon')) { $before = $el.closest('.layout'); } // add layout this.add({ layout: layout, before: $before }); // hide popup just in case var $popup = $('.acf-fc-popup'); if ($popup.length) { $popup.hide(); } } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: Placeholder */ var Field = acfe.FieldExtender({ id: 'fc_placeholder', type: 'flexible_content', condition: function() { return this.has('acfeFlexiblePlaceholder'); }, initialize: function() { // initialize this.getParent(Field).initialize.apply(this, arguments); // add events this.addEvents({ 'showLayout': 'acfePlaceholderShowLayout', 'hideLayout': 'acfePlaceholderHideLayout', 'newLayout': 'acfePlaceholderNewLayout', }); }, acfePlaceholderShowLayout: function(e, $el, $layout) { // hide placeholder if (!this.has('acfeFlexibleModalEdition')) { acf.hide($layout.find('> .acfe-fc-placeholder')); } }, acfePlaceholderHideLayout: function(e, $el, $layout) { // show placeholder acf.show($layout.find('> .acfe-fc-placeholder')); }, acfePlaceholderNewLayout: function(e, $el, $layout) { // show placeholder if (this.isLayoutClosed($layout)) { acf.show($layout.find('> .acfe-fc-placeholder')); } }, }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: Preview */ var Field = acfe.FieldExtender({ id: 'fc_preview', type: 'flexible_content', condition: function() { return this.has('acfeFlexiblePreview'); }, events: { 'hideLayout': 'acfePreviewHideLayout', 'appendLayout': 'acfePreviewAppendLayout', }, acfeLayoutPreview: function($layout) { // validate if (!this.isLayoutClosed($layout) || $layout.find('> .acfe-fc-placeholder').hasClass('-loading')) { return; } // vars var key = this.get('key'); var name = this.get('name'); var $el = this.$el; var layout = $layout.data('layout'); var index = $layout.index(); var $placeholder = $layout.find('> .acfe-fc-placeholder'); $placeholder.addClass('acfe-fc-preview -loading').find('> .acfe-flexible-placeholder').prepend('<span class="spinner"></span>'); $placeholder.find('> .acfe-fc-overlay').addClass('-hover'); // vars var $input = $layout.children('input'); var prefix = $input.attr('name').replace('[acf_fc_layout]', ''); // ajax data var ajaxData = { action: 'acfe/flexible/layout_preview', field_key: key, i: index, layout: layout, value: acf.serialize($layout, prefix) }; acf.doAction('acfe/fields/flexible_content/before_preview', $el, $layout, ajaxData); acf.doAction('acfe/fields/flexible_content/before_preview/name=' + name, $el, $layout, ajaxData); acf.doAction('acfe/fields/flexible_content/before_preview/key=' + key, $el, $layout, ajaxData); acf.doAction('acfe/fields/flexible_content/before_preview/layout=' + layout, $el, $layout, ajaxData); acf.doAction('acfe/fields/flexible_content/before_preview/name=' + name + '&layout=' + layout, $el, $layout, ajaxData); acf.doAction('acfe/fields/flexible_content/before_preview/key=' + key + '&layout=' + layout, $el, $layout, ajaxData); // on success var onSuccess = function(response) { if (response) { $placeholder.find('> .acfe-flexible-placeholder').html(response); } else { $placeholder.removeClass('acfe-fc-preview'); } acf.doAction('acfe/fields/flexible_content/preview', response, $el, $layout, ajaxData); acf.doAction('acfe/fields/flexible_content/preview/name=' + name, response, $el, $layout, ajaxData); acf.doAction('acfe/fields/flexible_content/preview/key=' + key, response, $el, $layout, ajaxData); acf.doAction('acfe/fields/flexible_content/preview/layout=' + layout, response, $el, $layout, ajaxData); acf.doAction('acfe/fields/flexible_content/preview/name=' + name + '&layout=' + layout, response, $el, $layout, ajaxData); acf.doAction('acfe/fields/flexible_content/preview/key=' + key + '&layout=' + layout, response, $el, $layout, ajaxData); }; // on complete var onComplete = function() { $placeholder.find('> .acfe-fc-overlay').removeClass('-hover'); $placeholder.removeClass('-loading').find('> .acfe-flexible-placeholder > .spinner').remove(); }; // ajax $.ajax({ url: acf.get('ajaxurl'), data: acf.prepareForAjax(ajaxData), dataType: 'html', type: 'post', success: onSuccess, complete: onComplete }); }, acfePreviewHideLayout: function(e, $el, $layout) { this.acfeLayoutPreview($layout); }, acfePreviewAppendLayout: function(e, $el, $layout) { this.acfeLayoutPreview($layout); }, }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: State */ var Field = acfe.FieldExtender({ id: 'fc_state', type: 'flexible_content', condition: function() { return this.has('acfeFlexibleOpen'); }, addCollapsed: function() { // ... } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: Title Ajax */ var Field = acfe.FieldExtender({ id: 'fc_title_ajax', type: 'flexible_content', condition: function() { return this.has('acfeFlexibleRemoveAjaxTitle'); }, renderLayout: function() { // ... } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: Title Inline */ var Field = acfe.FieldExtender({ id: 'fc_title_inline', type: 'flexible_content', condition: function() { return this.has('acfeFlexibleTitleEdition'); }, events: { 'click .acf-fc-layout-handle': 'acfeEditLayoutTitleToggleHandle', 'click .acfe-layout-title-text': 'acfeEditLayoutTitle', 'blur input.acfe-flexible-control-title': 'acfeEditLayoutTitleToggle', 'click input.acfe-flexible-control-title': 'acfeEditLayoutTitlePropagation', 'input [data-acfe-flexible-control-title-input]': 'acfeEditLayoutTitleInput', 'keypress [data-acfe-flexible-control-title-input]': 'acfeEditLayoutTitleInputEnter', }, acfeEditLayoutTitleToggleHandle: function(e, $el) { // layout var $layout = $el.closest('.layout'); if ($layout.hasClass('acfe-flexible-title-edition')) { $layout.find('> .acf-fc-layout-handle > .acfe-layout-title > input.acfe-flexible-control-title').trigger('blur'); } }, acfeEditLayoutTitle: function(e, $el) { e.stopPropagation(); this.acfeEditLayoutTitleToggle(e, $el); }, acfeEditLayoutTitleToggle: function(e, $el) { // vars var $layout = $el.closest('.layout'); var $handle = $layout.find('> .acf-fc-layout-handle'); var $title = $handle.find('.acfe-layout-title'); if ($layout.hasClass('acfe-flexible-title-edition')) { var $input = $title.find('> input[data-acfe-flexible-control-title-input]'); if ($input.val() === '') { $input.val($input.attr('placeholder')).trigger('input'); } $layout.removeClass('acfe-flexible-title-edition'); $input.insertAfter($handle); } else { var $input = $layout.find('> input[data-acfe-flexible-control-title-input]'); var $input = $input.appendTo($title); $layout.addClass('acfe-flexible-title-edition'); $input.focus().attr('size', $input.val().length); } }, acfeEditLayoutTitlePropagation: function(e, $el) { e.stopPropagation(); }, acfeEditLayoutTitleInput: function(e, $el) { // vars var $layout = $el.closest('.layout'); var $title = $layout.find('> .acf-fc-layout-handle .acfe-layout-title .acfe-layout-title-text'); var val = $el.val(); $el.attr('size', val.length); $title.html(val); }, acfeEditLayoutTitleInputEnter: function(e, $el) { // 'enter' if (e.keyCode === 13) { e.preventDefault(); $el.blur(); } } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Flexible Content: Toggle */ var Field = acfe.FieldExtender({ id: 'fc_toggle', type: 'flexible_content', condition: function() { return this.has('acfeFlexibleToggle'); }, events: { 'click [data-acfe-flexible-control-toggle]': 'acfeLayoutToggle', }, acfeLayoutToggle: function(e, $el) { // vars var $layout = $el.closest('.layout'); var $input = $layout.find('> .acfe-flexible-layout-toggle'); if ($input.length) { if ($input.val() === '1') { $layout.removeClass('acfe-flexible-layout-hidden'); $input.val(''); } else { $layout.addClass('acfe-flexible-layout-hidden'); $input.val('1'); } } } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Group */ var Group = acf.Field.extend({ wait: false, type: 'group', events: { 'duplicateField': 'onDuplicate' }, initialize: function() { if (this.has('acfeGroupModal')) { this.$inputWrap().find('> .acf-fields, > .acf-table').wrapAll('<div class="acfe-modal"><div class="acfe-modal-wrapper"><div class="acfe-modal-content"></div></div></div>'); this.$inputWrap().append('<a href="#" class="acf-button button" data-modal>' + this.get('acfeGroupModalButton') + '</a>'); this.initializeModal(); } }, initializeModal: function() { // normal title var title = this.$labelWrap().find('label').text().trim(); // inside table if (this.$el.is('td')) { title = this.get('acfeGroupModalButton'); var $th = this.$el.closest('table').find(' > thead th[data-key="' + this.get('key') + '"]'); if ($th.length) { title = acfe.getTextNode($th); } } // fallback to button text if (!title.length) { title = this.get('acfeGroupModalButton'); } // modal this.getModal({ title: title, size: this.has('acfeGroupModalSize') ? this.get('acfeGroupModalSize') : 'large', footer: this.has('acfeGroupModalClose') ? acf.__('Close') : false, class: 'acfe-modal-edit-' + this.get('name') + ' acfe-modal-edit-' + this.get('key') }); }, onDuplicate: function(e, $el, $duplicate) { $duplicate.find('.acf-input:first > a[data-modal]').remove(); } }); acf.registerFieldType(Group); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } // fix icon picker field // in alignMediaLibraryTabToCurrentValue(), the field update the img src attribute with this.get('mediaLibraryPreviewUrl') // but this will return a value only when an image is actually selected // otherwise, it returns 'undefined' and thus never update the src, because $.attr() ignore 'undefined' values // when using acfe.get() extension, it returns 'null' instead of 'undefined', and $.attr() update the src attribute as 'empty' // alignMediaLibraryTabToCurrentValue() is executed both on field render and when a user select an image (weird design) if (typeof acf.models.IconPickerField !== 'undefined') { // rollback to legacy acf.Model.get() acf.models.IconPickerField.prototype.get = function(name) { return this.data[name]; }; } })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Radio */ var Radio = acf.models.RadioField; acf.models.RadioField = Radio.extend({ // add setValue method // this allows to use field.val('new_value') to assign a new value to the field setValue: function(val) { // clear value if (!val) { return this.clearValue(); } // get option with value var $option = this.$(':radio[value="' + val + '"]'); // option exists and is not already selected if ($option.length && !$option.is(':checked')) { // select the option $option.prop('checked', true).trigger('change'); this.onClick(null, $option); } }, // add clearValue method // this allows to set the value to the first radio or if allow_null is enabled, to null clearValue: function() { // if allow_null is enabled, get selected option and click it if (this.get('allow_null')) { if (this.$input().length) { this.onClick(null, this.$input()); } // otherwise use first radio value as default value } else { this.val(this.$(':radio').first().val()); } } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: reCaptcha */ var reCaptcha = acf.Field.extend({ type: 'acfe_recaptcha', wait: 'load', widgetID: 0, events: { 'invalidField': 'onInvalidField' }, $control: function() { return this.$('.acf-input-wrap'); }, $input: function() { return this.$('input[type="hidden"]'); }, initialize: function() { reCaptchaAPI.load(this, this.render); }, render: function() { if (this.get('version') === 'v2') { this.renderV2(); } else if (this.get('version') === 'v3') { this.renderV3(); } }, renderV2: function() { // request this.widgetID = grecaptcha.render(this.$control().find('> div')[0], { 'sitekey': this.get('siteKey'), 'theme': this.get('theme'), 'size': this.get('size'), 'callback': this.proxy(function(response) { acf.val(this.$input(), response, true); this.removeError(); }), 'error-callback': this.proxy(function() { this.showError('An error has occured'); }), 'expired-callback': this.proxy(function() { this.showError('reCaptcha has expired'); }) }); }, renderV3: function() { // vars var $input = this.$input(); var sitekey = this.get('siteKey'); // request var request = function() { grecaptcha.execute(sitekey, { action: 'homepage' }).then(function(response) { acf.val($input, response, true); }); // refresh every 80sec // this avoid an issue where token becomes invalid after 2min setTimeout(request, 80 * 1000); } // execute request request(); }, reset: function() { // reset v2 if (this.get('version') === 'v2') { grecaptcha.reset(this.widgetID); acf.val(this.$input(), '', true); // reset v3 } else if (this.get('version') === 'v3') { this.renderV3(); } }, onInvalidField: function(e, $el) { this.reset(); }, }); acf.registerFieldType(reCaptcha); /** * recpatchaAPI * * @type {acf.Model} */ var reCaptchaAPI = new acf.Model({ busy: false, load: function(field, callback) { // defaults callback = field.proxy(callback); // vars var url_v2 = 'https://www.google.com/recaptcha/api.js?render=explicit'; var url_v3 = 'https://www.google.com/recaptcha/api.js?render=' + field.get('siteKey'); var url = field.get('version') === 'v2' ? url_v2 : url_v3; // check if recaptcha exists if (typeof grecaptcha !== 'undefined' || acf.isset(window, 'grecaptcha')) { return callback(); } acf.addAction('acfe/recpatcha_loaded', callback); // already busy if (this.busy) { return; } // set busy this.busy = true; // load api $.ajax({ url: url, dataType: 'script', cache: true, context: this, success: function() { grecaptcha.ready(this.proxy(function() { acf.doAction('acfe/recpatcha_loaded'); this.busy = false; })); } }); } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Init */ var repeater = acf.getFieldType('repeater'); var model = repeater.prototype; // Repeater: Lock Layouts model.acfeOnHover = function() { var repeater = this; // remove event repeater.off('mouseover'); } /** * Spawn */ acf.addAction('new_field/type=repeater', function(repeater) { // ACFE: Lock if (repeater.has('acfeRepeaterLock')) { repeater.removeEvents({ 'mouseover': 'onHover' }); repeater.addEvents({ 'mouseover': 'acfeOnHover' }); } // ACFE: Remove Actions if (repeater.has('acfeRepeaterRemoveActions')) { repeater.$actions().remove(); repeater.$el.find('thead:first > tr > th.acf-row-handle:last').remove(); repeater.$rows().find('> .acf-row-handle:last').remove(); repeater.$control().find('> .acfe-repeater-stylised-button').remove(); } // ACFE: Stylised button if (repeater.has('acfeRepeaterStylisedButton')) { repeater.$button().removeClass('button-primary'); repeater.$actions().wrap('<div class="acfe-repeater-stylised-button" />'); } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Select */ new acf.Model({ actions: { 'new_field/type=select': 'newSelect', 'select2_init': 'init', }, filters: { 'select2_args': 'args', }, newSelect: function(field) { // inherit properties field.inherit(field.$input()); // remove "- -" characters from placeholder // acf already apply this to all select2 if (!field.get('ui') && field.get('allow_null')) { field.$input().find('option').each(function(i, option) { if (!option.value && option.text.startsWith('- ') && option.text.endsWith(' -')) { option.text = option.text.substring(2); // remove starting "- " option.text = option.text.substring(0, option.text.length - 2); // remove ending " -" } }); } // prepend / append if (field.has('acfePrepend') || field.has('acfeAppend')) { if (!field.$input().parent('.acf-input-wrap').length) { field.$input().wrapAll('<div class="acf-input-wrap"></div>'); if (field.get('ui')) { field.$('.acf-input-wrap:first').append(field.$('.select2')); } if (field.has('acfePrepend')) { field.$('.acf-input-wrap:first').before('<div class="acf-input-prepend">' + field.get('acfePrepend') + '</div>'); field.$input().addClass('acf-is-prepended'); } if (field.has('acfeAppend')) { field.$('.acf-input-wrap:first').before('<div class="acf-input-append">' + field.get('acfeAppend') + '</div>'); field.$input().addClass('acf-is-appended'); } } } }, init: function($select, options, data, field, instance) { // close dropdown on clear $select.on('select2:clear', function(e) { $(this).on('select2:opening.cancelOpen', function(e) { e.preventDefault(); $(this).off("select2:opening.cancelOpen"); }); }); // bail early if (!field) { return; } // add css class to dropdown with field name + key for developers <3 if ($select.data('select2')) { $select.data('select2').$dropdown .addClass('select2-dropdown-acf') .addClass('select2-dropdown-acf-field-' + field.get('name')) .addClass('select2-dropdown-acf-field-' + field.get('key')); } // search placeholder // only in single mode if (!field.get('multiple') && field.get('acfeSearchPlaceholder')) { $select.on('select2:open', function(e) { $('.select2-search.select2-search--dropdown > .select2-search__field').attr('placeholder', field.get('acfeSearchPlaceholder')); }); } }, args: function(options, $select, data, field, instance) { // bail early if (!field) { return options; } // custom tags disallowed if (!field.get('acfeAllowCustom')) { return options; } // allow custom tags options.tags = true; // create tag options.createTag = function(params) { var term = $.trim(params.term); if (term === '') { return null; } // vars var foundTerm; var ajaxResults = acf.isget(this, '_request', 'responseJSON', 'results'); // ajax results if (ajaxResults) { loop: for (var item of ajaxResults) { if (item.children) { for (var child of item.children) { if (typeof child.id === 'string' && child.id.toLowerCase() === term.toLowerCase()) { foundTerm = true; break loop; } } } } // normal results } else { for (var option of this.$element.find('option')) { if (option.value.toLowerCase() === term.toLowerCase()) { foundTerm = true; break; } } } // found term if (foundTerm) { return null; } // create tag return { id: term, text: term }; }; // insert tag options.insertTag = function(results, tag) { var found; for (var result of results) { if ($.trim(tag.text).toUpperCase() === $.trim(result.text).toUpperCase()) { found = true; break; } } if (!found) { results.unshift(tag); } }; return options; }, }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Slug */ var ACFE_Slug = acf.Field.extend({ type: 'acfe_slug', events: { 'input input': 'onInput', 'focusout input': 'onFocusOut', }, onInput: function(e, $el) { $el.val($el.val().toLowerCase() .replace(/\s+/g, '-') // Replace spaces with - .replace(/[^\w\-]+/g, '') // Remove all non-word chars .replace(/\-\-+/g, '-') // Replace multiple - with single - .replace(/\_\_+/g, '_') // Replace multiple _ with single _ .replace(/^-+/, '')); // Trim - from start of text }, onFocusOut: function(e, $el) { $el.val($el.val().toLowerCase() .replace(/-+$/, '') // Trim - from end of text .replace(/_+$/, '')); // Trim _ from end of text }, }); acf.registerFieldType(ACFE_Slug); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Tab */ new acf.Model({ actions: { 'prepare_field/type=tab': 'prepareField', }, prepareField: function(field) { if (!field.has('noPreference')) return; var $tabs = field.findTabs(); var tabs = acf.getInstances($tabs); var key = field.get('key'); if (tabs.length) { var preference = acf.getPreference('this.tabs'); if (!preference) return; $.each(tabs, function(i, group) { var groupIndex = group.get('index'); if (group.data.key !== key) return; preference[groupIndex] = 0; }); // update acf.setPreference('this.tabs', preference); } } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: Textarea */ var Textarea = acf.Field.extend({ type: 'textarea', events: { 'keydown textarea': 'onInput', }, onInput: function(e, $el) { //check for mode if (!this.has('acfeTextareaCode')) return; // check for tab input if (e.keyCode !== 9) return; e.preventDefault(); var input = this.$el.find('textarea')[0]; var s = input.selectionStart; this.$el.find('textarea').val(function(i, v) { return v.substring(0, s) + " " + v.substring(input.selectionEnd) }); input.selectionEnd = s + 4; }, }); acf.registerFieldType(Textarea); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: True/False */ var TrueFalse = acf.models.TrueFalseField; acf.models.TrueFalseField = TrueFalse.extend({ // add setValue method // this allows to use field.val('new_value') to assign a new value to the field setValue: function(val) { // clear value if (!val) { return this.clearValue(); } this.switchOn(); this.trigger('change'); // trigger change for conditional logic }, // add clearValue method // this allows to set the value to the first radio or if allow_null is enabled, to null clearValue: function() { this.switchOff(); this.trigger('change'); // trigger change for conditional logic } }); })(jQuery); (function($) { if (typeof acf === 'undefined' || typeof acfe === 'undefined') { return; } /** * Field: WYSIWYG Overwrite */ var Wysiwyg = acf.models.WysiwygField; acf.models.WysiwygField = Wysiwyg.extend({ initialize: function() { // initialize Editor if no delay and not already initialized if (!this.has('id') && !this.$control().hasClass('delay')) { this.initializeEditor(); } } }); /** * Field: WYSIWYG */ new acf.Model({ actions: { 'append_field/type=wysiwyg': 'appendField', 'show_field/type=wysiwyg': 'showField', 'ready_field/type=wysiwyg': 'showField', }, appendField: function(field) { // initialize editor when inside flexible content > repeater // on click repeater add row this.setTimeout(function() { this.showField(field); }, 1); }, showField: function(field) { if (field.has('acfeWysiwygAutoInit') && field.$el.is(':visible') && !field.has('id') && !acfe.isFilterEnabled('acfeFlexibleOpen')) { this.initializeEditor(field); } }, initializeEditor: function(field) { if (field.$control().hasClass('delay')) { field.$control().removeClass('delay'); field.$control().find('.acf-editor-toolbar').remove(); // initialize field.initializeEditor(); } }, }); })(jQuery);