/** * 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 = ''; break; case 'image/x-icon': thumb = ''; break; case 'video/mpeg': case 'video/mp4': case 'video/quicktime': case 'video/webm': case 'video/ogg': thumb = ''; break; case 'audio/mpeg': case 'audio/wav': case 'audio/ogg': thumb = ''; break; } new_img += '
'+ '
'+ '
' + thumb + '
'+ ''+ '' + img_data.title + ''+ '
'+ '
'; 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( '' ); } } ); } }, 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._ ) );