(function($, undefined){ // vars var CONTEXT = 'tab'; var Field = acf.Field.extend({ type: 'tab', wait: '', tabs: false, tab: false, findFields: function(){ return this.$el.nextUntil('.acf-field-tab', '.acf-field'); }, getFields: function(){ return acf.getFields( this.findFields() ); }, findTabs: function(){ return this.$el.prevAll('.acf-tab-wrap:first'); }, findTab: function(){ return this.$('.acf-tab-button'); }, initialize: function(){ // bail early if is td if( this.$el.is('td') ) { this.events = {}; return false; } // vars var $tabs = this.findTabs(); var $tab = this.findTab(); var settings = acf.parseArgs($tab.data(), { endpoint: false, placement: '', before: this.$el }); // create wrap if( !$tabs.length || settings.endpoint ) { this.tabs = new Tabs( settings ); } else { this.tabs = $tabs.data('acf'); } // add tab this.tab = this.tabs.addTab($tab, this); }, isActive: function(){ return this.tab.isActive(); }, showFields: function(){ // show fields this.getFields().map(function( field ){ field.show( this.cid, CONTEXT ); field.hiddenByTab = false; }, this); }, hideFields: function(){ // hide fields this.getFields().map(function( field ){ field.hide( this.cid, CONTEXT ); field.hiddenByTab = this.tab; }, this); }, show: function( lockKey ){ // show field and store result var visible = acf.Field.prototype.show.apply(this, arguments); // check if now visible if( visible ) { // show tab this.tab.show(); // check active tabs this.tabs.refresh(); } // return return visible; }, hide: function( lockKey ){ // hide field and store result var hidden = acf.Field.prototype.hide.apply(this, arguments); // check if now hidden if( hidden ) { // hide tab this.tab.hide(); // reset tabs if this was active if( this.isActive() ) { this.tabs.reset(); } } // return return hidden; }, enable: function( lockKey ){ // enable fields this.getFields().map(function( field ){ field.enable( CONTEXT ); }); }, disable: function( lockKey ){ // disable fields this.getFields().map(function( field ){ field.disable( CONTEXT ); }); } }); acf.registerFieldType( Field ); /** * tabs * * description * * @date 8/2/18 * @since 5.6.5 * * @param type $var Description. Default. * @return type Description. */ var i = 0; var Tabs = acf.Model.extend({ tabs: [], active: false, actions: { 'refresh': 'onRefresh' }, data: { before: false, placement: 'top', index: 0, initialized: false, }, setup: function( settings ){ // data $.extend(this.data, settings); // define this prop to avoid scope issues this.tabs = []; this.active = false; // vars var placement = this.get('placement'); var $before = this.get('before'); var $parent = $before.parent(); // add sidebar for left placement if( placement == 'left' && $parent.hasClass('acf-fields') ) { $parent.addClass('-sidebar'); } // create wrap if( $before.is('tr') ) { this.$el = $(''); } else { this.$el = $('
'); } // append $before.before( this.$el ); // set index this.set('index', i, true); i++; }, initializeTabs: function(){ // find first visible tab var tab = this.getVisible().shift(); // remember previous tab state var order = acf.getPreference('this.tabs') || []; var groupIndex = this.get('index'); var tabIndex = order[ groupIndex ]; if( this.tabs[ tabIndex ] && this.tabs[ tabIndex ].isVisible() ) { tab = this.tabs[ tabIndex ]; } // select if( tab ) { this.selectTab( tab ); } else { this.closeTabs(); } // set local variable used by tabsManager this.set('initialized', true); }, getVisible: function(){ return this.tabs.filter(function( tab ){ return tab.isVisible(); }); }, getActive: function(){ return this.active; }, setActive: function( tab ){ return this.active = tab; }, hasActive: function(){ return (this.active !== false); }, isActive: function( tab ){ var active = this.getActive(); return (active && active.cid === tab.cid); }, closeActive: function(){ if( this.hasActive() ) { this.closeTab( this.getActive() ); } }, openTab: function( tab ){ // close existing tab this.closeActive(); // open tab.open(); // set active this.setActive( tab ); }, closeTab: function( tab ){ // close tab.close(); // set active this.setActive( false ); }, closeTabs: function(){ this.tabs.map( this.closeTab, this ); }, selectTab: function( tab ){ // close other tabs this.tabs.map(function( t ){ if( tab.cid !== t.cid ) { this.closeTab( t ); } }, this); // open this.openTab( tab ); }, addTab: function( $a, field ){ // create
  • var $li = $('
  • '); // append $li.append( $a ); // append this.$('ul').append( $li ); // initialize var tab = new Tab({ $el: $li, field: field, group: this, }); // store this.tabs.push( tab ); // return return tab; }, reset: function(){ // close existing tab this.closeActive(); // find and active a tab return this.refresh(); }, refresh: function(){ // bail early if active already exists if( this.hasActive() ) { return false; } // find next active tab var tab = this.getVisible().shift(); // open tab if( tab ) { this.openTab( tab ); } // return return tab; }, onRefresh: function(){ // only for left placements if( this.get('placement') !== 'left' ) { return; } // vars var $parent = this.$el.parent(); var $list = this.$el.children('ul'); var attribute = $parent.is('td') ? 'height' : 'min-height'; // find height (minus 1 for border-bottom) var height = $list.position().top + $list.outerHeight(true) - 1; // add css $parent.css(attribute, height); } }); var Tab = acf.Model.extend({ group: false, field: false, events: { 'click a': 'onClick' }, index: function(){ return this.$el.index(); }, isVisible: function(){ return acf.isVisible( this.$el ); }, isActive: function(){ return this.$el.hasClass('active'); }, open: function(){ // add class this.$el.addClass('active'); // show field this.field.showFields(); }, close: function(){ // remove class this.$el.removeClass('active'); // hide field this.field.hideFields(); }, onClick: function( e, $el ){ // prevent default e.preventDefault(); // toggle this.toggle(); }, toggle: function(){ // bail early if already active if( this.isActive() ) { return; } // toggle this tab this.group.openTab( this ); } }); var tabsManager = new acf.Model({ priority: 50, actions: { 'prepare': 'render', 'append': 'render', 'unload': 'onUnload', 'invalid_field': 'onInvalidField' }, findTabs: function(){ return $('.acf-tab-wrap'); }, getTabs: function(){ return acf.getInstances( this.findTabs() ); }, render: function( $el ){ this.getTabs().map(function( tabs ){ if( !tabs.get('initialized') ) { tabs.initializeTabs(); } }); }, onInvalidField: function( field ){ // bail early if busy if( this.busy ) { return; } // ignore if not hidden by tab if( !field.hiddenByTab ) { return; } // toggle tab field.hiddenByTab.toggle(); // ignore other invalid fields this.busy = true; this.setTimeout(function(){ this.busy = false; }, 100); }, onUnload: function(){ // vars var order = []; // loop this.getTabs().map(function( group ){ var active = group.hasActive() ? group.getActive().index() : 0; order.push(active); }); // bail if no tabs if( !order.length ) { return; } // update acf.setPreference('this.tabs', order); } }); })(jQuery);