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

2406 lines
41 KiB
JavaScript

(function($){
// comon
acf.pro = acf.model.extend({
actions: {
'refresh': 'refresh',
},
filters: {
'get_fields' : 'get_fields',
},
get_fields: function( $fields ){
// remove clone fields
$fields = $fields.not('.acf-clone .acf-field');
// return
return $fields;
},
/*
* refresh
*
* This function will run when acf detects a refresh is needed on the UI
* Most commonly after ready / conditional logic change
*
* @type function
* @date 10/11/2014
* @since 5.0.9
*
* @param n/a
* @return n/a
*/
refresh: function( $el ){
// reference
var self = this;
// defaults
$el = $el || false;
// if is row
if( $el && $el.is('tr') ) {
self.render_table( $el.closest('table') );
return;
}
// find and rener all tables
$('.acf-table', $el).each(function(){
self.render_table( $(this) );
});
},
render_table: function( $table ){
// vars
var $ths = $table.find('> thead th.acf-th'),
colspan = 1,
available_width = 100;
// bail early if no $ths
if( !$ths.exists() ) {
return;
}
// render th/td visibility
$ths.each(function(){
// vars
var $th = $(this),
key = $th.attr('data-key'),
$td = $table.find('td[data-key="' + key + '"]');
// clear class
$td.removeClass('appear-empty');
$th.removeClass('hidden-by-conditional-logic');
// no td
if( !$td.exists() ) {
// do nothing
// if all td are hidden
} else if( $td.not('.hidden-by-conditional-logic').length == 0 ) {
$th.addClass('hidden-by-conditional-logic');
// if 1 or more td are visible
} else {
$td.filter('.hidden-by-conditional-logic').addClass('appear-empty');
}
});
// clear widths
$ths.css('width', 'auto');
// update $ths
$ths = $ths.not('.hidden-by-conditional-logic');
// set colspan
colspan = $ths.length;
// set custom widths first
$ths.filter('[data-width]').each(function(){
// vars
var width = parseInt( $(this).attr('data-width') );
// remove from available
available_width -= width;
// set width
$(this).css('width', width + '%');
});
// update $ths
$ths = $ths.not('[data-width]');
// set custom widths first
$ths.each(function(){
// cal width
var width = available_width / $ths.length;
// set width
$(this).css('width', width + '%');
});
// update colspan
$table.find('.acf-row .acf-field.-collapsed-target').removeAttr('colspan');
$table.find('.acf-row.-collapsed .acf-field.-collapsed-target').attr('colspan', colspan);
},
});
})(jQuery);
(function($){
acf.fields.repeater = acf.field.extend({
type: 'repeater',
$el: null,
$input: null,
$table: null,
$tbody: null,
$clone: null,
actions: {
'ready': 'initialize',
'append': 'initialize',
'show': 'show'
},
events: {
'click a[data-event="add-row"]': '_add',
'click a[data-event="remove-row"]': '_remove',
'click a[data-event="collapse-row"]': '_collapse',
'mouseenter td.order': '_mouseenter'
},
focus: function(){
// vars
this.$el = this.$field.find('.acf-repeater:first');
this.$input = this.$field.find('input:first');
this.$table = this.$field.find('table:first');
this.$tbody = this.$table.children('tbody');
this.$clone = this.$tbody.children('tr.acf-clone');
// get options
this.o = acf.get_data( this.$el );
// min / max
this.o.min = this.o.min || 0;
this.o.max = this.o.max || 0;
},
initialize: function(){
// disable clone inputs
this.$clone.find('input, textarea, select').attr('disabled', 'disabled');
// render
this.render();
},
show: function(){
this.$tbody.find('.acf-field:visible').each(function(){
acf.do_action('show_field', $(this));
});
},
count: function(){
return this.$tbody.children().length - 1;
},
render: function(){
// update order numbers
this.$tbody.children().each(function(i){
$(this).find('> td.order > span').html( i+1 );
});
// empty?
if( this.count() == 0 ) {
this.$el.addClass('-empty');
} else {
this.$el.removeClass('-empty');
}
// row limit reached
if( this.o.max > 0 && this.count() >= this.o.max ) {
this.$el.find('> .acf-actions .button').addClass('disabled');
} else {
this.$el.find('> .acf-actions .button').removeClass('disabled');
}
},
add: function( $tr ){
// defaults
$tr = $tr || this.$clone;
// validate
if( this.o.max > 0 && this.count() >= this.o.max ) {
alert( acf._e('repeater','max').replace('{max}', this.o.max) );
return false;
}
// reference
var $field = this.$field;
// duplicate
$el = acf.duplicate( this.$clone );
// remove clone class
$el.removeClass('acf-clone');
// enable inputs (ignore inputs disabled for life)
$el.find('input, textarea, select').not('.acf-disabled').removeAttr('disabled');
// move row
$tr.before( $el );
// focus (may have added sub repeater)
this.doFocus($field);
// update order
this.render();
// validation
acf.validation.remove_error( this.$field );
// sync collapsed order
this.sync();
// return
return $el;
},
remove: function( $tr ){
// reference
var self = this;
// validate
if( this.count() <= this.o.min ) {
alert( acf._e('repeater','min').replace('{min}', this.o.min) );
return false;
}
// action for 3rd party customization
acf.do_action('remove', $tr);
// animate out tr
acf.remove_tr( $tr, function(){
// trigger change to allow attachment save
self.$input.trigger('change');
// render
self.render();
// sync collapsed order
self.sync();
// refersh field (hide/show columns)
acf.do_action('refresh', self.$field);
});
},
sync: function(){
// vars
var name = 'collapsed_' + this.$field.data('key'),
collapsed = [];
// populate collapsed value
this.$tbody.children().each(function( i ){
if( $(this).hasClass('-collapsed') ) {
collapsed.push( i );
}
});
// update
acf.update_user_setting( name, collapsed.join(',') );
},
/*
* events
*
* these functions are fired for this fields events
*
* @type function
* @date 17/09/2015
* @since 5.2.3
*
* @param e
* @return n/a
*/
_mouseenter: function( e ){ //console.log('_mouseenter');
// bail early if already sortable
if( this.$tbody.hasClass('ui-sortable') ) return;
// bail early if max 1 row
if( this.o.max == 1 ) return;
// reference
var self = this;
// add sortable
this.$tbody.sortable({
items: '> tr',
handle: '> td.order',
forceHelperSize: true,
forcePlaceholderSize: true,
scroll: true,
start: function(event, ui) {
acf.do_action('sortstart', ui.item, ui.placeholder);
},
stop: function(event, ui) {
// render
self.render();
acf.do_action('sortstop', ui.item, ui.placeholder);
},
update: function(event, ui) {
// trigger change
self.$input.trigger('change');
}
});
},
_add: function( e ){ //console.log('_add');
// vars
$row = false;
// row add
if( e.$el.hasClass('acf-icon') ) {
$row = e.$el.closest('.acf-row');
}
// add
this.add( $row );
},
_remove: function( e ){ //console.log('_remove');
this.remove( e.$el.closest('.acf-row') );
},
_collapse: function( e ){ //console.log('_collapse');
// vars
var $tr = e.$el.closest('.acf-row');
// reference
var $field = this.$field;
// open row
if( $tr.hasClass('-collapsed') ) {
$tr.removeClass('-collapsed');
acf.do_action('show', $tr, 'collapse');
} else {
$tr.addClass('-collapsed');
acf.do_action('hide', $tr, 'collapse');
}
// sync
this.set('$field', $field).sync();
// refersh field (hide/show columns)
acf.do_action('refresh', this.$field);
}
});
})(jQuery);
(function($){
acf.fields.flexible_content = acf.field.extend({
type: 'flexible_content',
$el: null,
$input: null,
$values: null,
$clones: null,
actions: {
'ready': 'initialize',
'append': 'initialize',
'show': 'show'
},
events: {
'click [data-event="add-layout"]': '_open',
'click [data-event="remove-layout"]': '_remove',
'click [data-event="collapse-layout"]': '_collapse',
'click .acf-fc-layout-handle': '_collapse',
'click .acf-fc-popup a': '_add',
'blur .acf-fc-popup .focus': '_close',
'mouseenter .acf-fc-layout-handle': '_mouseenter'
},
focus: function(){
// vars
this.$el = this.$field.find('.acf-flexible-content:first');
this.$input = this.$el.siblings('input');
this.$values = this.$el.children('.values');
this.$clones = this.$el.children('.clones');
// get options
this.o = acf.get_data( this.$el );
// min / max
this.o.min = this.o.min || 0;
this.o.max = this.o.max || 0;
},
count: function(){
return this.$values.children('.layout').length;
},
initialize: function(){
// disable clone inputs
this.$clones.find('input, textarea, select').attr('disabled', 'disabled');
// render
this.render();
},
show: function(){
this.$values.find('.acf-field:visible').each(function(){
acf.do_action('show_field', $(this));
});
},
render: function(){
// vars
var self = this;
// update order numbers
this.$values.children('.layout').each(function( i ){
$(this).find('> .acf-fc-layout-handle .acf-fc-layout-order').html( i+1 );
});
// empty?
if( this.count() == 0 ) {
this.$el.addClass('empty');
} else {
this.$el.removeClass('empty');
}
// row limit reached
if( this.o.max > 0 && this.count() >= this.o.max ) {
this.$el.find('> .acf-actions .button').addClass('disabled');
} else {
this.$el.find('> .acf-actions .button').removeClass('disabled');
}
},
render_layout_title: function( $layout ){
// vars
var ajax_data = acf.serialize( $layout );
// append
ajax_data = acf.parse_args( ajax_data, {
action: 'acf/fields/flexible_content/layout_title',
field_key: this.$field.data('key'),
i: $layout.index(),
layout: $layout.data('layout'),
});
// prepare
ajax_data = acf.prepare_for_ajax(ajax_data);
// ajax get title HTML
$.ajax({
url : acf.get('ajaxurl'),
dataType : 'html',
type : 'post',
data : ajax_data,
success: function( html ){
// bail early if no html
if( !html ) return;
// update html
$layout.find('> .acf-fc-layout-handle').html( html );
}
});
},
validate_add: function( layout ){
// vadiate max
if( this.o.max > 0 && this.count() >= this.o.max ) {
// vars
var identifier = ( this.o.max == 1 ) ? 'layout' : 'layouts',
s = acf._e('flexible_content', 'max');
// translate
s = s.replace('{max}', this.o.max);
s = s.replace('{identifier}', acf._e('flexible_content', identifier));
// alert
alert( s );
// return
return false;
}
// vadiate max layout
var $popup = $( this.$el.children('.tmpl-popup').html() ),
$a = $popup.find('[data-layout="' + layout + '"]'),
layout_max = parseInt( $a.attr('data-max') ),
layout_count = this.$values.children('.layout[data-layout="' + layout + '"]').length;
if( layout_max > 0 && layout_count >= layout_max ) {
// vars
var identifier = ( layout_max == 1 ) ? 'layout' : 'layouts',
s = acf._e('flexible_content', 'max_layout');
// translate
s = s.replace('{max}', layout_count);
s = s.replace('{label}', '"' + $a.text() + '"');
s = s.replace('{identifier}', acf._e('flexible_content', identifier));
// alert
alert( s );
// return
return false;
}
// return
return true;
},
validate_remove: function( layout ){
// vadiate min
if( this.o.min > 0 && this.count() <= this.o.min ) {
// vars
var identifier = ( this.o.min == 1 ) ? 'layout' : 'layouts',
s = acf._e('flexible_content', 'min') + ', ' + acf._e('flexible_content', 'remove');
// translate
s = s.replace('{min}', this.o.min);
s = s.replace('{identifier}', acf._e('flexible_content', identifier));
s = s.replace('{layout}', acf._e('flexible_content', 'layout'));
// return
return confirm( s );
}
// vadiate max layout
var $popup = $( this.$el.children('.tmpl-popup').html() ),
$a = $popup.find('[data-layout="' + layout + '"]'),
layout_min = parseInt( $a.attr('data-min') ),
layout_count = this.$values.children('.layout[data-layout="' + layout + '"]').length;
if( layout_min > 0 && layout_count <= layout_min ) {
// vars
var identifier = ( layout_min == 1 ) ? 'layout' : 'layouts',
s = acf._e('flexible_content', 'min_layout') + ', ' + acf._e('flexible_content', 'remove');
// translate
s = s.replace('{min}', layout_count);
s = s.replace('{label}', '"' + $a.text() + '"');
s = s.replace('{identifier}', acf._e('flexible_content', identifier));
s = s.replace('{layout}', acf._e('flexible_content', 'layout'));
// return
return confirm( s );
}
// return
return true;
},
sync: function(){
// vars
var name = 'collapsed_' + this.$field.data('key'),
collapsed = [];
// populate collapsed value
this.$values.children('.layout').each(function( i ){
if( $(this).hasClass('-collapsed') ) {
collapsed.push( i );
}
});
// update
acf.update_user_setting( name, collapsed.join(',') );
},
add: function( layout, $before ){
// defaults
$before = $before || false;
// bail early if validation fails
if( !this.validate_add(layout) ) {
return false;
}
// reference
var $field = this.$field;
// vars
var $clone = this.$clones.children('.layout[data-layout="' + layout + '"]');
// duplicate
$el = acf.duplicate( $clone );
// enable inputs (ignore inputs disabled for life)
$el.find('input, textarea, select').not('.acf-disabled').removeAttr('disabled');
// hide no values message
this.$el.children('.no-value-message').hide();
// add row
if( $before ) {
$before.before( $el );
} else {
this.$values.append( $el );
}
// focus (may have added sub flexible content)
this.doFocus($field);
// update order
this.render();
// validation
acf.validation.remove_error( this.$field );
// sync collapsed order
this.sync();
},
/*
* events
*
* these functions are fired for this fields events
*
* @type function
* @date 17/09/2015
* @since 5.2.3
*
* @param e
* @return n/a
*/
_mouseenter: function( e ){ //console.log('_mouseenter');
// bail early if already sortable
if( this.$values.hasClass('ui-sortable') ) return;
// bail early if max 1 row
if( this.o.max == 1 ) return;
// reference
var self = this;
// sortable
this.$values.sortable({
items: '> .layout',
handle: '> .acf-fc-layout-handle',
forceHelperSize: true,
forcePlaceholderSize: true,
scroll: true,
start: function(event, ui) {
acf.do_action('sortstart', ui.item, ui.placeholder);
},
stop: function(event, ui) {
// render
self.render();
acf.do_action('sortstop', ui.item, ui.placeholder);
},
update: function(event, ui) {
// trigger change
self.$input.trigger('change');
}
});
},
_open: function( e ){ //console.log('_open');
// reference
var $values = this.$values;
// vars
var $popup = $( this.$el.children('.tmpl-popup').html() );
// modify popup
$popup.find('a').each(function(){
// vars
var min = parseInt( $(this).attr('data-min') ),
max = parseInt( $(this).attr('data-max') ),
name = $(this).attr('data-layout'),
label = $(this).text(),
count = $values.children('.layout[data-layout="' + name + '"]').length,
$status = $(this).children('.status');
if( max > 0 ) {
// find diff
var available = max - count,
s = acf._e('flexible_content', 'available'),
identifier = ( available == 1 ) ? 'layout' : 'layouts',
// translate
s = s.replace('{available}', available);
s = s.replace('{max}', max);
s = s.replace('{label}', '"' + label + '"');
s = s.replace('{identifier}', acf._e('flexible_content', identifier));
// show status
$status.show().text( available ).attr('title', s);
// limit reached?
if( available == 0 ) {
$status.addClass('warning');
}
}
if( min > 0 ) {
// find diff
var required = min - count,
s = acf._e('flexible_content', 'required'),
identifier = ( required == 1 ) ? 'layout' : 'layouts',
// translate
s = s.replace('{required}', required);
s = s.replace('{min}', min);
s = s.replace('{label}', '"' + label + '"');
s = s.replace('{identifier}', acf._e('flexible_content', identifier));
// limit reached?
if( required > 0 ) {
$status.addClass('warning').show().text( required ).attr('title', s);
}
}
});
// add popup
e.$el.after( $popup );
// within layout?
if( e.$el.closest('.acf-fc-layout-controlls').exists() ) {
$popup.closest('.layout').addClass('-open');
}
// vars
$popup.css({
'margin-top' : 0 - $popup.height() - e.$el.outerHeight() - 14,
'margin-left' : ( e.$el.outerWidth() - $popup.width() ) / 2,
});
// check distance to top
var offset = $popup.offset().top;
if( offset < 30 ) {
$popup.css({
'margin-top' : 15
});
$popup.find('.bit').addClass('top');
}
// focus
$popup.children('.focus').trigger('focus');
},
_close: function( e ){ //console.log('_close');
var $popup = e.$el.parent(),
$layout = $popup.closest('.layout');
// hide controlls?
$layout.removeClass('-open');
// remove popup
setTimeout(function(){
$popup.remove();
}, 200);
},
_add: function( e ){ //console.log('_add');
// vars
var $popup = e.$el.closest('.acf-fc-popup'),
layout = e.$el.attr('data-layout'),
$before = false;
// move row
if( $popup.closest('.acf-fc-layout-controlls').exists() ) {
$before = $popup.closest('.layout');
}
// add row
this.add( layout, $before );
},
_remove: function( e ){ //console.log('_remove');
// reference
var self = this;
// vars
var $layout = e.$el.closest('.layout');
// bail early if validation fails
if( !this.validate_remove( $layout.attr('data-layout') ) ) {
return;
}
// close field
var end_height = 0,
$message = this.$el.children('.no-value-message');
if( $layout.siblings('.layout').length == 0 ) {
end_height = $message.outerHeight();
}
// action for 3rd party customization
acf.do_action('remove', $layout);
// remove
acf.remove_el( $layout, function(){
// update order
self.render();
// trigger change to allow attachment save
self.$input.trigger('change');
if( end_height > 0 ) {
$message.show();
}
// sync collapsed order
self.sync();
}, end_height);
},
_collapse: function( e ){ //console.log('_collapse');
// vars
var $layout = e.$el.closest('.layout');
// render
// - do this before calling actions to avoif focusing on the wrong field
this.render_layout_title( $layout );
// open
if( $layout.hasClass('-collapsed') ) {
$layout.removeClass('-collapsed');
acf.do_action('show', $layout, 'collapse');
// close
} else {
$layout.addClass('-collapsed');
acf.do_action('hide', $layout, 'collapse');
}
// sync collapsed order
this.sync();
}
});
})(jQuery);
(function($){
acf.fields.gallery = acf.field.extend({
type: 'gallery',
$el: null,
$main: null,
$side: null,
$attachments: null,
$input: null,
//$attachment: null,
actions: {
'ready': 'initialize',
'append': 'initialize',
'show': 'resize'
},
events: {
'click .acf-gallery-attachment': '_select',
'click .acf-gallery-add': '_add',
'click .acf-gallery-remove': '_remove',
'click .acf-gallery-close': '_close',
'change .acf-gallery-sort': '_sort',
'click .acf-gallery-edit': '_edit',
'click .acf-gallery-update': '_update',
'change .acf-gallery-side input': '_update',
'change .acf-gallery-side textarea': '_update',
'change .acf-gallery-side select': '_update'
},
/*
* focus
*
* This function will setup variables when focused on a field
*
* @type function
* @date 12/04/2016
* @since 5.3.8
*
* @param n/a
* @return n/a
*/
focus: function(){
// el
this.$el = this.$field.find('.acf-gallery:first');
this.$main = this.$el.children('.acf-gallery-main');
this.$side = this.$el.children('.acf-gallery-side');
this.$attachments = this.$main.children('.acf-gallery-attachments');
this.$input = this.$el.find('input:first');
// get options
this.o = acf.get_data( this.$el );
// min / max
this.o.min = this.o.min || 0;
this.o.max = this.o.max || 0;
},
/*
* initialize
*
* This function will initialize the field
*
* @type function
* @date 12/04/2016
* @since 5.3.8
*
* @param n/a
* @return n/a
*/
initialize: function(){
// reference
var self = this,
$field = this.$field;
// sortable
this.$attachments.unbind('sortable').sortable({
items : '.acf-gallery-attachment',
forceHelperSize : true,
forcePlaceholderSize : true,
scroll : true,
start: function (event, ui) {
ui.placeholder.html( ui.item.html() );
ui.placeholder.removeAttr('style');
acf.do_action('sortstart', ui.item, ui.placeholder);
},
stop: function (event, ui) {
acf.do_action('sortstop', ui.item, ui.placeholder);
}
});
// resizable
this.$el.unbind('resizable').resizable({
handles: 's',
minHeight: 200,
stop: function(event, ui){
acf.update_user_setting('gallery_height', ui.size.height);
}
});
// resize
$(window).on('resize', function(){
self.set('$field', $field).resize();
});
// render
this.render();
// resize
this.resize();
},
/*
* resize
*
* This function will resize the columns
*
* @type function
* @date 20/04/2016
* @since 5.3.8
*
* @param $post_id (int)
* @return $post_id (int)
*/
resize: function(){
// vars
var min = 100,
max = 175,
columns = 4,
width = this.$el.width();
// get width
for( var i = 4; i < 20; i++ ) {
var w = width/i;
if( min < w && w < max ) {
columns = i;
break;
}
}
// max columns css is 8
columns = Math.min(columns, 8);
// update data
this.$el.attr('data-columns', columns);
},
/*
* render
*
* This function will render classes etc
*
* @type function
* @date 19/04/2016
* @since 5.3.8
*
* @param n/a
* @return n/a
*/
render: function() {
// vars
var $select = this.$main.find('.acf-gallery-sort'),
$a = this.$main.find('.acf-gallery-add');
// disable a
if( this.o.max > 0 && this.count() >= this.o.max ) {
$a.addClass('disabled');
} else {
$a.removeClass('disabled');
}
// disable select
if( !this.count() ) {
$select.addClass('disabled');
} else {
$select.removeClass('disabled');
}
},
/*
* open_sidebar
*
* This function will open the gallery sidebar
*
* @type function
* @date 19/04/2016
* @since 5.3.8
*
* @param n/a
* @return n/a
*/
open_sidebar: function(){
// add class
this.$el.addClass('sidebar-open');
// hide bulk actions
this.$main.find('.acf-gallery-sort').hide();
// vars
var width = this.$el.width() / 3;
// set minimum width
width = parseInt( width );
width = Math.max( width, 350 );
// animate
this.$side.children('.acf-gallery-side-inner').css({ 'width' : width-1 });
this.$side.animate({ 'width' : width-1 }, 250);
this.$main.animate({ 'right' : width }, 250);
},
/*
* _close
*
* event listener
*
* @type function
* @date 12/04/2016
* @since 5.3.8
*
* @param e (event)
* @return n/a
*/
_close: function( e ){
this.close_sidebar();
},
/*
* close_sidebar
*
* This function will open the gallery sidebar
*
* @type function
* @date 19/04/2016
* @since 5.3.8
*
* @param n/a
* @return n/a
*/
close_sidebar: function(){
// remove class
this.$el.removeClass('sidebar-open');
// vars
var $select = this.$el.find('.acf-gallery-sort');
// clear selection
this.get_attachment('active').removeClass('active');
// disable sidebar
this.$side.find('input, textarea, select').attr('disabled', 'disabled');
// animate
this.$main.animate({ right: 0 }, 250);
this.$side.animate({ width: 0 }, 250, function(){
$select.show();
$(this).find('.acf-gallery-side-data').html('');
});
},
/*
* count
*
* This function will return the number of attachemnts
*
* @type function
* @date 12/04/2016
* @since 5.3.8
*
* @param n/a
* @return n/a
*/
count: function(){
return this.get_attachments().length;
},
/*
* get_attachments
*
* description
*
* @type function
* @date 19/04/2016
* @since 5.3.8
*
* @param $post_id (int)
* @return $post_id (int)
*/
get_attachments: function(){
return this.$attachments.children('.acf-gallery-attachment');
},
/*
* get_attachment
*
* This function will return an attachment
*
* @type function
* @date 19/04/2016
* @since 5.3.8
*
* @param id (string)
* @return $el
*/
get_attachment: function( s ){
// defaults
s = s || 0;
// update selector
if( s === 'active' ) {
s = '.active';
} else {
s = '[data-id="' + s + '"]';
}
// return
return this.$attachments.children( '.acf-gallery-attachment'+s );
},
/*
* render_attachment
*
* This functin will render an attachemnt
*
* @type function
* @date 20/04/2016
* @since 5.3.8
*
* @param $post_id (int)
* @return $post_id (int)
*/
render_attachment: function( data ){
// prepare
data = this.prepare(data);
// vars
var $attachment = this.get_attachment(data.id),
$margin = $attachment.find('.margin'),
$img = $attachment.find('img'),
$filename = $attachment.find('.filename'),
$input = $attachment.find('input[type="hidden"]');
// thumbnail
var thumbnail = data.url;
// image
if( data.type == 'image' ) {
// remove filename
$filename.remove();
// other (video)
} else {
// attempt to find attachment thumbnail
thumbnail = acf.maybe_get(data, 'thumb.src');
// update filenmae text
$filename.text( data.filename );
}
// default icon
if( !thumbnail ) {
thumbnail = acf._e('media', 'default_icon');
$attachment.addClass('-icon');
}
// update els
$img.attr({
'src': thumbnail,
'alt': data.alt,
'title': data.title
});
// update val
acf.val( $input, data.id );
},
_add: function( e ){
// validate
if( this.o.max > 0 && this.count() >= this.o.max ) {
acf.validation.add_warning( this.$field, acf._e('gallery', 'max'));
return;
}
// reference
var self = this,
$field = this.$field;
// popup
var frame = acf.media.popup({
title: acf._e('gallery', 'select'),
mode: 'select',
type: '',
field: this.$field.data('key'),
multiple: 'add',
library: this.o.library,
mime_types: this.o.mime_types,
select: function( attachment, i ) {
// add
self.set('$field', $field).add_attachment( attachment, i );
}
});
// modify DOM
frame.on('content:activate:browse', function(){
self.render_collection( frame );
frame.content.get().collection.on( 'reset add', function(){
self.render_collection( frame );
});
});
},
/*
* add_attachment
*
* This function will add an attachment
*
* @type function
* @date 20/04/2016
* @since 5.3.8
*
* @param $post_id (int)
* @return $post_id (int)
*/
add_attachment: function( data, i ){
// defaults
i = i || 0;
// prepare
data = this.prepare(data);
// validate
if( this.o.max > 0 && this.count() >= this.o.max ) return;
// is image already in gallery?
if( this.get_attachment(data.id).exists() ) return;
// vars
var name = this.$el.find('input[type="hidden"]:first').attr('name');
// html
var html = [
'<div class="acf-gallery-attachment acf-soh" data-id="' + data.id + '">',
'<input type="hidden" value="' + data.id + '" name="' + name + '[]">',
'<div class="margin" title="">',
'<div class="thumbnail">',
'<img src="" alt="">',
'</div>',
'<div class="filename"></div>',
'</div>',
'<div class="actions acf-soh-target">',
'<a href="#" class="acf-icon -cancel dark acf-gallery-remove" data-id="' + data.id + '"></a>',
'</div>',
'</div>'].join('');
var $html = $(html);
// append
this.$attachments.append( $html );
// more to beginning
if( this.o.insert === 'prepend' ) {
// vars
var $before = this.$attachments.children(':eq('+i+')');
// move
if( $before.exists() ) {
$before.before( $html );
}
}
// render data
this.render_attachment( data );
// render
this.render();
// trigger change
this.$input.trigger('change');
},
/*
* _select
*
* event listener
*
* @type function
* @date 12/04/2016
* @since 5.3.8
*
* @param e (event)
* @return n/a
*/
_select: function( e ){
// vars
var id = e.$el.data('id');
// select
this.select_attachment(id);
},
/*
* select_attachment
*
* This function will select an attachment for editing
*
* @type function
* @date 20/04/2016
* @since 5.3.8
*
* @param $post_id (int)
* @return $post_id (int)
*/
select_attachment: function( id ){
// vars
var $attachment = this.get_attachment(id);
// bail early if already active
if( $attachment.hasClass('active') ) return;
// clear selection
this.get_attachment('active').removeClass('active');
// add selection
$attachment.addClass('active');
// fetch
this.fetch( id );
// open sidebar
this.open_sidebar();
},
/*
* prepare
*
* This function will prepare an object of attachment data
* selecting a library image vs embed an image via url return different data
* this function will keep the 2 consistent
*
* @type function
* @date 12/04/2016
* @since 5.3.8
*
* @param attachment (object)
* @return data (object)
*/
prepare: function( attachment ) {
// defaults
attachment = attachment || {};
// bail ealry if already valid
if( attachment._valid ) return attachment;
// vars
var data = {
id: '',
url: '',
alt: '',
title: '',
filename: ''
};
// wp image
if( attachment.id ) {
// update data
data = attachment.attributes;
// maybe get preview size
data.url = acf.maybe_get(data, 'sizes.medium.url', data.url);
}
// valid
data._valid = true;
// return
return data;
},
/*
* fetch
*
* This function will fetch the sidebar html to edit an attachment
*
* @type function
* @date 19/04/2016
* @since 5.3.8
*
* @param n/a
* @return n/a
*/
fetch: function( id ){
// vars
var data = acf.prepare_for_ajax({
action : 'acf/fields/gallery/get_attachment',
field_key : this.$field.data('key'),
id : id
});
// abort XHR if this field is already loading AJAX data
if( this.$el.data('xhr') ) {
this.$el.data('xhr').abort();
}
// add custom attachment
if( typeof id === 'string' && id.indexOf('_') === 0 ) {
// vars
var val = this.get_attachment(id).find('input[type="hidden"]').val();
// parse json
val = $.parseJSON(val);
// append
data.attachment = val;
}
// get results
var xhr = $.ajax({
url : acf.get('ajaxurl'),
dataType : 'html',
type : 'post',
cache : false,
data : data,
context : this,
success : this.fetch_success
});
// update el data
this.$el.data('xhr', xhr);
},
fetch_success: function( html ){
// bail early if no html
if( !html ) return;
// vars
var $side = this.$side.find('.acf-gallery-side-data');
// render
$side.html( html );
// remove acf form data
$side.find('.compat-field-acf-form-data').remove();
// detach meta tr
var $tr = $side.find('> .compat-attachment-fields > tbody > tr').detach();
// add tr
$side.find('> table.form-table > tbody').append( $tr );
// remove origional meta table
$side.find('> .compat-attachment-fields').remove();
// setup fields
acf.do_action('append', $side);
},
/*
* _sort
*
* event listener
*
* @type function
* @date 12/04/2016
* @since 5.3.8
*
* @param e (event)
* @return n/a
*/
_sort: function( e ){
// vars
var sort = e.$el.val();
// validate
if( !sort ) return;
// vars
var data = acf.prepare_for_ajax({
action : 'acf/fields/gallery/get_sort_order',
field_key : this.$field.data('key'),
ids : [],
sort : sort
});
// find and add attachment ids
this.get_attachments().each(function(){
// vars
var id = $(this).attr('data-id');
// bail early if no id (insert from url)
if( !id ) return;
// append
data.ids.push(id);
});
// get results
var xhr = $.ajax({
url: acf.get('ajaxurl'),
dataType: 'json',
type: 'post',
cache: false,
data: data,
context: this,
success: this._sort_success
});
},
_sort_success: function( json ) {
// validate
if( !acf.is_ajax_success(json) ) return;
// reverse order
json.data.reverse();
// loop over json
for( i in json.data ) {
var id = json.data[ i ],
$attachment = this.get_attachment(id);
// prepend attachment
this.$attachments.prepend( $attachment );
}
},
/*
* _update
*
* event listener
*
* @type function
* @date 12/04/2016
* @since 5.3.8
*
* @param e (event)
* @return n/a
*/
_update: function(){
// vars
var $submit = this.$side.find('.acf-gallery-update'),
$edit = this.$side.find('.acf-gallery-edit'),
$form = this.$side.find('.acf-gallery-side-data'),
id = $edit.data('id'),
data = acf.serialize_form( $form );
// validate
if( $submit.attr('disabled') ) return false;
// add attr
$submit.attr('disabled', 'disabled');
$submit.before('<i class="acf-loading"></i>');
// append AJAX action
data.action = 'acf/fields/gallery/update_attachment';
// prepare for ajax
acf.prepare_for_ajax(data);
// ajax
$.ajax({
url : acf.get('ajaxurl'),
data : data,
type : 'post',
dataType : 'json',
complete : function( json ){
$submit.removeAttr('disabled');
$submit.prev('.acf-loading').remove();
}
});
},
/*
* _remove
*
* event listener
*
* @type function
* @date 12/04/2016
* @since 5.3.8
*
* @param e (event)
* @return n/a
*/
_remove: function( e ){
// prevent event from triggering click on attachment
e.stopPropagation();
// vars
var id = e.$el.data('id');
// select
this.remove_attachment(id);
},
/*
* remove_attachment
*
* This function will remove an attachment
*
* @type function
* @date 20/04/2016
* @since 5.3.8
*
* @param $post_id (int)
* @return $post_id (int)
*/
remove_attachment: function( id ){
// close sidebar (if open)
this.close_sidebar();
// remove attachment
this.get_attachment(id).remove();
// render (update classes)
this.render();
// trigger change
this.$input.trigger('change');
},
/*
* _edit
*
* event listener
*
* @type function
* @date 12/04/2016
* @since 5.3.8
*
* @param e (event)
* @return n/a
*/
_edit:function( e ){
// vars
var id = e.$el.data('id');
// select
this.edit_attachment(id);
},
/*
* edit_attachment
*
* This function will create a WP popup to edit an attachment
*
* @type function
* @date 20/04/2016
* @since 5.3.8
*
* @param $post_id (int)
* @return $post_id (int)
*/
edit_attachment: function( id ){
// reference
var self = this,
$field = this.$field;
// popup
var frame = acf.media.popup({
mode: 'edit',
title: acf._e('image', 'edit'),
button: acf._e('image', 'update'),
attachment: id,
select: function( attachment ){
// render attachment
self.set('$field', $field).render_attachment( attachment );
// render sidebar
self.fetch( id );
}
});
},
render_collection: function( frame ){
var self = this;
// Note: Need to find a differen 'on' event. Now that attachments load custom fields, this function can't rely on a timeout. Instead, hook into a render function foreach item
// set timeout for 0, then it will always run last after the add event
setTimeout(function(){
// vars
var $content = frame.content.get().$el
collection = frame.content.get().collection || null;
if( collection ) {
var i = -1;
collection.each(function( item ){
i++;
var $li = $content.find('.attachments > .attachment:eq(' + i + ')');
// if image is already inside the gallery, disable it!
if( self.get_attachment(item.id).exists() ) {
item.off('selection:single');
$li.addClass('acf-selected');
}
});
}
}, 10);
}
});
/*
* acf_gallery_manager
*
* Priveds some global functionality for the gallery field
*
* @type function
* @date 25/11/2015
* @since 5.3.2
*
* @param n/a
* @return n/a
*/
var acf_gallery_manager = acf.model.extend({
actions: {
'validation_begin': 'validation_begin',
'validation_failure': 'validation_failure'
},
validation_begin: function(){
// lock all gallery forms
$('.acf-gallery-side-data').each(function(){
acf.disable_form( $(this), 'gallery' );
});
},
validation_failure: function(){
// lock all gallery forms
$('.acf-gallery-side-data').each(function(){
acf.enable_form( $(this), 'gallery' );
});
}
});
})(jQuery);
// @codekit-prepend "../js/acf-pro.js";
// @codekit-prepend "../js/acf-repeater.js";
// @codekit-prepend "../js/acf-flexible-content.js";
// @codekit-prepend "../js/acf-gallery.js";