new module's parent.
* @param {String} parentId The node id of the new module's parent.
* @param {String} type The type of module to add.
* @param {Number} position The position of the new module within its parent.
* @param {String} widget The type of widget if this module is a widget.
*/
_addModule: function(parent, parentId, type, position, widget)
{
// Show the loader.
FLBuilder.showAjaxLoader();
// Save the new module data.
if ( parent.hasClass( 'fl-col-group' ) ) {
FLBuilder._newModuleParent = null;
FLBuilder._newModulePosition = 0;
}
else {
FLBuilder._newModuleParent = parent;
FLBuilder._newModulePosition = position;
}
// Send the request.
FLBuilder.ajax({
action : 'render_new_module',
parent_id : parentId,
type : type,
position : position,
node_preview : 1,
widget : typeof widget === 'undefined' ? '' : widget
}, FLBuilder._addModuleComplete);
},
/**
* Shows the settings lightbox and sets the content when
* the module settings have finished loading.
*
* @since 1.0
* @access private
* @method _addModuleComplete
* @param {String} response The JSON encoded response.
*/
_addModuleComplete: function(response)
{
FLBuilder._showLightbox();
FLBuilder._moduleSettingsLoaded(response);
$('.fl-builder-module-settings').data('new-module', '1');
},
/**
* Registers a helper class for a module's settings.
*
* @since 1.0
* @method registerModuleHelper
* @param {String} type The type of module.
* @param {Object} obj The module helper.
*/
registerModuleHelper: function(type, obj)
{
var defaults = {
rules: {},
init: function(){},
submit: function(){ return true; },
preview: function(){}
};
FLBuilder._moduleHelpers[type] = $.extend({}, defaults, obj);
},
/**
* Deprecated. Use the public method registerModuleHelper instead.
*
* @since 1.0
* @access private
* @method _registerModuleHelper
* @param {String} type The type of module.
* @param {Object} obj The module helper.
*/
_registerModuleHelper: function(type, obj)
{
FLBuilder.registerModuleHelper(type, obj);
},
/* Node Templates
----------------------------------------------------------*/
/**
* Saves a node's settings and shows the node template settings
* when the Save As button is clicked.
*
* @since 1.6.3
* @access private
* @method _showNodeTemplateSettings
* @param {Object} e An event object.
*/
_showNodeTemplateSettings: function( e )
{
var form = $( '.fl-builder-settings-lightbox .fl-builder-settings' );
FLBuilder._saveSettings();
FLBuilder.ajax( {
action : 'render_node_template_settings',
node_id : form.attr( 'data-node' )
}, FLBuilder._nodeTemplateSettingsLoaded );
},
/**
* Sets the lightbox content when the node template settings have loaded.
*
* @since 1.6.3
* @access private
* @method _nodeTemplateSettingsLoaded
* @param {String} response The JSON with the HTML for the settings form.
*/
_nodeTemplateSettingsLoaded: function( response )
{
var data = JSON.parse( response );
FLBuilder._showLightbox( false );
FLBuilder._setSettingsFormContent( data.html );
FLBuilder._initSettingsValidation({
name: {
required: true
}
});
},
/**
* Saves a node as a template when the save button is clicked.
*
* @since 1.6.3
* @access private
* @method _saveNodeTemplate
*/
_saveNodeTemplate: function()
{
var form = $( '.fl-builder-settings-lightbox .fl-builder-settings' ),
valid = form.validate().form();
if ( valid ) {
FLBuilder.showAjaxLoader();
FLBuilder.ajax({
action : 'save_node_template',
node_id : form.attr( 'data-node' ),
settings : FLBuilder._getSettings( form )
}, FLBuilder._saveNodeTemplateComplete);
FLBuilder._lightbox.close();
}
},
/**
* Callback for when a node template has been saved.
*
* @since 1.6.3
* @access private
* @method _saveNodeTemplateComplete
*/
_saveNodeTemplateComplete: function( response )
{
var data = JSON.parse( response ),
panel = $( '.fl-builder-saved-' + data.type + 's' ),
blocks = panel.find( '.fl-builder-block' ),
block = null,
text = '',
name = data.name.toLowerCase(),
i = 0,
template = wp.template( 'fl-node-template-block' );
// Show the success alert.
if ( 'row' == data.type ) {
FLBuilder.alert( FLBuilderStrings.rowTemplateSaved );
}
else if ( 'module' == data.type ) {
FLBuilder.alert( FLBuilderStrings.moduleTemplateSaved );
}
// Update the layout for global templates.
if ( data.layout ) {
FLBuilder._renderLayout( data.layout );
}
// Add the new template to the builder panel.
if ( 0 === blocks.length ) {
panel.append( template( data ) );
}
else {
for ( ; i < blocks.length; i++ ) {
block = blocks.eq( i );
text = block.text().toLowerCase().trim();
if ( 0 === i && name < text ) {
panel.prepend( template( data ) );
break;
}
else if ( name < text ) {
block.before( template( data ) );
break;
}
else if ( blocks.length - 1 === i ) {
panel.append( template( data ) );
break;
}
}
}
// Remove the no templates placeholder.
panel.find( '.fl-builder-block-no-node-templates' ).remove();
},
/**
* Callback for when a node template drag from the
* builder panel has stopped.
*
* @since 1.6.3
* @access private
* @method _nodeTemplateDragStop
* @param {Object} e The event object.
* @param {Object} ui An object with additional info for the drag.
*/
_nodeTemplateDragStop: function( e, ui )
{
FLBuilder._blockDragStop( e, ui );
var item = ui.item,
parent = item.parent(),
parentId = null,
position = 0,
node = null,
action = '',
callback = null;
// A saved row was dropped.
if ( item.hasClass( 'fl-builder-block-saved-row' ) || item.hasClass( 'fl-builder-block-row-template' ) ) {
node = item.closest( '.fl-row' );
position = ! node.length ? 0 : $( FLBuilder._contentClass + ' .fl-row' ).index( node );
position = parent.hasClass( 'fl-drop-target-last' ) ? position + 1 : position;
parentId = null;
action = 'render_new_row';
callback = FLBuilder._addRowComplete;
FLBuilder._newRowPosition = position;
}
// A saved module was dropped.
else if ( item.hasClass( 'fl-builder-block-saved-module' ) || item.hasClass( 'fl-builder-block-module-template' ) ) {
action = 'render_new_module';
callback = FLBuilder._addModuleComplete;
// Cancel the drop if the sortable is disabled?
if ( parent.hasClass( 'fl-sortable-disabled' ) ) {
item.remove();
FLBuilder._showPanel();
return;
}
// Dropped into a row position.
else if ( parent.hasClass( 'fl-row-drop-target' ) ) {
parent = item.closest('.fl-builder-content');
parentId = 0;
position = parent.find( '.fl-row' ).index( item.closest('.fl-row') );
}
// Dropped into a column group position.
else if ( parent.hasClass( 'fl-col-group-drop-target' ) ) {
parent = item.closest( '.fl-row-content' );
parentId = parent.closest( '.fl-row' ).attr( 'data-node' );
position = parent.find( ' > .fl-col-group' ).index( item.closest( '.fl-col-group' ) );
}
// Dropped into a column position.
else if ( parent.hasClass( 'fl-col-drop-target' ) ) {
parent = item.closest('.fl-col-group');
position = parent.children('.fl-col').index( item.closest('.fl-col') );
parentId = parent.attr('data-node');
}
// Dropped into a column.
else {
position = parent.children( '.fl-module, .fl-builder-block' ).index( item );
parentId = item.closest( '.fl-col' ).attr( 'data-node' );
}
// Increment the position?
if ( item.closest( '.fl-drop-target-last' ).length ) {
position += 1;
}
// Save the new module data.
if ( parent.hasClass( 'fl-col-group' ) ) {
FLBuilder._newModuleParent = null;
FLBuilder._newModulePosition = 0;
}
else {
FLBuilder._newModuleParent = parent;
FLBuilder._newModulePosition = position;
}
}
// Show the loader.
FLBuilder.showAjaxLoader();
// Apply and render the node template.
FLBuilder.ajax({
action : action,
template_id : item.attr( 'data-id' ),
template_type : item.attr( 'data-type' ),
parent_id : parentId,
position : position
}, callback );
// Remove the helper.
item.remove();
},
/**
* Launches the builder in a new tab to edit a user
* defined node template when the edit link is clicked.
*
* @since 1.6.3
* @access private
* @method _editUserTemplateClicked
* @param {Object} e The event object.
*/
_editNodeTemplateClicked: function( e )
{
e.preventDefault();
e.stopPropagation();
window.open( $( this ).attr( 'href' ) );
},
/**
* Fires when the delete node template icon is clicked in the builder's panel.
*
* @since 1.6.3
* @access private
* @method _deleteNodeTemplateClicked
* @param {Object} e The event object.
*/
_deleteNodeTemplateClicked: function( e )
{
var button = $( e.target ),
section = button.closest( '.fl-builder-blocks-section' ),
panel = section.find( '.fl-builder-blocks-section-content' ),
blocks = panel.find( '.fl-builder-block' ),
block = button.closest( '.fl-builder-block' ),
global = block.hasClass( 'fl-builder-block-global' ),
callback = global ? FLBuilder._updateLayout : undefined,
message = global ? FLBuilderStrings.deleteGlobalTemplate : FLBuilderStrings.deleteTemplate;
if ( confirm( message ) ) {
// Delete the UI block.
block.remove();
// Add the no templates placeholder?
if ( 1 === blocks.length ) {
if ( block.hasClass( 'fl-builder-block-saved-row' ) ) {
panel.append( '' + FLBuilderStrings.noSavedRows + '' );
}
else {
panel.append( '' + FLBuilderStrings.noSavedModules + '' );
}
}
// Delete the template.
FLBuilder.ajax({
action : 'delete_node_template',
template_id : block.attr( 'data-id' ),
silent : block.hasClass( 'fl-builder-block-global' ) ? false : true
}, callback);
}
},
/* Settings
----------------------------------------------------------*/
/**
* Initializes logic for settings forms.
*
* @since 1.0
* @access private
* @method _initSettingsForms
*/
_initSettingsForms: function()
{
FLBuilder._initColorPickers();
FLBuilder._initSelectFields();
FLBuilder._initMultipleFields();
FLBuilder._initAutoSuggestFields();
FLBuilder._initLinkFields();
FLBuilder._initFontFields();
/**
* Hook for settings form init.
*/
FLBuilder.triggerHook('settings-form-init');
},
/**
* Sets the content for the settings lightbox.
*
* @since 1.0
* @access private
* @method _setSettingsFormContent
* @param {String} html The HTML content for the lightbox.
*/
_setSettingsFormContent: function(html)
{
FLBuilder._setLightboxContent(html);
FLBuilder._initSettingsForms();
},
/**
* Shows the content for a settings form tab when it is clicked.
*
* @since 1.0
* @access private
* @method _settingsTabClicked
* @param {Object} e The event object.
*/
_settingsTabClicked: function(e)
{
var tab = $(this),
form = tab.closest('.fl-builder-settings'),
id = tab.attr('href').split('#').pop();
form.find('.fl-builder-settings-tab').removeClass('fl-active');
form.find('#' + id).addClass('fl-active');
form.find('.fl-builder-settings-tabs .fl-active').removeClass('fl-active');
$(this).addClass('fl-active');
e.preve