(function($){
/*
* Flexible Content
*
* static model for this field
*
* @type event
* @date 18/08/13
*
*/
acf.fields.flexible_content = {
$el : null,
$values : null,
o : {},
set : function( o ){
// merge in new option
$.extend( this, o );
// find elements
this.$values = this.$el.children('.values');
// get options
this.o = acf.helpers.get_atts( this.$el );
// add layout_count
this.o.layout_count = this.$values.children('.layout').length;
// return this for chaining
return this;
},
init : function(){
// reference
var _this = this,
$el = this.$el;
// sortable
if( this.o.max != 1 )
{
this.$values.unbind('sortable').sortable({
items : '> .layout',
handle : '> .acf-fc-layout-handle',
forceHelperSize : true,
forcePlaceholderSize : true,
scroll : true,
start : function (event, ui) {
$(document).trigger('acf/sortable_start', ui.item);
$(document).trigger('acf/sortable_start_flex', ui.item);
},
stop : function (event, ui) {
$(document).trigger('acf/sortable_stop', ui.item);
$(document).trigger('acf/sortable_stop_flex', ui.item);
// render
_this.set({ $el : $el }).render();
}
});
}
// render
this.render();
// make field required if has min
var add_required = false;
if( this.o.min > 0 )
{
add_required = true;
}
else
{
// vars
var $popup = $( this.$el.children('.tmpl-popup').html() );
$popup.find('a').each(function(){
// vars
var min = parseInt( $(this).attr('data-min') );
if( min > 0 )
{
add_required = true;
// end loop
return false;
}
});
}
if( add_required )
{
this.$el.closest('.field').addClass('required');
}
},
render : function(){
// update order numbers
this.$values.children('.layout').each(function( i ){
$(this).find('> .acf-fc-layout-handle .fc-layout-order').html( i+1 );
});
// empty?
if( this.o.layout_count == 0 )
{
this.$el.addClass('empty');
}
else
{
this.$el.removeClass('empty');
}
// row limit reached
if( this.o.layout_count >= this.o.max )
{
this.$el.addClass('disabled');
this.$el.find('> .acf-flexible-content-footer .acf-button').addClass('disabled');
}
else
{
this.$el.removeClass('disabled');
this.$el.find('> .flexible-footer .acf-button').removeClass('disabled');
}
},
validate_add : function( layout ){
var r = true;
// vadiate max
this.o.max = parseInt(this.o.max);
if( this.o.max > 0 && this.o.layout_count >= this.o.max )
{
var identifier = ( this.o.max == 1 ) ? 'layout' : 'layouts',
s = acf.l10n.flexible_content.max;
// translate
s = s.replace('{max}', this.o.max);
s = s.replace('{identifier}', acf.l10n.flexible_content[ identifier ]);
r = false;
alert( s );
}
// vadiate max layout
var $popup = $( this.$el.children('.tmpl-popup').html() ),
$a = $popup.find('[data-layout="' + layout + '"]'),
layout_max = $a.attr('data-max'),
layout_count = this.$values.children('.layout[data-layout="' + layout + '"]').length;
layout_max = parseInt(layout_max);
if( layout_max > 0 && layout_count >= layout_max )
{
var identifier = ( layout_max == 1 ) ? 'layout' : 'layouts',
s = acf.l10n.flexible_content.max_layout;
// translate
s = s.replace('{max}', layout_count);
s = s.replace('{label}', '"' + $a.text() + '"');
s = s.replace('{identifier}', acf.l10n.flexible_content[ identifier ]);
r = false;
alert( s );
}
// return
return r;
},
validate_remove : function( layout ){
// vadiate min
this.o.min = parseInt(this.o.min);
if( this.o.min > 0 && this.o.layout_count <= this.o.min )
{
var identifier = ( this.o.min == 1 ) ? 'layout' : 'layouts',
s = acf.l10n.flexible_content.min + ', ' + acf.l10n.flexible_content.remove;
// translate
s = s.replace('{min}', this.o.min);
s = s.replace('{identifier}', acf.l10n.flexible_content[ identifier ]);
s = s.replace('{layout}', acf.l10n.flexible_content.layout);
return confirm( s );
}
// vadiate max layout
var $popup = $( this.$el.children('.tmpl-popup').html() ),
$a = $popup.find('[data-layout="' + layout + '"]'),
layout_min = $a.attr('data-min'),
layout_count = this.$values.children('.layout[data-layout="' + layout + '"]').length;
layout_min = parseInt(layout_min);
if( layout_min > 0 && layout_count <= layout_min )
{
var identifier = ( layout_min == 1 ) ? 'layout' : 'layouts',
s = acf.l10n.flexible_content.min_layout + ', ' + acf.l10n.flexible_content.remove;
// translate
s = s.replace('{min}', layout_count);
s = s.replace('{label}', '"' + $a.text() + '"');
s = s.replace('{identifier}', acf.l10n.flexible_content[ identifier ]);
s = s.replace('{layout}', acf.l10n.flexible_content.layout);
return confirm( s );
}
// return
return true;
},
add : function( layout, $before ){
// bail early if validation fails
if( !this.validate_add( layout ) )
{
return;
}
// vars
var new_id = acf.helpers.uniqid(),
new_field_html = this.$el.find('> .clones > .layout[data-layout="' + layout + '"]').html().replace(/(=["]*[\w-\[\]]*?)(acfcloneindex)/g, '$1' + new_id),
new_field = $('<div class="layout" data-layout="' + layout + '"></div>').append( new_field_html );
// hide no values message
this.$el.children('.no_value_message').hide();
// add row
if( $before )
{
$before.before( new_field );
}
else
{
this.$values.append( new_field );
}
// acf/setup_fields
$(document).trigger('acf/setup_fields', [ new_field ] );
// update order
this.render();
// validation
this.$el.closest('.field').removeClass('error');
},
remove : function( $el ){
// bail early if validation fails
if( !this.validate_remove( $el.attr('data-layout') ) )
{
return;
}
// refernce
var _this = this;
// set layout
$el.css({
height : $el.height(),
width : $el.width(),
position : 'absolute'
});
// fade $tr
$el.animate({ opacity : 0 }, 250, function(){
$(this).remove();
});
// create blank space
$blank = $('<div style="height:' + $el.height() + 'px"></div>');
$el.after( $blank );
// close field
var end_height = 0;
if( $el.siblings('.layout').length == 0 )
{
end_height = this.$el.children('.no_value_message').outerHeight();
}
$blank.animate({ height : end_height }, 250, function(){
$(this).remove();
if( end_height > 0 )
{
_this.$el.children('.no_value_message').show();
}
});
},
toggle : function( $layout ){
if( $layout.attr('data-toggle') == 'closed' )
{
$layout.attr('data-toggle', 'open');
$layout.children('.acf-input-table').show();
}
else
{
$layout.attr('data-toggle', 'closed');
$layout.children('.acf-input-table').hide();
}
},
open_popup : function( $a, in_layout ){
// reference
var _this = this;
// defaults
in_layout = in_layout || false;
// vars
$popup = $( this.$el.children('.tmpl-popup').html() );
$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 = _this.$values.children('.layout[data-layout="' + name + '"]').length,
$status = $(this).children('.status');
if( max > 0 )
{
// find diff
var available = max - count,
s = acf.l10n.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.l10n.flexible_content[ identifier ]);
$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.l10n.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.l10n.flexible_content[ identifier ]);
if( required > 0 )
{
$status.addClass('warning').show().text( required ).attr('title', s);
}
}
});
// add popup
$a.after( $popup );
// within layout?
if( in_layout )
{
$popup.addClass('within-layout');
$popup.closest('.layout').addClass('popup-open');
}
// vars
$popup.css({
'margin-top' : 0 - $popup.height() - $a.outerHeight() - 14,
'margin-left' : ( $a.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');
}
$popup.children('.focus').trigger('focus');
}
};
/*
* acf/setup_fields
*
* run init function on all elements for this field
*
* @type event
* @date 20/07/13
*
* @param {object} e event object
* @param {object} el DOM object which may contain new ACF elements
* @return N/A
*/
$(document).on('acf/setup_fields', function(e, el){
$(el).find('.acf-flexible-content').each(function(){
acf.fields.flexible_content.set({ $el : $(this) }).init();
});
});
/*
* Events
*
* jQuery events for this field
*
* @type function
* @date 1/03/2011
*
* @param N/A
* @return N/A
*/
$(document).on('click', '.acf-flexible-content .flexible-footer .acf-fc-add', function( e ){
e.preventDefault();
acf.fields.flexible_content.set({ $el : $(this).closest('.acf-flexible-content') }).open_popup( $(this) );
$(this).blur();
});
$(document).on('click', '.acf-flexible-content .acf-fc-layout-controlls .acf-fc-add', function( e ){
e.preventDefault();
acf.fields.flexible_content.set({ $el : $(this).closest('.acf-flexible-content') }).open_popup( $(this), true );
$(this).blur();
});
$(document).on('click', '.acf-flexible-content .acf-fc-layout-controlls .acf-fc-remove', function( e ){
e.preventDefault();
acf.fields.flexible_content.set({ $el : $(this).closest('.acf-flexible-content') }).remove( $(this).closest('.layout') );
$(this).blur();
});
$(document).on('click', '.acf-flexible-content .acf-fc-layout-handle', function( e ){
e.preventDefault();
acf.fields.flexible_content.toggle( $(this).closest('.layout') );
$(this).blur();
});
/* popup */
$(document).on('click', '.acf-flexible-content .acf-fc-popup li a', function( e ){
e.preventDefault();
var $popup = $(this).closest('.acf-fc-popup'),
$layout = null;
if( $popup.hasClass('within-layout') )
{
$layout = $popup.closest('.layout');
}
acf.fields.flexible_content.set({ $el : $(this).closest('.acf-flexible-content') }).add( $(this).attr('data-layout'), $layout );
$(this).blur();
});
$(document).on('blur', '.acf-flexible-content .acf-fc-popup .focus', function( e ){
var $popup = $(this).parent();
// hide controlls?
if( $popup.closest('.layout').exists() )
{
$popup.closest('.layout').removeClass('popup-open');
}
setTimeout(function(){
$popup.remove();
}, 200);
});
/*
* Validate
*
* jQuery events for this field
*
* @type function
* @date 1/03/2011
*
* @param N/A
* @return N/A
*/
$(document).on('acf/validate_field', function( e, field ){
// vars
var $field = $( field );
// validate
if( ! $field.hasClass('field_type-flexible_content') )
{
return;
}
var $el = $field.find('.acf-flexible-content:first');
// required
$field.data('validation', false);
$field.data('validation_message', false);
if( $el.children('.values').children('.layout').exists() )
{
$field.data('validation', true);
}
// min total
var min = parseInt( $el.attr('data-min') );
if( min > 0 )
{
if( $el.children('.values').children('.layout').length < min )
{
var identifier = ( min == 1 ) ? 'layout' : 'layouts',
s = acf.l10n.flexible_content.min;
// translate
s = s.replace('{min}', min);
s = s.replace('{identifier}', acf.l10n.flexible_content[ identifier ]);
$field.data('validation', false);
$field.data('validation_message', s);
}
}
// min layout
var $popup = $( $el.children('.tmpl-popup').html() );
$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 = $el.children('.values').children('.layout[data-layout="' + name + '"]').length;
if( count < min )
{
var identifier = ( min == 1 ) ? 'layout' : 'layouts',
s = acf.l10n.flexible_content.min_layout;
// translate
s = s.replace('{min}', min);
s = s.replace('{label}', '"' + label + '"');
s = s.replace('{identifier}', acf.l10n.flexible_content[ identifier ]);
$field.data('validation', false);
$field.data('validation_message', s);
}
});
});
})(jQuery);