(function($){ acf.field_group = acf.model.extend({ // vars $fields: null, $locations: null, $options: null, actions: { 'ready': 'init' }, events: { 'submit #post': 'submit', 'click a[href="#"]': 'preventDefault', 'click .submitdelete': 'trash', 'mouseenter .acf-field-list': 'sortable' }, /* * init * * This function will run on document ready and initialize the module * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param n/a * @return n/a */ init: function(){ // $el this.$fields = $('#acf-field-group-fields'); this.$locations = $('#acf-field-group-locations'); this.$options = $('#acf-field-group-options'); // disable validation acf.validation.active = 0; }, /* * sortable * * This function will add sortable to the feild group list * sortable is added on mouseover to speed up page load * * @type function * @date 28/10/2015 * @since 5.3.2 * * @param $post_id (int) * @return $post_id (int) */ sortable: function( e ){ // bail early if already sortable if( e.$el.hasClass('ui-sortable') ) { return; } // vars var self = this; // sortable e.$el.sortable({ handle: '.acf-sortable-handle', connectWith: '.acf-field-list', update: function(event, ui){ // vars var $el = ui.item; // render self.render_fields(); // actions acf.do_action('sortstop', $el); } }); }, /* * preventDefault * * This helper will preventDefault on all events for empty links * * @type function * @date 18/08/2015 * @since 5.2.3 * * @param $post_id (int) * @return $post_id (int) */ preventDefault: function( e ){ e.preventDefault(); }, /* * render_fields * * This function is triggered by a change in field order, and will update the field icon number * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param n/a * @return n/a */ render_fields: function(){ // reference var self = this; // update order numbers $('.acf-field-list').each(function(){ // vars var $fields = $(this).children('.acf-field-object'); // loop over fields $fields.each(function( i ){ // update meta self.update_field_meta( $(this), 'menu_order', i ); // update icon number $(this).children('.handle').find('.acf-icon').html( i+1 ); }); // show no fields message if( !$fields.exists() ){ $(this).children('.no-fields-message').show(); } else { $(this).children('.no-fields-message').hide(); } }); }, /* * get_field_meta * * This function will return an input value for a field * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @param name * @return (string) */ get_field_meta: function( $el, name ){ //console.log( 'get_field_meta(%o, %o)', $el, name ); // vars var $input = $el.find('> .meta > .input-' + name); // bail early if no input if( !$input.exists() ) { //console.log( '- aborted due to no input' ); return false; } // return return $input.val(); }, /* * update_field_meta * * This function will update an input value for a field * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @param name * @param value * @return n/a */ update_field_meta: function( $el, name, value ){ //console.log( 'update_field_meta(%o, %o, %o)', $el, name, value ); // vars var $input = $el.find('> .meta > .input-' + name); // create hidden input if doesn't exist if( !$input.exists() ) { // vars var html = $el.find('> .meta > .input-ID').outerHTML(); // replcae html = acf.str_replace('ID', name, html); // update $input $input = $(html); // reset value $input.val( value ); // append $el.children('.meta').append( $input ); //console.log( '- created new input' ); } // bail early if no change if( $input.val() == value ) { //console.log( '- aborted due to no change in input value' ); return; } // update value $input.val( value ); // bail early if updating save if( name == 'save' ) { //console.log( '- aborted due to name == save' ); return; } // meta has changed, update save this.save_field( $el, 'meta' ); }, /* * delete_field_meta * * This function will return an input value for a field * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @param name * @return (string) */ delete_field_meta: function( $el, name ){ //console.log( 'delete_field_meta(%o, %o, %o)', $el, name ); // vars var $input = $el.find('> .meta > .input-' + name); // bail early if not exists if( !$input.exists() ) { //console.log( '- aborted due to no input' ); return; } // remove $input.remove(); // meta has changed, update save this.save_field( $el, 'meta' ); }, /* * save_field * * This function will update the changed input for a given field making sure it is saved on submit * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @return n/a */ save_field: function( $el, type ){ //console.log('save_field(%o %o)', $el, type); // defaults type = type || 'settings'; // vars var value = this.get_field_meta( $el, 'save' ); // bail early if already 'settings' if( value == 'settings' ) { return; } // bail early if no change if( value == type ) { return; } // update meta this.update_field_meta( $el, 'save', type ); // action for 3rd party customization acf.do_action('save_field', $el, type); }, /* * submit * * This function is triggered when submitting the form and provides validation prior to posting the data * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param n/a * @return (boolean) */ submit: function( e ){ // reference var self = this; // vars var $title = $('#titlewrap #title'); // title empty if( !$title.val() ) { // prevent default e.preventDefault(); // unlock form acf.validation.toggle( e.$el, 'unlock' ); // alert alert( acf._e('title_is_required') ); // focus $title.focus(); } // close / delete fields $('.acf-field-object').each(function(){ // vars var save = self.get_field_meta( $(this), 'save'), ID = self.get_field_meta( $(this), 'ID'), open = $(this).hasClass('open'); // close if( open ) { self.close_field( $(this) ); } // remove unnecessary inputs if( save == 'settings' ) { // allow all settings to save (new field, changed field) } else if( save == 'meta' ) { $(this).children('.settings').find('[name^="acf_fields[' + ID + ']"]').remove(); } else { $(this).find('[name^="acf_fields[' + ID + ']"]').remove(); } }); }, /* * trash * * This function is triggered when moving the field group to trash * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param n/a * @return (boolean) */ trash: function( e ){ var result = confirm( acf._e('move_to_trash') ); if( !result ) { e.preventDefault(); } }, /* * render_field * * This function will update the field's info * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @return n/a */ render_field: function( $el ){ // vars var label = $el.find('.field-label:first').val(), name = $el.find('.field-name:first').val(), type = $el.find('.field-type:first option:selected').text(), required = $el.find('.field-required:first input:checked').val(); // update label $el.find('> .handle .li-field-label strong a').text( label ); // update required $el.find('> .handle .li-field-label .acf-required').remove(); if( required == '1' ) { $el.find('> .handle .li-field-label strong').append('*'); } // update name $el.find('> .handle .li-field-name').text( name ); // update type $el.find('> .handle .li-field-type').text( type ); }, /* * edit_field * * This function is triggered when clicking on a field. It will open / close a fields settings * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @return n/a */ edit_field: function( $field ){ // toggle if( $field.hasClass('open') ) { this.close_field( $field ); } else { this.open_field( $field ); } }, /* * open_field * * This function will open a fields settings * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @return n/a */ open_field: function( $el ){ // bail early if already open if( $el.hasClass('open') ) { return false; } // add class $el.addClass('open'); // action for 3rd party customization acf.do_action('open_field', $el); // animate toggle $el.children('.settings').animate({ 'height' : 'toggle' }, 250 ); }, /* * close_field * * This function will open a fields settings * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @return n/a */ close_field: function( $el ){ // bail early if already closed if( !$el.hasClass('open') ) { return false; } // remove class $el.removeClass('open'); // action for 3rd party customization acf.do_action('close_field', $el); // animate toggle $el.children('.settings').animate({ 'height' : 'toggle' }, 250 ); }, /* * wipe_field * * This function will prepare a new field by updating the input names * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @return n/a */ wipe_field: function( $el ){ // vars var id = $el.attr('data-id'), key = $el.attr('data-key'), new_id = acf.get_uniqid(), new_key = 'field_' + new_id; // update attr $el.attr('data-id', new_id); $el.attr('data-key', new_key); $el.attr('data-orig', key); // update hidden inputs this.update_field_meta( $el, 'ID', '' ); this.update_field_meta( $el, 'key', new_key ); // update attributes $el.find('[id*="' + id + '"]').each(function(){ $(this).attr('id', $(this).attr('id').replace(id, new_id) ); }); $el.find('[name*="' + id + '"]').each(function(){ $(this).attr('name', $(this).attr('name').replace(id, new_id) ); }); // update key $el.find('> .handle .pre-field-key').text( new_key ); // remove sortable classes $el.find('.ui-sortable').removeClass('ui-sortable'); // action for 3rd party customization acf.do_action('wipe_field', $el); }, /* * add_field * * This function will add a new field to a field list * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $fields * @return n/a */ add_field: function( $fields ){ // clone tr var $el = $( $('#tmpl-acf-field').html() ), $label = $el.find('.field-label:first'), $name = $el.find('.field-name:first'); // update names this.wipe_field( $el ); // append to table $fields.append( $el ); // clear name $label.val(''); $name.val(''); // focus after form has dropped down setTimeout(function(){ $label.focus(); }, 251); // update order numbers this.render_fields(); // trigger append acf.do_action('append', $el); // open up form this.edit_field( $el ); // action for 3rd party customization acf.do_action('add_field', $el); }, /* * duplicate_field * * This function will duplicate a field * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @return $el2 */ duplicate_field: function( $el ){ // allow acf to modify DOM acf.do_action('before_duplicate', $el); // vars var $el2 = $el.clone(), $label = $el2.find('.field-label:first'), $name = $el2.find('.field-name:first'); // remove JS functionality acf.do_action('remove', $el2); // update names this.wipe_field( $el2 ); // allow acf to modify DOM acf.do_action('after_duplicate', $el, $el2); // append to table $el.after( $el2 ); // trigger append acf.do_action('append', $el2); // focus after form has dropped down setTimeout(function(){ $label.focus(); }, 251); // update order numbers this.render_fields(); // open up form if( $el.hasClass('open') ) { this.close_field( $el ); } else { this.open_field( $el2 ); } // update new_field label / name $label.val( $label.val() + ' (' + acf._e('copy') + ')' ); $name.val( $name.val() + '_' + acf._e('copy') ); // save field this.save_field( $el2 ); // render field this.render_field( $el2 ); // action for 3rd party customization acf.do_action('duplicate_field', $el2); // return return $el2; }, /* * move_field * * This function will launch a popup to move a field to another field group * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $field * @return n/a */ move_field: function( $field ){ // reference var self = this; // AJAX data var ajax_data = acf.prepare_for_ajax({ action: 'acf/field_group/move_field', field_id: this.get_field_meta( $field, 'ID' ) }); // vars var warning = false; // validate if( !ajax_data.field_id ) { // Case: field not saved to DB warning = true; } else if( this.get_field_meta( $field, 'save' ) == 'settings' ) { // Case: field's settings have changed warning = true; } else { // Case: sub field's settings have changed $field.find('.acf-field-object').each(function(){ if( !self.get_field_meta( $(this), 'ID' ) ) { // Case: field not saved to DB warning = true; return false; } else if( self.get_field_meta( $(this), 'save' ) == 'settings' ) { // Case: field's settings have changed warning = true; } }); } // bail early if can't move if( warning ) { alert( acf._e('move_field_warning') ); return; } // open popup acf.open_popup({ title : acf._e('move_field'), loading : true, height : 145 }); // get HTML $.ajax({ url: acf.get('ajaxurl'), data: ajax_data, type: 'post', dataType: 'html', success: function(html){ self.move_field_confirm( $field, html ); } }); }, /* * move_field_confirm * * This function will move a field to another field group * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $post_id (int) * @return $post_id (int) */ move_field_confirm: function( $field, html ){ // reference var self = this; // update popup acf.update_popup({ content : html }); // AJAX data var ajax_data = acf.prepare_for_ajax({ 'action' : 'acf/field_group/move_field', 'field_id' : this.get_field_meta($field, 'ID'), 'field_group_id' : 0 }); // submit form $('#acf-move-field-form').on('submit', function(){ ajax_data.field_group_id = $(this).find('select').val(); // get HTML $.ajax({ url: acf.get('ajaxurl'), data: ajax_data, type: 'post', dataType: 'html', success: function(html){ acf.update_popup({ content : html }); // remove the field without actually deleting it self.remove_field( $field ); } }); return false; }); }, /* * delete_field * * This function will delete a field * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @param animation * @return n/a */ delete_field: function( $el, animation ){ // defaults animation = animation || true; // vars var id = this.get_field_meta($el, 'ID'); // add to remove list if( id ) { $('#input-delete-fields').val( $('#input-delete-fields').val() + '|' + id ); } // action for 3rd party customization acf.do_action('delete_field', $el); // bail early if no animation if( animation ) { this.remove_field( $el ); } }, /* * remove_field * * This function will visualy remove a field * * @type function * @date 24/10/2014 * @since 5.0.9 * * @param $el * @param animation * @return n/a */ remove_field: function( $el ){ // reference var self = this; // vars var $field_list = $el.closest('.acf-field-list'); // set layout $el.css({ height : $el.height(), width : $el.width(), position : 'absolute' }); // wrap field $el.wrap( '
' ); // fade $el $el.animate({ opacity : 0 }, 250); // close field var end_height = 0, $show = false; if( $field_list.children('.acf-field-object').length == 1 ) { $show = $field_list.children('.no-fields-message'); end_height = $show.outerHeight(); } $el.parent('.temp-field-wrap').animate({ height : end_height }, 250, function(){ // show another element if( $show ) { $show.show(); } // action for 3rd party customization acf.do_action('remove', $(this)); // remove $el $(this).remove(); // render fields becuase they have changed self.render_fields(); }); }, /* * change_field_type * * This function will update the field's settings based on the new field type * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $select * @return n/a */ change_field_type: function( $select ){ // vars var $tbody = $select.closest('tbody'), $el = $tbody.closest('.acf-field-object'), $parent = $el.parent().closest('.acf-field-object'), key = $el.attr('data-key'), old_type = $el.attr('data-type'), new_type = $select.val(); // update class $el.removeClass('acf-field-object-' + old_type.replace('_', '-')); $el.addClass('acf-field-object-' + new_type.replace('_', '-')); // update atts $el.attr('data-type', new_type); // abort XHR if this field is already loading AJAX data if( $el.data('xhr') ) { $el.data('xhr').abort(); } // get settings var $settings = $tbody.children('.acf-field[data-setting="' + old_type + '"]'), html = ''; // populate settings html $settings.each(function(){ html += $(this).outerHTML(); }); // remove settings $settings.remove(); // save field settings html acf.update( key + '_settings_' + old_type, html ); // render field this.render_field( $el ); // show field options if they already exist html = acf.get( key + '_settings_' + new_type ); if( html ) { // append settings $tbody.children('.acf-field[data-name="conditional_logic"]').before( html ); // remove field settings html acf.update( key + '_settings_' + new_type, '' ); // trigger event acf.do_action('change_field_type', $el); // return return; } // add loading var $tr = $('
'); // add $tr $tbody.children('.acf-field[data-name="conditional_logic"]').before( $tr ); var ajax_data = { action : 'acf/field_group/render_field_settings', nonce : acf.o.nonce, parent : acf.o.post_id, field_group : acf.o.post_id, prefix : $select.attr('name').replace('[type]', ''), type : new_type, }; // parent if( $parent.exists() ) { ajax_data.parent = this.get_field_meta( $parent, 'ID' ); } // ajax var xhr = $.ajax({ url: acf.o.ajaxurl, data: ajax_data, type: 'post', dataType: 'html', success: function( html ){ // bail early if no html if( !html ) { return; } // vars var $new_tr = $(html); // replace $tr.after( $new_tr ); // trigger event acf.do_action('append', $new_tr); acf.do_action('change_field_type', $el); }, complete : function(){ // this function will also be triggered by $el.data('xhr').abort(); $tr.remove(); } }); // update el data $el.data('xhr', xhr); }, /* * change_field_label * * This function is triggered when changing the field's label * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @return n/a */ change_field_label: function( $el ) { // vars var $label = $el.find('.field-label:first'), $name = $el.find('.field-name:first'), type = $el.attr('data-type'); // render name if( $name.val() == '' ) { // vars var s = $label.val(); // sanitize s = acf.str_sanitize(s); // update name $name.val( s ).trigger('change'); } // render field this.render_field( $el ); // action for 3rd party customization acf.do_action('change_field_label', $el); }, /* * change_field_name * * This function is triggered when changing the field's name * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $el * @return n/a */ change_field_name: function( $el ) { // vars var $name = $el.find('.field-name:first'); if( $name.val().substr(0, 6) === 'field_' ) { alert( acf._e('field_name_start') ); setTimeout(function(){ $name.focus(); }, 1); } } }); /* * field * * This model will handle field events * * @type function * @date 19/08/2015 * @since 5.2.3 * * @param $post_id (int) * @return $post_id (int) */ acf.field_group.field = acf.model.extend({ events: { 'click .edit-field': 'edit', 'click .duplicate-field': 'duplicate', 'click .move-field': 'move', 'click .delete-field': 'delete', 'click .add-field': 'add', 'change .field-type': 'change_type', 'blur .field-label': 'change_label', 'blur .field-name': 'change_name', 'keyup .field-label': 'render', 'keyup .field-name': 'render', 'change .field-required input': 'render', 'change .acf-field-object input': 'save', 'change .acf-field-object textarea': 'save', 'change .acf-field-object select': 'save' }, event: function( e ){ // append $field e.$field = e.$el.closest('.acf-field-object'); // return return e; }, /* * events * * description * * @type function * @date 19/08/2015 * @since 5.2.3 * * @param $post_id (int) * @return $post_id (int) */ edit: function( e ){ acf.field_group.edit_field( e.$field ); }, duplicate: function( e ){ acf.field_group.duplicate_field( e.$field ); }, move: function( e ){ acf.field_group.move_field( e.$field ); }, delete: function( e ){ acf.field_group.delete_field( e.$field ); }, add: function( e ){ var $list = e.$el.closest('.acf-field-list-wrap').children('.acf-field-list'); acf.field_group.add_field( $list ); }, change_type: function( e ){ acf.field_group.change_field_type( e.$el ); }, change_label: function( e ){ acf.field_group.change_field_label( e.$field ); }, change_name: function( e ){ acf.field_group.change_field_name( e.$field ); }, render: function( e ){ acf.field_group.render_field( e.$field ); }, save: function( e ){ acf.field_group.save_field( e.$field ); } }); /* * conditions * * This model will handle conditional logic events * * @type function * @date 19/08/2015 * @since 5.2.3 * * @param $post_id (int) * @return $post_id (int) */ acf.field_group.conditional_logic = acf.model.extend({ actions: { 'open_field': 'render_field', 'change_field_label': 'render_fields', 'change_field_type': 'render_fields' }, events: { 'click .add-conditional-rule': 'add_rule', 'click .add-conditional-group': 'add_group', 'click .remove-conditional-rule': 'remove_rule', 'change .conditional-toggle input': 'change_toggle', 'change .conditional-rule-param': 'change_param' }, /* * render_fields * * description * * @type function * @date 19/08/2015 * @since 5.2.3 * * @param $post_id (int) * @return $post_id (int) */ render_fields: function(){ var self = this; $('.acf-field-object.open').each(function(){ self.render_field( $(this) ); }); }, /* * render_field * * This function will render the conditional logic fields for a given field * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $field * @return n/a */ render_field: function( $field ){ // reference var self = this; // vars var key = $field.attr('data-key'), $ancestors = $field.parents('.acf-field-list'), $tr = $field.find('.acf-field[data-name="conditional_logic"]:last'); // choices var choices = []; // loop over ancestors $.each( $ancestors, function( i ){ // vars var group = (i == 0) ? acf._e('sibling_fields') : acf._e('parent_fields'); // loop over fields $(this).children('.acf-field-object').each(function(){ // vars var $this_field = $(this), this_key = $this_field.attr('data-key'), this_type = $this_field.attr('data-type'), this_label = $this_field.find('.field-label:first').val(); // validate if( $.inArray(this_type, ['select', 'checkbox', 'true_false', 'radio']) === -1 ) { return; } else if( this_key == key ) { return; } // add this field to available triggers choices.push({ value: this_key, label: this_label, group: group }); }); }); // empty? if( !choices.length ) { choices.push({ value: '', label: acf._e('no_fields') }); } // create select fields $tr.find('.rule').each(function(){ self.render_rule( $(this), choices ); }); }, /* * populate_triggers * * description * * @type function * @date 22/08/2015 * @since 5.2.3 * * @param $post_id (int) * @return $post_id (int) */ render_rule: function( $tr, triggers ) { // vars var $trigger = $tr.find('.conditional-rule-param'), $value = $tr.find('.conditional-rule-value'); // populate triggers if( triggers ) { acf.render_select( $trigger, triggers ); } // vars var $field = $('.acf-field-object[data-key="' + $trigger.val() + '"]'), field_type = $field.attr('data-type'), choices = []; // populate choices if( field_type == "true_false" ) { choices.push({ 'value': 1, 'label': acf._e('checked') }); // select } else if( field_type == "select" || field_type == "checkbox" || field_type == "radio" ) { // vars var lines = $field.find('.acf-field[data-name="choices"] textarea').val().split("\n"); $.each(lines, function(i, line){ // explode line = line.split(':'); // default label to value line[1] = line[1] || line[0]; // append choices.push({ 'value': $.trim( line[0] ), 'label': $.trim( line[1] ) }); }); // allow null var $allow_null = $field.find('.acf-field[data-name="allow_null"]'); if( $allow_null.exists() ) { if( $allow_null.find('input:checked').val() == '1' ) { choices.unshift({ 'value': '', 'label': acf._e('null') }); } } } // update select acf.render_select( $value, choices ); }, /* * change_toggle * * This function is triggered by changing the 'Conditional Logic' radio button * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $input * @return n/a */ change_toggle: function( e ){ // vars var $input = e.$el, val = $input.val(), $td = $input.closest('.acf-input'); if( val == "1" ) { $td.find('.rule-groups').show(); $td.find('.rule-groups').find('[name]').removeAttr('disabled'); } else { $td.find('.rule-groups').hide(); $td.find('.rule-groups').find('[name]').attr('disabled', 'disabled'); } }, /* * change_trigger * * This function is triggered by changing a 'Conditional Logic' trigger * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $select * @return n/a */ change_param: function( e ){ // vars var $rule = e.$el.closest('.rule'); // render this.render_rule( $rule ); }, /* * add_rule * * This function will add a new rule below the specified $tr * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $tr * @return n/a */ add_rule: function( e ){ // vars var $tr = e.$el.closest('tr'); // duplicate $tr2 = acf.duplicate( $tr ); // save field $tr2.find('select:first').trigger('change'); }, /* * remove_rule * * This function will remove the $tr and potentially the group * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $tr * @return n/a */ remove_rule: function( e ){ // vars var $tr = e.$el.closest('tr'); // save field $tr.find('select:first').trigger('change'); if( $tr.siblings('tr').length == 0 ) { // remove group $tr.closest('.rule-group').remove(); } // remove tr $tr.remove(); }, /* * add_group * * This function will add a new rule group to the given $groups container * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $tr * @return n/a */ add_group: function( e ){ // vars var $groups = e.$el.closest('.rule-groups'), $group = $groups.find('.rule-group:last'); // duplicate $group2 = acf.duplicate( $group ); // update h4 $group2.find('h4').text( acf._e('or') ); // remove all tr's except the first one $group2.find('tr:not(:first)').remove(); // save field $group2.find('select:first').trigger('change'); } }); /* * locations * * This model will handle location rule events * * @type function * @date 19/08/2015 * @since 5.2.3 * * @param $post_id (int) * @return $post_id (int) */ acf.field_group.locations = acf.model.extend({ events: { 'click .add-location-rule': 'add_rule', 'click .add-location-group': 'add_group', 'click .remove-location-rule': 'remove_rule', 'change .location-rule-param': 'change_rule' }, /* * add_rule * * This function will add a new rule below the specified $tr * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $tr * @return n/a */ add_rule: function( e ){ // vars var $tr = e.$el.closest('tr'); // duplicate $tr2 = acf.duplicate( $tr ); }, /* * remove_rule * * This function will remove the $tr and potentially the group * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $tr * @return n/a */ remove_rule: function( e ){ // vars var $tr = e.$el.closest('tr'); // save field $tr.find('select:first').trigger('change'); if( $tr.siblings('tr').length == 0 ) { // remove group $tr.closest('.rule-group').remove(); } // remove tr $tr.remove(); }, /* * add_group * * This function will add a new rule group to the given $groups container * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $tr * @return n/a */ add_group: function( e ){ // vars var $groups = e.$el.closest('.rule-groups'), $group = $groups.find('.rule-group:last'); // duplicate $group2 = acf.duplicate( $group ); // update h4 $group2.find('h4').text( acf._e('or') ); // remove all tr's except the first one $group2.find('tr:not(:first)').remove(); }, /* * change_rule * * This function is triggered when changing a location rule trigger * * @type function * @date 8/04/2014 * @since 5.0.0 * * @param $select * @return n/a */ change_rule: function( e ){ // vars var $select = e.$el, $tr = $select.closest('tr'), rule_id = $tr.attr('data-id'), $group = $tr.closest('.rule-group'), group_id = $group.attr('data-id'); // add loading gif var $div = $('
'); $tr.find('td.value').html( $div ); // load location html $.ajax({ url: acf.get('ajaxurl'), data: acf.prepare_for_ajax({ 'action': 'acf/field_group/render_location_value', 'rule_id': rule_id, 'group_id': group_id, 'param': $select.val(), 'value': '' }), type: 'post', dataType: 'html', success: function(html){ $div.replaceWith(html); } }); } }); /* * Append * * description * * @type function * @date 12/02/2015 * @since 5.1.5 * * @param $post_id (int) * @return $post_id (int) */ acf.add_action('open_field change_field_type', function( $el ){ // clear name $el.find('.acf-field[data-append]').each(function(){ // vars var append = $(this).data('append'); // find sibling $sibling = $(this).siblings('[data-name="' + append + '"]'); // bail early if no $sibling if( !$sibling.exists() ) { return; } // vars var $wrap = $sibling.children('.acf-input'), $ul = $wrap.children('.acf-hl'); if( !$ul.exists() ) { $wrap.wrapInner(''); $ul = $wrap.children('.acf-hl'); } // create $li var $li = $('
  • ').append( $(this).children('.acf-input').children() ); // append $li $ul.append( $li ); // update cols $ul.attr('data-cols', $ul.children().length ); // remove $(this).remove(); }); }); /* * Select * * This field type requires some extra logic for its settings * * @type function * @date 24/10/13 * @since 5.0.0 * * @param n/a * @return n/a */ var acf_settings_select = acf.model.extend({ actions: { 'open_field': 'render', 'change_field_type': 'render' }, events: { 'change .acf-field[data-name="ui"] input': 'render' }, event: function( e ){ // override return e.$el.closest('.acf-field-object'); }, render: function( $el ){ // bail early if not correct field type if( $el.attr('data-type') != 'select' ) { return; } // vars var val = $el.find('.acf-field[data-name="ui"] input:checked').val(); // show / hide if( val == '1' ) { $el.find('.acf-field[data-name="ajax"]').show(); } else { $el.find('.acf-field[data-name="ajax"]').hide(); } } }); /* * Radio * * This field type requires some extra logic for its settings * * @type function * @date 24/10/13 * @since 5.0.0 * * @param n/a * @return n/a */ var acf_settings_radio = acf.model.extend({ actions: { 'open_field': 'render', 'change_field_type': 'render' }, events: { 'change .acf-field[data-name="other_choice"] input': 'render' }, event: function( e ){ // override return e.$el.closest('.acf-field-object'); }, render: function( $el ){ // bail early if not correct field type if( $el.attr('data-type') != 'radio' ) { return; } // vars var val = $el.find('.acf-field[data-name="other_choice"] input:checked').val(); if( val == '1' ) { $el.find('.acf-field[data-name="save_other_choice"]').show(); } else { $el.find('.acf-field[data-name="save_other_choice"]').hide(); $el.find('.acf-field[data-name="save_other_choice"] input').prop('checked', false); } } }); /* * Date Picker * * This field type requires some extra logic for its settings * * @type function * @date 24/10/13 * @since 5.0.0 * * @param n/a * @return n/a */ var acf_settings_date_picker = acf.model.extend({ actions: { 'open_field': 'render', 'change_field_type': 'render' }, events: { 'change .acf-field[data-name="display_format"] input': 'render', 'change .acf-field[data-name="return_format"] input': 'render' }, event: function( e ){ // override return e.$el.closest('.acf-field-object'); }, render: function( $el ){ // bail early if not correct field type if( $el.attr('data-type') != 'date_picker' ) { return; } $.each(['display_format', 'return_format'], function(k,v){ // vars var $radio = $el.find('.acf-field[data-name="' + v + '"] input[type="radio"]:checked'), $other = $el.find('.acf-field[data-name="' + v + '"] input[type="text"]'); // display val if( $radio.val() != 'other' ) { $other.val( $radio.val() ); } }); } }); /* * Date Time Picker * * This field type requires some extra logic for its settings * * @type function * @date 24/10/13 * @since 5.0.0 * * @param n/a * @return n/a */ var acf_settings_date_time_picker = acf.model.extend({ actions: { 'open_field': 'render', 'change_field_type': 'render' }, events: { 'change .acf-field-object-date-time-picker input[type="radio"]': 'render', }, event: function( e ){ // override return e.$el.closest('.acf-field-object'); }, render: function( $el ){ // bail early if not correct field type if( $el.attr('data-type') != 'date_time_picker' ) return; // loop $el.find('.acf-radio-list[data-other_choice="1"]').each(function(){ // vars var $ul = $(this), $radio = $ul.find('input[type="radio"]:checked'), $other = $ul.find('input[type="text"]'); // display val if( $radio.val() != 'other' ) { $other.val( $radio.val() ); } }); } }); /* * Time Picker * * This field type requires some extra logic for its settings * * @type function * @date 24/10/13 * @since 5.0.0 * * @param n/a * @return n/a */ var acf_settings_time_picker = acf.model.extend({ actions: { 'open_field': 'render', 'change_field_type': 'render' }, events: { 'change .acf-field-object-time-picker input[type="radio"]': 'render', }, event: function( e ){ // override return e.$el.closest('.acf-field-object'); }, render: function( $el ){ // bail early if not correct field type if( $el.attr('data-type') != 'time_picker' ) return; // loop $el.find('.acf-radio-list[data-other_choice="1"]').each(function(){ // vars var $ul = $(this), $radio = $ul.find('input[type="radio"]:checked'), $other = $ul.find('input[type="text"]'); // display val if( $radio.val() != 'other' ) { $other.val( $radio.val() ); } }); } }); /* * tab * * description * * @type function * @date 12/02/2015 * @since 5.1.5 * * @param $post_id (int) * @return $post_id (int) */ var acf_settings_tab = acf.model.extend({ actions: { 'open_field': 'render', 'change_field_type': 'render' }, render: function( $el ){ // bail early if not correct field type if( $el.attr('data-type') != 'tab' ) return; // vars var id = $el.data('id'); // clear name $('#acf_fields-' + id + '-name').val('').trigger('change'); // clear required $('#acf_fields-' + id + '-required-0').trigger('click'); } }); /* * message * * description * * @type function * @date 12/02/2015 * @since 5.1.5 * * @param $post_id (int) * @return $post_id (int) */ var acf_settings_message = acf.model.extend({ actions: { 'open_field': 'render', 'change_field_type': 'render' }, render: function( $el ){ // bail early if not correct field type if( $el.attr('data-type') != 'message' ) return; // vars var id = $el.data('id'); // clear name $('#acf_fields-' + id + '-name').val('').trigger('change'); // clear required $('#acf_fields-' + id + '-required-0').trigger('click'); } }); /* * clone * * This field type requires some extra logic for its settings * * @type function * @date 24/10/13 * @since 5.0.0 * * @param n/a * @return n/a */ var acf_settings_clone = acf.model.extend({ actions: { 'open_field': 'render', 'change_field_type': 'render' }, filters: { 'select2_args': 'select2_args', 'select2_ajax_data': 'select2_ajax_data' }, events: { 'change .acf-field-object-clone .setting-display': 'render_display', 'change .acf-field-object-clone .setting-prefix-label input': 'render_prefix_label', 'change .acf-field-object-clone .setting-prefix-name input': 'render_prefix_name', }, event: function( e ){ // override return e.$el.closest('.acf-field-object'); }, render: function( $el ){ // bail early if not correct field type if( $el.attr('data-type') != 'clone' ) return; // render this.render_display( $el ); this.render_prefix_label( $el ); this.render_prefix_name( $el ); }, render_display: function( $el ){ // vars var $layout = $el.find('.acf-field[data-name="layout"]'), $display = $el.find('.acf-field[data-name="display"] select'), $conditional = $el.find('.acf-field[data-name="conditional_logic"]'), $wrapper = $el.find('.acf-field[data-name="wrapper"]'); // hide conditional logic if( $display.val() == 'seamless' ) { $conditional.hide(); $wrapper.hide(); $layout.hide(); } else { $conditional.show(); $wrapper.show(); $layout.show(); } }, render_prefix_label: function( $el ){ // vars var $prefix_label = $el.find('.setting-prefix-label input:checked'), $field_label = $el.find('.field-label'), $code = $el.find('.prefix-label-code-1'); // html var html = '%field_label%'; if( $prefix_label.val() === '1' ) { html = $field_label.val() + ' ' + html; } // update code $code.html( html ); }, render_prefix_name: function( $el ){ // vars var $prefix_name = $el.find('.setting-prefix-name input:checked'), $field_name = $el.find('.field-name'), $code = $el.find('.prefix-name-code-1'); // html var label = '%field_name%'; if( $prefix_name.val() === '1' ) { label = $field_name.val() + '_' + label; } // html $code.html( label ); }, select2_args: function( select2_args, $select, args ){ // bail early if not clone if( args.ajax_action !== 'acf/fields/clone/query' ) return select2_args; // remain open on select select2_args.closeOnSelect = false; // return return select2_args; }, select2_ajax_data: function( data, args, params ){ // bail early if not clone if( args.ajax_action !== 'acf/fields/clone/query' ) return select2_args; // find current fields var fields = {}; // loop $('.acf-field-object').each(function(){ // vars var $el = $(this), key = $el.data('key'), type = $el.data('type'), label = $el.find('.field-label:first').val(), $ancestors = $el.parents('.acf-field-object'); // label fields[ key ] = { 'key': key, 'type': type, 'label': label, 'ancestors': $ancestors.length }; }); // append fields data.fields = fields; // append title data.title = $('#title').val(); // return return data; } }); /* * screen * * description * * @type function * @date 23/07/2015 * @since 5.2.3 * * @param $post_id (int) * @return $post_id (int) */ acf.field_group.screen = acf.model.extend({ actions: { 'ready': 'ready' }, events: { 'click #acf-field-key-hide': 'toggle' }, ready: function(){ // vars var $el = $('#adv-settings'), $append = $el.find('#acf-append-show-on-screen'); // append $el.find('.metabox-prefs').append( $append.html() ); // move br $el.find('.metabox-prefs br').remove(); // remove $append.remove(); // render this.render(); }, toggle: function( e ){ // vars var val = e.$el.prop('checked') ? 1 : 0; // update user setting acf.update_user_setting('show_field_keys', val); // render $fields this.render(); }, render: function(){ // vars var options = acf.serialize_form( $('#adv-settings') ); // convert types options.show_field_keys = parseInt(options.show_field_keys); // toggle class var $fields = acf.field_group.$fields; // show field keys if( options.show_field_keys ) { $fields.addClass('show-field-keys'); } else { $fields.removeClass('show-field-keys'); } }, }); })(jQuery); // @codekit-prepend "../js/field-group.js";