pluto3/inc/acf/advanced-custom-fields-pro/assets/js/acf-field-group.js
2017-09-19 16:23:41 +08:00

2816 lines
47 KiB
JavaScript

(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('<span class="acf-required">*</span>');
}
// 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( '<div class="temp-field-wrap" style="height:' + $el.height() + 'px"></div>' );
// 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 = $('<tr class="acf-field"><td class="acf-label"></td><td class="acf-input"><div class="acf-loading"></div></td></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 = $('<div class="acf-loading"></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 class="acf-hl"><li></li></ul>');
$ul = $wrap.children('.acf-hl');
}
// create $li
var $li = $('<li></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";