1068 lines
30 KiB
JavaScript
1068 lines
30 KiB
JavaScript
/**
|
|
* Interface Builder
|
|
*/
|
|
;( function( $, underscore ) {
|
|
|
|
'use strict';
|
|
|
|
var cxInterfaceBuilder = {
|
|
|
|
init: function() {
|
|
// Component Init
|
|
this.component.init();
|
|
$( document ).on( 'cxFramework:interfaceBuilder:component', this.component.init.bind( this.component ) );
|
|
|
|
// Control Init
|
|
this.control.init();
|
|
$( document ).on( 'cxFramework:interfaceBuilder:control', this.control.init.bind( this.control ) );
|
|
},
|
|
|
|
component: {
|
|
tabClass: '.cx-tab',
|
|
accordionClass: '.cx-accordion',
|
|
toggleClass: '.cx-toggle',
|
|
|
|
buttonClass: '.cx-component__button',
|
|
contentClass: '.cx-settings__content',
|
|
|
|
buttonActiveClass: 'active',
|
|
showClass: 'show',
|
|
|
|
localStorage: {},
|
|
|
|
controlConditions: window.cxInterfaceBuilder.conditions || {},
|
|
|
|
controlValues: window.cxInterfaceBuilder.fields || {},
|
|
|
|
conditionState: {},
|
|
|
|
init: function () {
|
|
this.localStorage = this.getState() || {};
|
|
|
|
this.componentInit( this.tabClass );
|
|
this.componentInit( this.accordionClass );
|
|
this.componentInit( this.toggleClass );
|
|
|
|
this.addEvent();
|
|
this.conditionsHandleInit();
|
|
},
|
|
|
|
addEvent: function() {
|
|
$( 'body' )
|
|
.off( 'click.cxInterfaceBuilder' )
|
|
.on( 'click.cxInterfaceBuilder',
|
|
this.tabClass + ' ' + this.buttonClass + ', ' +
|
|
this.toggleClass + ' ' + this.buttonClass + ', ' +
|
|
this.accordionClass + ' ' + this.buttonClass,
|
|
|
|
this.componentClick.bind( this )
|
|
);
|
|
},
|
|
|
|
conditionsHandleInit: function() {
|
|
var self = this;
|
|
|
|
$( window ).on( 'cx-switcher-change', function( event ) {
|
|
var controlName = event.controlName,
|
|
controlStatus = event.controlStatus;
|
|
|
|
self.updateConditionRules( controlName, controlStatus );
|
|
self.renderConditionRules();
|
|
});
|
|
|
|
$( window ).on( 'cx-select-change', function( event ) {
|
|
var controlName = event.controlName,
|
|
controlStatus = event.controlStatus;
|
|
|
|
self.updateConditionRules( controlName, controlStatus );
|
|
self.renderConditionRules();
|
|
});
|
|
|
|
$( window ).on( 'cx-select2-change', function( event ) {
|
|
var controlName = event.controlName,
|
|
controlStatus = event.controlStatus;
|
|
|
|
self.updateConditionRules( controlName, controlStatus );
|
|
self.renderConditionRules();
|
|
});
|
|
|
|
$( window ).on( 'cx-radio-change', function( event ) {
|
|
var controlName = event.controlName,
|
|
controlStatus = event.controlStatus;
|
|
|
|
self.updateConditionRules( controlName, controlStatus );
|
|
self.renderConditionRules();
|
|
});
|
|
|
|
$( window ).on( 'cx-checkbox-change', function( event ) {
|
|
var controlName = event.controlName,
|
|
controlStatus = event.controlStatus,
|
|
updatedStatus = {};
|
|
|
|
$.each( controlStatus[ controlName ], function( checkbox, value ) {
|
|
updatedStatus[ checkbox ] = cxInterfaceBuilder.utils.filterBoolValue( value );
|
|
} );
|
|
|
|
self.updateConditionRules( controlName, updatedStatus );
|
|
self.renderConditionRules();
|
|
});
|
|
|
|
this.generateConditionRules();
|
|
self.renderConditionRules();
|
|
|
|
},
|
|
|
|
generateConditionRules: function() {
|
|
var self = this;
|
|
|
|
$.each( this.controlConditions, function( control, conditions ) {
|
|
$.each( conditions, function( control, value ) {
|
|
if ( self.controlValues.hasOwnProperty( control ) ) {
|
|
self.conditionState[ control ] = self.controlValues[ control ];
|
|
}
|
|
} );
|
|
} );
|
|
},
|
|
|
|
updateConditionRules: function( name, status ) {
|
|
this.conditionState[ name ] = status;
|
|
},
|
|
|
|
renderConditionRules: function() {
|
|
var self = this;
|
|
|
|
$.each( this.controlConditions, function( control, conditions ) {
|
|
var $selector = $( '.cx-control[data-control-name="' + control + '"]' ),
|
|
hidden = true;
|
|
|
|
$selector.addClass( 'cx-control-hidden' );
|
|
|
|
$.each( conditions, function( control, value ) {
|
|
hidden = true;
|
|
|
|
if ( self.conditionState.hasOwnProperty( control ) ) {
|
|
|
|
if ( self.conditionState[ control ] === value ) {
|
|
hidden = false;
|
|
}
|
|
|
|
if ( 'object' === typeof self.conditionState[ control ] ) {
|
|
hidden = false;
|
|
|
|
$.each( self.conditionState[ control ], function( prop, val ) {
|
|
|
|
if ( ! val && -1 !== value.indexOf( prop ) ) {
|
|
hidden = true;
|
|
|
|
return false;
|
|
}
|
|
} );
|
|
}
|
|
}
|
|
|
|
if ( hidden ) {
|
|
return false;
|
|
}
|
|
} );
|
|
|
|
if ( hidden ) {
|
|
$selector.addClass( 'cx-control-hidden' );
|
|
} else {
|
|
$selector.removeClass( 'cx-control-hidden' );
|
|
}
|
|
} );
|
|
},
|
|
|
|
componentInit: function( componentClass ) {
|
|
var _this = this,
|
|
components = $( componentClass ),
|
|
componentId = null,
|
|
button = null,
|
|
contentId = null,
|
|
notShow = '';
|
|
|
|
components.each( function( index, component ) {
|
|
component = $( component );
|
|
componentId = component.data( 'compotent-id' );
|
|
|
|
switch ( componentClass ) {
|
|
case _this.toggleClass:
|
|
if ( _this.localStorage[ componentId ] && _this.localStorage[ componentId ].length ) {
|
|
notShow = _this.localStorage[ componentId ].join( ', ' );
|
|
}
|
|
|
|
$( _this.contentClass, component )
|
|
.not( notShow )
|
|
.addClass( _this.showClass )
|
|
.prevAll( _this.buttonClass )
|
|
.addClass( _this.buttonActiveClass );
|
|
break;
|
|
|
|
case _this.tabClass:
|
|
case _this.accordionClass:
|
|
if ( _this.localStorage[ componentId ] ) {
|
|
contentId = _this.localStorage[ componentId ][ 0 ];
|
|
button = $( '[data-content-id="' + contentId + '"]', component );
|
|
} else {
|
|
button = $( _this.buttonClass, component ).eq( 0 );
|
|
contentId = button.data( 'content-id' );
|
|
}
|
|
|
|
_this.showElement( button, component, contentId );
|
|
break;
|
|
}
|
|
} );
|
|
},
|
|
|
|
componentClick: function( event ) {
|
|
var $target = $( event.target ),
|
|
$parent = $target.closest( this.tabClass + ', ' + this.accordionClass + ', ' + this.toggleClass ),
|
|
expr = new RegExp( this.tabClass + '|' + this.accordionClass + '|' + this.toggleClass ),
|
|
componentName = $parent[0].className.match( expr )[ 0 ].replace( ' ', '.' ),
|
|
contentId = $target.data( 'content-id' ),
|
|
componentId = $parent.data( 'compotent-id' ),
|
|
activeFlag = $target.hasClass( this.buttonActiveClass ),
|
|
itemClosed;
|
|
|
|
switch ( componentName ) {
|
|
case this.tabClass:
|
|
if ( ! activeFlag ) {
|
|
this.hideElement( $parent );
|
|
this.showElement( $target, $parent, contentId );
|
|
|
|
this.localStorage[ componentId ] = new Array( contentId );
|
|
this.setState();
|
|
}
|
|
break;
|
|
|
|
case this.accordionClass:
|
|
this.hideElement( $parent );
|
|
|
|
if ( ! activeFlag ) {
|
|
this.showElement( $target, $parent, contentId );
|
|
|
|
this.localStorage[ componentId ] = new Array( contentId );
|
|
} else {
|
|
this.localStorage[ componentId ] = {};
|
|
}
|
|
this.setState();
|
|
break;
|
|
|
|
case this.toggleClass:
|
|
$target
|
|
.toggleClass( this.buttonActiveClass )
|
|
.nextAll( contentId )
|
|
.toggleClass( this.showClass );
|
|
|
|
if ( Array.isArray( this.localStorage[ componentId ] ) ) {
|
|
itemClosed = this.localStorage[ componentId ].indexOf( contentId );
|
|
|
|
if ( -1 !== itemClosed ) {
|
|
this.localStorage[ componentId ].splice( itemClosed, 1 );
|
|
} else {
|
|
this.localStorage[ componentId ].push( contentId );
|
|
}
|
|
|
|
} else {
|
|
this.localStorage[ componentId ] = new Array( contentId );
|
|
}
|
|
|
|
this.setState();
|
|
break;
|
|
}
|
|
$target.blur();
|
|
|
|
return false;
|
|
},
|
|
|
|
showElement: function ( button, holder, contentId ) {
|
|
button
|
|
.addClass( this.buttonActiveClass );
|
|
|
|
holder
|
|
.data( 'content-id', contentId );
|
|
|
|
$( contentId, holder )
|
|
.addClass( this.showClass );
|
|
},
|
|
|
|
hideElement: function ( holder ) {
|
|
var contsntId = holder.data( 'content-id' );
|
|
|
|
$( '[data-content-id="' + contsntId + '"]', holder )
|
|
.removeClass( this.buttonActiveClass );
|
|
|
|
$( contsntId, holder )
|
|
.removeClass( this.showClass );
|
|
},
|
|
|
|
getState: function() {
|
|
try {
|
|
return JSON.parse( localStorage.getItem( 'interface-builder' ) );
|
|
} catch ( e ) {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
setState: function() {
|
|
try {
|
|
localStorage.setItem( 'interface-builder', JSON.stringify( this.localStorage ) );
|
|
} catch ( e ) {
|
|
return false;
|
|
}
|
|
}
|
|
},
|
|
|
|
control: {
|
|
init: function () {
|
|
this.switcher.init();
|
|
this.checkbox.init();
|
|
this.radio.init();
|
|
this.slider.init();
|
|
this.select.init();
|
|
this.media.init();
|
|
this.colorpicker.init();
|
|
this.iconpicker.init();
|
|
this.dimensions.init();
|
|
this.repeater.init();
|
|
},
|
|
|
|
// CX-Switcher
|
|
switcher: {
|
|
switcherClass: '.cx-switcher-wrap',
|
|
trueClass: '.cx-input-switcher-true',
|
|
falseClass: '.cx-input-switcher-false',
|
|
|
|
init: function() {
|
|
$( 'body' ).on( 'click.cxSwitcher', this.switcherClass, this.switchState.bind( this ) );
|
|
},
|
|
|
|
switchState: function( event ) {
|
|
var $this = $( event.currentTarget ),
|
|
$inputTrue = $( this.trueClass, $this ),
|
|
$inputFalse = $( this.falseClass, $this ),
|
|
status = $inputTrue[0].checked,
|
|
$parent = $( event.currentTarget ).closest( '.cx-control-switcher' ),
|
|
name = $parent.data( 'control-name' );
|
|
|
|
$inputTrue.prop( 'checked', ( status ) ? false : true );
|
|
$inputFalse.prop( 'checked', ( ! status ) ? false : true );
|
|
|
|
status = $inputTrue[0].checked;
|
|
|
|
$( window ).trigger( {
|
|
type: 'cx-switcher-change',
|
|
controlName: name,
|
|
controlStatus: status
|
|
} );
|
|
}
|
|
|
|
},//End CX-Switcher
|
|
|
|
// CX-Checkbox
|
|
checkbox: {
|
|
inputClass: '.cx-checkbox-input[type="hidden"]:not([name*="__i__"])',
|
|
itemClass: '.cx-checkbox-label, .cx-checkbox-item',
|
|
|
|
init: function() {
|
|
$( 'body' ).on( 'click.cxCheckbox', this.itemClass, this.switchState.bind( this ) );
|
|
},
|
|
|
|
switchState: function( event ) {
|
|
var $_input = $( event.currentTarget ).siblings( this.inputClass ),
|
|
status = $_input[0].checked,
|
|
$parent = $( event.currentTarget ).closest( '.cx-control-checkbox' ),
|
|
name = $parent.data( 'control-name' ),
|
|
statusData = {};
|
|
|
|
$_input.val( ! status ? 'true' : 'false' ).attr( 'checked', ! status ? true : false );
|
|
|
|
statusData = cxInterfaceBuilder.utils.serializeObject( $parent );
|
|
|
|
$( window ).trigger( {
|
|
type: 'cx-checkbox-change',
|
|
controlName: name,
|
|
controlStatus: statusData
|
|
} );
|
|
}
|
|
},//End CX-Checkbox
|
|
|
|
// CX-Radio
|
|
radio: {
|
|
inputClass: '.cx-radio-input:not([name*="__i__"])',
|
|
|
|
init: function() {
|
|
$( 'body' ).on( 'click.cxRadio', this.inputClass, this.switchState.bind( this ) );
|
|
},
|
|
|
|
switchState: function( event ) {
|
|
var $this = $( event.currentTarget ),
|
|
$parent = $( event.currentTarget ).closest( '.cx-control-radio' ),
|
|
name = $parent.data( 'control-name' );
|
|
|
|
$( window ).trigger( {
|
|
type: 'cx-radio-change',
|
|
controlName: name,
|
|
controlStatus: $( $this ).val()
|
|
} );
|
|
}
|
|
},//End CX-Radio
|
|
|
|
// CX-Slider
|
|
slider: {
|
|
init: function() {
|
|
$( 'body' ).on( 'input.cxSlider change.cxSlider', '.cx-slider-unit, .cx-ui-stepper-input', this.changeHandler.bind( this ) );
|
|
},
|
|
|
|
changeHandler: function( event ) {
|
|
var $this = $( event.currentTarget ),
|
|
$sliderWrapper = $this.closest( '.cx-slider-wrap' ),
|
|
targetClass = ( ! $this.hasClass( 'cx-slider-unit' ) ) ? '.cx-slider-unit' : '.cx-ui-stepper-input';
|
|
|
|
$( targetClass, $sliderWrapper ).val( $this.val() );
|
|
}
|
|
},//End CX-Slider
|
|
|
|
// CX-Select
|
|
select: {
|
|
selectClass: '.cx-ui-select[data-filter="false"]:not([name*="__i__"])',
|
|
select2Class: '.cx-ui-select[data-filter="true"]:not([name*="__i__"]), .cx-ui-select[multiple]:not([name*="__i__"])',
|
|
|
|
init: function() {
|
|
$( document )
|
|
.on( 'ready.cxSelect', this.selectRender.bind( this ) )
|
|
.on( 'cx-control-init', this.selectRender.bind( this ) );
|
|
},
|
|
|
|
selectRender: function( event ) {
|
|
var $target = ( event._target ) ? event._target : $( 'body' );
|
|
|
|
$( this.selectClass, $target ).each( this.selectInit.bind( this ) );
|
|
$( this.select2Class, $target ).each( this.select2Init.bind( this ) );
|
|
},
|
|
|
|
selectInit: function ( index, element ) {
|
|
var $this = $( element ),
|
|
name = $this.attr( 'id' );
|
|
|
|
$this.change( function( event ) {
|
|
$( window ).trigger( {
|
|
type: 'cx-select-change',
|
|
controlName: name,
|
|
controlStatus: $( event.target ).val()
|
|
} );
|
|
});
|
|
},
|
|
|
|
select2Init: function ( index, element ) {
|
|
var $this = $( element ),
|
|
name = $this.attr( 'id' );
|
|
|
|
$this.select2( {
|
|
placeholder: $this.data( 'placeholder' )
|
|
} ).on( 'change.cxSelect2', function( event ) {
|
|
$( window ).trigger( {
|
|
type: 'cx-select2-change',
|
|
controlName: name,
|
|
controlStatus: $( event.target ).val()
|
|
} );
|
|
} );
|
|
}
|
|
},//End CX-Select
|
|
|
|
// CX-Media
|
|
media: {
|
|
init: function() {
|
|
$( document )
|
|
.on( 'ready.cxMedia', this.mediaRender.bind( this ) )
|
|
.on( 'cx-control-init', this.mediaRender.bind( this ) );
|
|
},
|
|
|
|
mediaRender: function( event ) {
|
|
var target = ( event._target ) ? event._target : $( 'body' ),
|
|
$buttons = $( '.cx-upload-button', target );
|
|
|
|
$buttons.each( function() {
|
|
var button = $( this ),
|
|
buttonParent = button.closest('.cx-ui-media-wrap'),
|
|
settings = {
|
|
input: $( '.cx-upload-input', buttonParent ),
|
|
img_holder: $( '.cx-upload-preview', buttonParent ),
|
|
title_text: button.data('title'),
|
|
multiple: button.data('multi-upload'),
|
|
library_type: button.data('library-type'),
|
|
},
|
|
cx_uploader = wp.media.frames.file_frame = wp.media({
|
|
title: settings.title_text,
|
|
button: { text: settings.title_text },
|
|
multiple: settings.multiple,
|
|
library : { type : settings.library_type }
|
|
});
|
|
|
|
if ( ! buttonParent.has('input[name*="__i__"]')[ 0 ] ) {
|
|
button.off( 'click.cx-media' ).on( 'click.cx-media', function() {
|
|
cx_uploader.open();
|
|
return !1;
|
|
} ); // end click
|
|
|
|
cx_uploader.on('select', function() {
|
|
var attachment = cx_uploader.state().get( 'selection' ).toJSON(),
|
|
count = 0,
|
|
input_value = '',
|
|
new_img_object = $( '.cx-all-images-wrap', settings.img_holder ),
|
|
new_img = '',
|
|
delimiter = '';
|
|
|
|
if ( settings.multiple ) {
|
|
input_value = settings.input.val();
|
|
delimiter = ',';
|
|
new_img = new_img_object.html();
|
|
}
|
|
|
|
while( attachment[ count ] ) {
|
|
var img_data = attachment[ count ],
|
|
return_data = img_data.id,
|
|
mimeType = img_data.mime,
|
|
img_src = '',
|
|
thumb = '';
|
|
|
|
switch (mimeType) {
|
|
case 'image/jpeg':
|
|
case 'image/png':
|
|
case 'image/gif':
|
|
if ( img_data.sizes !== undefined ) {
|
|
img_src = img_data.sizes.thumbnail ? img_data.sizes.thumbnail.url : img_data.sizes.full.url;
|
|
}
|
|
thumb = '<img src="' + img_src + '" alt="" data-img-attr="' + return_data + '">';
|
|
break;
|
|
case 'image/x-icon':
|
|
thumb = '<span class="dashicons dashicons-format-image"></span>';
|
|
break;
|
|
case 'video/mpeg':
|
|
case 'video/mp4':
|
|
case 'video/quicktime':
|
|
case 'video/webm':
|
|
case 'video/ogg':
|
|
thumb = '<span class="dashicons dashicons-format-video"></span>';
|
|
break;
|
|
case 'audio/mpeg':
|
|
case 'audio/wav':
|
|
case 'audio/ogg':
|
|
thumb = '<span class="dashicons dashicons-format-audio"></span>';
|
|
break;
|
|
}
|
|
|
|
new_img += '<div class="cx-image-wrap">'+
|
|
'<div class="inner">'+
|
|
'<div class="preview-holder" data-id-attr="' + return_data +'"><div class="centered">' + thumb + '</div></div>'+
|
|
'<a class="cx-remove-image" href="#"><i class="dashicons dashicons-no"></i></a>'+
|
|
'<span class="title">' + img_data.title + '</span>'+
|
|
'</div>'+
|
|
'</div>';
|
|
|
|
input_value += delimiter + return_data;
|
|
count++;
|
|
}
|
|
|
|
settings.input.val( input_value.replace( /(^,)/, '' ) ).trigger( 'change' );
|
|
new_img_object.html( new_img );
|
|
} );
|
|
|
|
var removeMediaPreview = function( item ) {
|
|
var buttonParent = item.closest( '.cx-ui-media-wrap' ),
|
|
input = $( '.cx-upload-input', buttonParent ),
|
|
img_holder = item.parent().parent( '.cx-image-wrap' ),
|
|
img_attr = $( '.preview-holder', img_holder ).data( 'id-attr' ),
|
|
input_value = input.attr( 'value' ),
|
|
pattern = new RegExp( img_attr + '(,*)', 'i' );
|
|
|
|
input_value = input_value.replace( pattern, '' );
|
|
input_value = input_value.replace( /(,$)/, '' );
|
|
input.attr( { 'value': input_value } ).trigger( 'change' );
|
|
img_holder.remove();
|
|
};
|
|
|
|
// This function remove upload image
|
|
buttonParent.on( 'click', '.cx-remove-image', function () {
|
|
removeMediaPreview( $( this ) );
|
|
return !1;
|
|
});
|
|
}
|
|
} ); // end each
|
|
|
|
// Image ordering
|
|
if ( $buttons[0] ) {
|
|
$('.cx-all-images-wrap', target).sortable( {
|
|
items: 'div.cx-image-wrap',
|
|
cursor: 'move',
|
|
scrollSensitivity: 40,
|
|
forcePlaceholderSize: true,
|
|
forceHelperSize: false,
|
|
helper: 'clone',
|
|
opacity: 0.65,
|
|
placeholder: 'cx-media-thumb-sortable-placeholder',
|
|
start:function(){},
|
|
stop:function(){},
|
|
update: function() {
|
|
var attachment_ids = '';
|
|
|
|
$('.cx-image-wrap', this).each(
|
|
function() {
|
|
var attachment_id = $('.preview-holder', this).data( 'id-attr' );
|
|
attachment_ids = attachment_ids + attachment_id + ',';
|
|
}
|
|
);
|
|
|
|
attachment_ids = attachment_ids.substr(0, attachment_ids.lastIndexOf(',') );
|
|
$(this).parent().siblings('.cx-element-wrap').find('input.cx-upload-input').val( attachment_ids ).trigger( 'change' );
|
|
}
|
|
} );
|
|
}
|
|
}
|
|
},//End CX-Media
|
|
|
|
// CX-Colorpicker
|
|
colorpicker: {
|
|
init: function() {
|
|
$( document )
|
|
.on( 'ready.cxColorpicker', this.render.bind( this ) )
|
|
.on( 'cx-control-init', this.render.bind( this ) );
|
|
},
|
|
|
|
render: function( event ) {
|
|
var target = ( event._target ) ? event._target : $( 'body' ),
|
|
input = $( 'input.cx-ui-colorpicker:not([name*="__i__"])', target );
|
|
|
|
if ( input[0] ) {
|
|
input.wpColorPicker();
|
|
}
|
|
}
|
|
},//End CX-Colorpicker
|
|
|
|
// CX-Iconpicker
|
|
iconpicker: {
|
|
iconSets: {},
|
|
iconSetsKey: 'cx-icon-sets',
|
|
|
|
init: function() {
|
|
$( document )
|
|
.on( 'ready.cxIconpicker', this.setIconsSets.bind( this, window.CxIconSets ) )
|
|
.on( 'ready.cxIconpicker', this.render.bind( this ) )
|
|
.on( 'cx-control-init', this.render.bind( this ) );
|
|
},
|
|
|
|
setIconsSets: function( iconSets ) {
|
|
var icons,
|
|
_this = this;
|
|
|
|
if ( iconSets ) {
|
|
icons = ( iconSets.response ) ? iconSets.response.CxIconSets : iconSets;
|
|
|
|
$.each( icons, function( name, data ) {
|
|
_this.iconSets[name] = data;
|
|
} );
|
|
|
|
_this.setState( _this.iconSetsKey, _this.iconSets );
|
|
}
|
|
},
|
|
|
|
getIconsSets: function() {
|
|
var iconSets = this.getState( this.iconSetsKey );
|
|
|
|
if ( iconSets ) {
|
|
this.iconSets = iconSets;
|
|
}
|
|
},
|
|
|
|
render: function( event ) {
|
|
var target = ( event._target ) ? event._target : $( 'body' ),
|
|
$picker = $( '.cx-ui-iconpicker:not([name*="__i__"])', target ),
|
|
$this,
|
|
set,
|
|
setData,
|
|
_this = this;
|
|
|
|
if ( $picker[0] ) {
|
|
this.getIconsSets();
|
|
|
|
$picker.each( function() {
|
|
$this = $( this );
|
|
set = $this.data( 'set' );
|
|
setData = _this.iconSets[set];
|
|
|
|
if ( $this.length && setData.icons ) {
|
|
$this.iconpicker({
|
|
icons: setData.icons,
|
|
iconBaseClass: setData.iconBase,
|
|
iconClassPrefix: setData.iconPrefix,
|
|
animation: false,
|
|
fullClassFormatter: function( val ) {
|
|
return setData.iconBase + ' ' + setData.iconPrefix + val;
|
|
}
|
|
}).on( 'iconpickerUpdated', function() {
|
|
$( this ).trigger( 'change' );
|
|
});
|
|
}
|
|
|
|
if ( setData ) {
|
|
$( 'head' ).append( '<link rel="stylesheet" type="text/css" href="' + setData.iconCSS + '"">' );
|
|
}
|
|
} );
|
|
}
|
|
},
|
|
|
|
getState: function( key ) {
|
|
try {
|
|
return JSON.parse( window.sessionStorage.getItem( key ) );
|
|
} catch ( e ) {
|
|
return false;
|
|
}
|
|
},
|
|
|
|
setState: function( key, data ) {
|
|
try {
|
|
window.sessionStorage.setItem( key, JSON.stringify( data ) );
|
|
} catch ( e ) {
|
|
return false;
|
|
}
|
|
}
|
|
},//End CX-Iconpicker
|
|
|
|
// CX-Dimensions
|
|
dimensions: {
|
|
container: '.cx-ui-dimensions',
|
|
isLinked: '.cx-ui-dimensions__is-linked',
|
|
units: '.cx-ui-dimensions__unit',
|
|
unitsInput: 'input[name*="[units]"]',
|
|
linkedInput: 'input[name*="[is_linked]"]',
|
|
valuesInput: '.cx-ui-dimensions__val',
|
|
|
|
init: function() {
|
|
$( 'body' )
|
|
.on( 'click', this.isLinked, { 'self': this }, this.switchLinked )
|
|
.on( 'click', this.units, { 'self': this }, this.switchUnits )
|
|
.on( 'input', this.valuesInput + '.is-linked', { 'self': this }, this.changeLinked );
|
|
},
|
|
|
|
render: function( event ) {
|
|
|
|
},
|
|
|
|
switchLinked: function( event ) {
|
|
|
|
var self = event.data.self,
|
|
$this = $( this ),
|
|
$container = $this.closest( self.container ),
|
|
$input = $container.find( self.linkedInput ),
|
|
$values = $container.find( self.valuesInput ),
|
|
isLinked = $input.val();
|
|
|
|
if ( 0 === parseInt( isLinked ) ) {
|
|
$input.val(1);
|
|
$this.addClass( 'is-linked' );
|
|
$values.addClass( 'is-linked' );
|
|
} else {
|
|
$input.val(0);
|
|
$this.removeClass( 'is-linked' );
|
|
$values.removeClass( 'is-linked' );
|
|
}
|
|
|
|
},
|
|
|
|
switchUnits: function( event ) {
|
|
var self = event.data.self,
|
|
$this = $( this ),
|
|
unit = $this.data( 'unit' ),
|
|
$container = $this.closest( self.container ),
|
|
$input = $container.find( self.unitsInput ),
|
|
$values = $container.find( self.valuesInput ),
|
|
range = $container.data( 'range' );
|
|
|
|
if ( $this.hasClass( 'is-active' ) ) {
|
|
return;
|
|
}
|
|
|
|
$this.addClass( 'is-active' ).siblings( self.units ).removeClass( 'is-active' );
|
|
$input.val( unit );
|
|
$values.attr({
|
|
min: range[ unit ].min,
|
|
max: range[ unit ].max,
|
|
step: range[ unit ].step
|
|
});
|
|
|
|
},
|
|
|
|
changeLinked: function( event ) {
|
|
var self = event.data.self,
|
|
$this = $( this ),
|
|
$container = $this.closest( '.cx-ui-dimensions__values' );
|
|
|
|
$( self.valuesInput, $container ).val( $this.val() )
|
|
}
|
|
},//End CX-Dimensions
|
|
|
|
// CX-Repeater
|
|
repeater: {
|
|
repeaterContainerClass: '.cx-ui-repeater-container',
|
|
repeaterListClass: '.cx-ui-repeater-list',
|
|
repeaterItemClass: '.cx-ui-repeater-item',
|
|
repeaterItemHandleClass: '.cx-ui-repeater-actions-box',
|
|
repeaterTitleClass: '.cx-ui-repeater-title',
|
|
addItemButtonClass: '.cx-ui-repeater-add',
|
|
removeItemButtonClass: '.cx-ui-repeater-remove',
|
|
toggleItemButtonClass: '.cx-ui-repeater-toggle',
|
|
minItemClass: 'cx-ui-repeater-min',
|
|
sortablePlaceholderClass: 'sortable-placeholder',
|
|
|
|
init: function() {
|
|
$( document ).on( 'ready.cxRepeat', this.addEvents.bind( this ) );
|
|
},
|
|
|
|
addEvents: function() {
|
|
$( 'body' )
|
|
.on( 'click', this.addItemButtonClass, { 'self': this }, this.addItem )
|
|
.on( 'click', this.removeItemButtonClass, { 'self': this }, this.removeItem )
|
|
.on( 'click', this.toggleItemButtonClass, { 'self': this }, this.toggleItem )
|
|
.on( 'change', this.repeaterListClass + ' input, ' + this.repeaterListClass + ' textarea, ' + this.repeaterListClass + ' select', { 'self': this }, this.changeWrapperLable )
|
|
.on( 'sortable-init', { 'self': this }, this.sortableItem );
|
|
|
|
$( document )
|
|
.on( 'cx-control-init', { 'self': this }, this.sortableItem );
|
|
|
|
this.triggers();
|
|
},
|
|
|
|
triggers: function( $target ) {
|
|
$( 'body' ).trigger( 'sortable-init' );
|
|
|
|
if ( $target ) {
|
|
$( document ).trigger( 'cx-control-init', { 'target': $target } );
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
addItem: function( event ) {
|
|
var self = event.data.self,
|
|
$list = $( this ).prev( self.repeaterListClass ),
|
|
index = $list.data( 'index' ),
|
|
tmplName = $list.data( 'name' ),
|
|
rowTemplate = wp.template( tmplName ),
|
|
widgetId = $list.data( 'widget-id' ),
|
|
data = { index: index },
|
|
$parent = $list.parent().closest( self.repeaterListClass );
|
|
|
|
widgetId = '__i__' !== widgetId ? widgetId : $list.attr( 'id' ) ;
|
|
|
|
if ( widgetId ) {
|
|
data.widgetId = widgetId;
|
|
}
|
|
|
|
if ( $parent.length ) {
|
|
data.parentIndex = parseInt( $parent.data( 'index' ), 10 ) - 1;
|
|
}
|
|
|
|
$list.append( rowTemplate( data ) );
|
|
|
|
index++;
|
|
$list.data( 'index', index );
|
|
|
|
self.triggers( $( self.repeaterItemClass + ':last', $list ) ).stopDefaultEvent( event );
|
|
},
|
|
|
|
removeItem: function( event ) {
|
|
var self = event.data.self,
|
|
$list = $( this ).closest( self.repeaterListClass );
|
|
|
|
self.applyChanges( $list );
|
|
|
|
$( this ).closest( self.repeaterItemClass ).remove();
|
|
|
|
self
|
|
.triggers()
|
|
.stopDefaultEvent( event );
|
|
},
|
|
|
|
toggleItem: function( event ) {
|
|
var self = event.data.self,
|
|
$container = $( this ).closest( self.repeaterItemClass );
|
|
|
|
$container.toggleClass( self.minItemClass );
|
|
|
|
self.stopDefaultEvent( event );
|
|
},
|
|
|
|
sortableItem: function( event ) {
|
|
var self = event.data.self,
|
|
$list = $( self.repeaterListClass ),
|
|
$this,
|
|
initFlag;
|
|
|
|
$list.each( function( indx, element ) {
|
|
$this = $( element );
|
|
initFlag = $( element ).data( 'sortable-init' );
|
|
|
|
if ( ! initFlag ) {
|
|
$this.sortable( {
|
|
items: self.repeaterItemClass,
|
|
handle: self.repeaterItemHandleClass,
|
|
cursor: 'move',
|
|
scrollSensitivity: 40,
|
|
forcePlaceholderSize: true,
|
|
forceHelperSize: false,
|
|
distance: 2,
|
|
tolerance: 'pointer',
|
|
helper: function( event, element ) {
|
|
return element.clone()
|
|
.find( ':input' )
|
|
.attr( 'name', function( i, currentName ) {
|
|
return 'sort_' + parseInt( Math.random() * 100000, 10 ).toString() + '_' + currentName;
|
|
} )
|
|
.end();
|
|
},
|
|
opacity: 0.65,
|
|
placeholder: self.sortablePlaceholderClass,
|
|
create: function() {
|
|
$this.data( 'sortable-init', true );
|
|
},
|
|
update: function( event ) {
|
|
var target = $( event.target );
|
|
|
|
self.applyChanges( target );
|
|
}
|
|
} );
|
|
} else {
|
|
$this.sortable( 'refresh' );
|
|
}
|
|
} );
|
|
},
|
|
|
|
changeWrapperLable: function( event ) {
|
|
var self = event.data.self,
|
|
$list = $( self.repeaterListClass ),
|
|
titleFilds = $list.data( 'title-field' ),
|
|
$this = $( this ),
|
|
value,
|
|
parentItem;
|
|
|
|
if ( titleFilds && $this.closest( '.' + titleFilds + '-wrap' )[0] ) {
|
|
value = $this.val(),
|
|
parentItem = $this.closest( self.repeaterItemClass );
|
|
|
|
$( self.repeaterTitleClass, parentItem ).html( value );
|
|
}
|
|
|
|
self.stopDefaultEvent( event );
|
|
},
|
|
|
|
applyChanges: function( target ) {
|
|
if ( undefined !== wp.customize ) {
|
|
$( 'input[name]:first, select[name]:first', target ).change();
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
stopDefaultEvent: function( event ) {
|
|
event.preventDefault();
|
|
event.stopImmediatePropagation();
|
|
event.stopPropagation();
|
|
|
|
return this;
|
|
}
|
|
|
|
}
|
|
},
|
|
|
|
utils: {
|
|
|
|
/**
|
|
* Serialize form into
|
|
*
|
|
* @return {Object}
|
|
*/
|
|
serializeObject: function( selector ) {
|
|
|
|
var self = this,
|
|
json = {},
|
|
pushCounters = {},
|
|
patterns = {
|
|
'validate': /^[a-zA-Z][a-zA-Z0-9_-]*(?:\[(?:\d*|[a-zA-Z0-9_-]+)\])*$/,
|
|
'key': /[a-zA-Z0-9_-]+|(?=\[\])/g,
|
|
'push': /^$/,
|
|
'fixed': /^\d+$/,
|
|
'named': /^[a-zA-Z0-9_-]+$/
|
|
},
|
|
serialized;
|
|
|
|
this.build = function( base, key, value ) {
|
|
base[ key ] = value;
|
|
|
|
return base;
|
|
};
|
|
|
|
this.push_counter = function( key ) {
|
|
if ( undefined === pushCounters[ key ] ) {
|
|
pushCounters[ key ] = 0;
|
|
}
|
|
|
|
return pushCounters[ key ]++;
|
|
};
|
|
|
|
if ( 'FORM' === selector[0].tagName ) {
|
|
serialized = selector.serializeArray();
|
|
} else {
|
|
serialized = selector.find( 'input, textarea, select' ).serializeArray();
|
|
}
|
|
|
|
$.each( serialized, function() {
|
|
var k, keys, merge, reverseKey;
|
|
|
|
// Skip invalid keys
|
|
if ( ! patterns.validate.test( this.name ) ) {
|
|
return;
|
|
}
|
|
|
|
keys = this.name.match( patterns.key );
|
|
merge = this.value;
|
|
reverseKey = this.name;
|
|
|
|
while ( undefined !== ( k = keys.pop() ) ) {
|
|
|
|
// Adjust reverseKey
|
|
reverseKey = reverseKey.replace( new RegExp( '\\[' + k + '\\]$' ), '' );
|
|
|
|
// Push
|
|
if ( k.match( patterns.push ) ) {
|
|
merge = self.build( [], self.push_counter( reverseKey ), merge );
|
|
} else if ( k.match( patterns.fixed ) ) {
|
|
merge = self.build( [], k, merge );
|
|
} else if ( k.match( patterns.named ) ) {
|
|
merge = self.build( {}, k, merge );
|
|
}
|
|
}
|
|
|
|
json = $.extend( true, json, merge );
|
|
});
|
|
|
|
return json;
|
|
},
|
|
|
|
/**
|
|
* Boolean value check
|
|
*
|
|
* @return {Boolean}
|
|
*/
|
|
filterBoolValue: function( value ) {
|
|
var num = +value;
|
|
|
|
return ! isNaN( num ) ? !! num : !! String( value ).toLowerCase().replace( !!0, '' );
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
cxInterfaceBuilder.init();
|
|
|
|
}( jQuery, window._ ) );
|