diff options
Diffstat (limited to 'ui/jquery.ui.tabs.js')
-rwxr-xr-x | ui/jquery.ui.tabs.js | 239 |
1 files changed, 134 insertions, 105 deletions
diff --git a/ui/jquery.ui.tabs.js b/ui/jquery.ui.tabs.js index 699c1a5ee..7946cc667 100755 --- a/ui/jquery.ui.tabs.js +++ b/ui/jquery.ui.tabs.js @@ -26,13 +26,15 @@ function getNextListId() { $.widget( "ui.tabs", { options: { - activate: null, active: null, - beforeActivate: null, - beforeLoad: null, collapsible: false, event: "click", fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 } + + // callbacks + activate: null, + beforeActivate: null, + beforeLoad: null, load: null }, @@ -79,7 +81,7 @@ $.widget( "ui.tabs", { options.active = active; // don't allow collapsible: false and active: false - if ( !options.collapsible && options.active === false ) { + if ( !options.collapsible && options.active === false && this.anchors.length ) { options.active = 0; } @@ -128,13 +130,26 @@ $.widget( "ui.tabs", { return; } + if ( key === "disabled" ) { + // don't use the widget factory's disabled handling + this._setupDisabled( value ); + return; + } + + this._super( "_setOption", key, value); + // setting collapsible: false while collapsed; open first panel if ( key === "collapsible" && !value && this.options.active === false ) { this._activate( 0 ); } - this.options[ key ] = value; - this.refresh(); + if ( key === "event" ) { + this._setupEvents( value ); + } + + if ( key === "fx" ) { + this._setupFx( value ); + } }, _tabId: function( a ) { @@ -155,39 +170,45 @@ $.widget( "ui.tabs", { }, refresh: function() { - var self = this; + var self = this, + options = this.options, + lis = this.list.children( ":has(a[href])" ); - this._processTabs(); + // get disabled tabs from class attribute from HTML + // this will get converted to a boolean if needed in _refresh() + options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) { + return lis.index( tab ); + }); + this._processTabs(); this._refresh(); + this.panels.not( this._getPanelForTab( this.active ) ).hide(); - // Remove panels that we created that are missing their tab - this.element.find(".ui-tabs-panel:data(destroy.tabs)").each( function( index, panel ) { - var anchor = self.anchors.filter( "[aria-controls='" + panel.id + "']"); - if ( !anchor.length ) { - $( panel ).remove(); - } - }); + // was collapsed or no tabs + if ( options.active === false || !this.anchors.length ) { + options.active = false; + this.active = $(); + // was active, but active tab is gone + } else if ( this.active.length && !$.contains( this.list[ 0 ], this.active[ 0 ] ) ) { + // activate previous tab + var next = options.active - 1; + this._activate( next >= 0 ? next : 0 ); + // was active, active tab still exists + } else { + // make sure active index is correct + options.active = this.anchors.index( this.active ); + } }, _refresh: function() { - var that = this, - options = that.options; + var options = this.options; this.element.toggleClass( "ui-tabs-collapsible", options.collapsible ); - this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); + this.list.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" ); this.lis.addClass( "ui-state-default ui-corner-top" ); this.panels.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ); - if ( !options.disabled.length ) { - options.disabled = false; - } - - // disable tabs - for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) { - $( li ).toggleClass( "ui-state-disabled", $.inArray( i, options.disabled ) !== -1 ); - } - + this._setupDisabled( options.disabled ); this._setupEvents( options.event ); // remove all handlers, may run on existing tabs @@ -258,6 +279,23 @@ $.widget( "ui.tabs", { .data( "destroy.tabs", true ); }, + _setupDisabled: function( disabled ) { + if ( $.isArray( disabled ) ) { + if ( !disabled.length ) { + disabled = false; + } else if ( disabled.length === this.anchors.length ) { + disabled = true; + } + } + + // disable tabs + for ( var i = 0, li; ( li = this.lis[ i ] ); i++ ) { + $( li ).toggleClass( "ui-state-disabled", ( disabled === true || $.inArray( i, disabled ) !== -1 ) ); + } + + this.options.disabled = disabled; + }, + _setupFx: function( fx ) { // set up animations if ( fx ) { @@ -500,53 +538,48 @@ $.widget( "ui.tabs", { }, enable: function( index ) { - if ( index === undefined ) { - for ( var i = 0, len = this.lis.length; i < len; i++ ) { - this.enable( i ); - } - return this; - } - index = this._getIndex( index ); - var o = this.options; - if ( !o.disabled || ($.isArray( o.disabled ) && $.inArray( index, o.disabled ) == -1 ) ) { + var disabled = this.options.disabled; + if ( disabled === false ) { return; } - this.lis.eq( index ).removeClass( "ui-state-disabled" ); - o.disabled = this.lis.map( function( i ) { - return $(this).is( ".ui-state-disabled" ) ? i : null; - }).get(); - - if ( !o.disabled.length ) { - o.disabled = false; + if ( index === undefined ) { + disabled = false; + } else { + index = this._getIndex( index ); + if ( $.isArray( disabled ) ) { + disabled = $.map( disabled, function( num ) { + return num !== index ? num : null; + }); + } else { + disabled = $.map( this.lis, function( li, num ) { + return num !== index ? num : null; + }); + } } - - return this; + this._setupDisabled( disabled ); }, disable: function( index ) { + var disabled = this.options.disabled; + if ( disabled === true ) { + return; + } + if ( index === undefined ) { - for ( var i = 0, len = this.lis.length; i < len; i++ ) { - this.disable( i ); + disabled = true; + } else { + index = this._getIndex( index ); + if ( $.inArray( index, disabled ) !== -1 ) { + return; } - return this; - } - index = this._getIndex( index ); - var o = this.options; - if ( !o.disabled || ($.isArray( o.disabled ) && $.inArray( index, o.disabled ) == -1 ) ) { - this.lis.eq( index ).addClass( "ui-state-disabled" ); - - o.disabled = this.lis.map( function( i ) { - return $(this).is( ".ui-state-disabled" ) ? i : null; - }).get(); - - if ( o.disabled.length === this.anchors.length ) { - o.disabled = true; + if ( $.isArray( disabled ) ) { + disabled = $.merge( [ index ], disabled ).sort(); + } else { + disabled = [ index ]; } - } - - return this; + this._setupDisabled( disabled ); }, load: function( index, event ) { @@ -626,6 +659,14 @@ $.extend( $.ui.tabs, { // DEPRECATED if ( $.uiBackCompat !== false ) { + + // url method + (function( $, prototype ) { + prototype.url = function( index, url ) { + this.anchors.eq( index ).attr( "href", url ); + }; + }( jQuery, jQuery.ui.tabs.prototype ) ); + // ajaxOptions and cache options (function( $, prototype ) { $.extend( prototype.options, { @@ -636,7 +677,7 @@ if ( $.uiBackCompat !== false ) { var _create = prototype._create, _setOption = prototype._setOption, _destroy = prototype._destroy, - oldurl = prototype._url; + oldurl = prototype.url || $.noop; $.extend( prototype, { _create: function() { @@ -785,43 +826,38 @@ if ( $.uiBackCompat !== false ) { index = this.anchors.length; } - var self = this, - o = this.options, - $li = $( o.tabTemplate.replace( /#\{href\}/g, url ).replace( /#\{label\}/g, label ) ), - id = !url.indexOf( "#" ) ? url.replace( "#", "" ) : this._tabId( $( "a", $li )[ 0 ] ); + var options = this.options, + li = $( options.tabTemplate + .replace( /#\{href\}/g, url ) + .replace( /#\{label\}/g, label ) ), + id = !url.indexOf( "#" ) ? + url.replace( "#", "" ) : + this._tabId( li.find( "a" )[ 0 ] ); - $li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true ); + li.addClass( "ui-state-default ui-corner-top" ).data( "destroy.tabs", true ); + li.find( "a" ).attr( "aria-controls", id ); // try to find an existing element before creating a new one - var $panel = self.element.find( "#" + id ); - if ( !$panel.length ) { - $panel = self._createPanel( id ); + var panel = this.element.find( "#" + id ); + if ( !panel.length ) { + panel = this._createPanel( id ); } - $panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide(); + panel.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" ).hide(); if ( index >= this.lis.length ) { - $li.appendTo( this.list ); - $panel.appendTo( this.list[ 0 ].parentNode ); + li.appendTo( this.list ); + panel.appendTo( this.list[ 0 ].parentNode ); } else { - $li.insertBefore( this.lis[ index ] ); - $panel.insertBefore( this.panels[ index ] ); + li.insertBefore( this.lis[ index ] ); + panel.insertBefore( this.panels[ index ] ); } - - o.disabled = $.map( o.disabled, function( n, i ) { + options.disabled = $.map( options.disabled, function( n ) { return n >= index ? ++n : n; }); this.refresh(); - - if ( this.anchors.length == 1 ) { - o.active = o.selected = 0; - $li.addClass( "ui-tabs-active ui-state-active" ); - $panel.show(); - this.element.queue( "tabs", function() { - self._trigger( "activate", null, self._ui( self.anchors[ 0 ], self.panels[ 0 ] ) ); - }); - - this.load( 0 ); + if ( this.lis.length === 1 && options.active === false ) { + this.option( "active", 0 ); } this._trigger( "add", null, this._ui( this.anchors[ index ], this.panels[ index ] ) ); @@ -830,27 +866,27 @@ if ( $.uiBackCompat !== false ) { prototype.remove = function( index ) { index = this._getIndex( index ); - var o = this.options, - $li = this.lis.eq( index ).remove(), - $panel = this.panels.eq( index ).remove(); + var options = this.options, + tab = this.lis.eq( index ).remove(), + panel = this.panels.eq( index ).remove(); // If selected tab was removed focus tab to the right or // in case the last tab was removed the tab to the left. - if ( $li.hasClass( "ui-tabs-active" ) && this.anchors.length > 1) { + if ( tab.hasClass( "ui-tabs-active" ) && this.anchors.length > 1) { this._activate( index + ( index + 1 < this.anchors.length ? 1 : -1 ) ); } - o.disabled = $.map( - $.grep( o.disabled, function(n, i) { - return n != index; + options.disabled = $.map( + $.grep( options.disabled, function( n ) { + return n !== index; }), - function( n, i ) { + function( n ) { return n >= index ? --n : n; }); this.refresh(); - this._trigger( "remove", null, this._ui( $li.find( "a" )[ 0 ], $panel[ 0 ] ) ); + this._trigger( "remove", null, this._ui( tab.find( "a" )[ 0 ], panel[ 0 ] ) ); return this; }; }( jQuery, jQuery.ui.tabs.prototype ) ); @@ -862,13 +898,6 @@ if ( $.uiBackCompat !== false ) { }; }( jQuery, jQuery.ui.tabs.prototype ) ); - // url method - (function( $, prototype ) { - prototype.url = function( index, url ) { - this.anchors.eq( index ).attr( "href", url ); - }; - }( jQuery, jQuery.ui.tabs.prototype ) ); - // panel ids (idPrefix option + title attribute) (function( $, prototype ) { $.extend( prototype.options, { |