2008-06-04 02:34:33 +00:00
/ *
2008-09-04 22:03:30 +00:00
* jQuery UI Tabs @ VERSION
2008-06-04 02:34:33 +00:00
*
* Copyright ( c ) 2007 , 2008 Klaus Hartl ( stilbuero . de )
* Dual licensed under the MIT ( MIT - LICENSE . txt )
* and GPL ( GPL - LICENSE . txt ) licenses .
*
* http : //docs.jquery.com/UI/Tabs
*
* Depends :
* ui . core . js
* /
2008-06-05 12:14:12 +00:00
( function ( $ ) {
2008-06-04 02:34:33 +00:00
$ . widget ( "ui.tabs" , {
2008-08-16 14:45:28 +00:00
_init : function ( ) {
2008-06-04 02:34:33 +00:00
// create tabs
2008-08-16 07:34:55 +00:00
this . _tabify ( true ) ;
2008-06-04 02:34:33 +00:00
} ,
2008-08-16 14:45:28 +00:00
_setData : function ( key , value ) {
2008-06-04 02:34:33 +00:00
if ( ( /^selected/ ) . test ( key ) )
this . select ( value ) ;
else {
this . options [ key ] = value ;
2008-08-16 07:34:55 +00:00
this . _tabify ( ) ;
2008-06-04 02:34:33 +00:00
}
} ,
length : function ( ) {
return this . $tabs . length ;
} ,
2008-08-16 07:34:55 +00:00
_tabId : function ( a ) {
2008-06-04 02:34:33 +00:00
return a . title && a . title . replace ( /\s/g , '_' ) . replace ( /[^A-Za-z0-9\-_:\.]/g , '' )
|| this . options . idPrefix + $ . data ( a ) ;
} ,
ui : function ( tab , panel ) {
return {
options : this . options ,
tab : tab ,
2008-07-06 15:03:38 +00:00
panel : panel ,
index : this . $tabs . index ( tab )
2008-06-04 02:34:33 +00:00
} ;
} ,
2008-10-02 14:20:35 +00:00
_sanitizeSelector : function ( hash ) {
return hash . replace ( /:/g , '\\:' ) ; // we need this because an id may contain a ":"
} ,
_cookie : function ( ) {
var cookie = this . cookie || ( this . cookie = 'ui-tabs-' + $ . data ( this . element [ 0 ] ) ) ;
return $ . cookie . apply ( null , [ cookie ] . concat ( $ . makeArray ( arguments ) ) ) ;
} ,
2008-08-16 07:34:55 +00:00
_tabify : function ( init ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
this . $lis = $ ( 'li:has(a[href])' , this . element ) ;
this . $tabs = this . $lis . map ( function ( ) { return $ ( 'a' , this ) [ 0 ] ; } ) ;
this . $panels = $ ( [ ] ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
var self = this , o = this . options ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
this . $tabs . each ( function ( i , a ) {
// inline tab
if ( a . hash && a . hash . replace ( '#' , '' ) ) // Safari 2 reports '#' for an empty hash
2008-10-02 14:20:35 +00:00
self . $panels = self . $panels . add ( self . _sanitizeSelector ( a . hash ) ) ;
2008-06-04 02:34:33 +00:00
// remote tab
else if ( $ ( a ) . attr ( 'href' ) != '#' ) { // prevent loading the page itself if href is just "#"
$ . data ( a , 'href.tabs' , a . href ) ; // required for restore on destroy
$ . data ( a , 'load.tabs' , a . href ) ; // mutable
2008-08-16 07:34:55 +00:00
var id = self . _tabId ( a ) ;
2008-06-04 02:34:33 +00:00
a . href = '#' + id ;
var $panel = $ ( '#' + id ) ;
if ( ! $panel . length ) {
$panel = $ ( o . panelTemplate ) . attr ( 'id' , id ) . addClass ( o . panelClass )
2008-10-04 11:25:28 +00:00
. insertAfter ( self . $panels [ i - 1 ] || self . element ) ;
2008-06-04 02:34:33 +00:00
$panel . data ( 'destroy.tabs' , true ) ;
}
2008-10-04 11:25:28 +00:00
self . $panels = self . $panels . add ( $panel ) ;
2008-06-04 02:34:33 +00:00
}
// invalid tab href
else
o . disabled . push ( i + 1 ) ;
} ) ;
2008-09-20 02:43:18 +00:00
2008-08-15 14:43:44 +00:00
// initialization from scratch
2008-06-04 02:34:33 +00:00
if ( init ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// attach necessary classes for styling if not present
this . element . addClass ( o . navClass ) ;
2008-10-04 11:25:28 +00:00
this . $panels . addClass ( o . panelClass ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// Selected tab
// use "selected" option or try to retrieve:
// 1. from fragment identifier in url
// 2. from cookie
// 3. from selected class attribute on <li>
if ( o . selected === undefined ) {
if ( location . hash ) {
this . $tabs . each ( function ( i , a ) {
if ( a . hash == location . hash ) {
o . selected = i ;
// prevent page scroll to fragment
2008-10-02 14:20:35 +00:00
if ( $ . browser . msie || $ . browser . opera ) {
var $toShow = $ ( this . _sanitizeSelector ( location . hash ) ) , toShowId = $toShow . attr ( 'id' ) ;
2008-06-04 02:34:33 +00:00
$toShow . attr ( 'id' , '' ) ;
setTimeout ( function ( ) {
$toShow . attr ( 'id' , toShowId ) ; // restore id
} , 500 ) ;
}
scrollTo ( 0 , 0 ) ;
return false ; // break
}
} ) ;
}
else if ( o . cookie ) {
2008-10-02 14:20:35 +00:00
var index = parseInt ( self . _cookie ( ) , 10 ) ;
2008-06-04 02:34:33 +00:00
if ( index && self . $tabs [ index ] )
o . selected = index ;
}
else if ( self . $lis . filter ( '.' + o . selectedClass ) . length )
o . selected = self . $lis . index ( self . $lis . filter ( '.' + o . selectedClass ) [ 0 ] ) ;
}
o . selected = o . selected === null || o . selected !== undefined ? o . selected : 0 ; // first tab selected by default
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// Take disabling tabs via class attribute from HTML
// into account and update option properly.
// A selected tab cannot become disabled.
o . disabled = $ . unique ( o . disabled . concat (
$ . map ( this . $lis . filter ( '.' + o . disabledClass ) ,
function ( n , i ) { return self . $lis . index ( n ) ; } )
) ) . sort ( ) ;
if ( $ . inArray ( o . selected , o . disabled ) != - 1 )
o . disabled . splice ( $ . inArray ( o . selected , o . disabled ) , 1 ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
// highlight selected tab
this . $panels . addClass ( o . hideClass ) ;
this . $lis . removeClass ( o . selectedClass ) ;
if ( o . selected !== null ) {
this . $panels . eq ( o . selected ) . show ( ) . removeClass ( o . hideClass ) ; // use show and remove class to show in any case no matter how it has been hidden before
2008-10-04 11:25:28 +00:00
var classes = [ o . selectedClass ] ;
2008-10-08 10:09:55 +00:00
if ( o . deselectable ) classes . push ( o . deselectableClass ) ;
2008-10-04 11:25:28 +00:00
this . $lis . eq ( o . selected ) . addClass ( classes . join ( ' ' ) ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
// seems to be expected behavior that the show callback is fired
var onShow = function ( ) {
2008-08-16 14:51:12 +00:00
self . _trigger ( 'show' , null ,
2008-07-14 23:54:16 +00:00
self . ui ( self . $tabs [ o . selected ] , self . $panels [ o . selected ] ) ) ;
} ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// load if remote tab
if ( $ . data ( this . $tabs [ o . selected ] , 'load.tabs' ) )
this . load ( o . selected , onShow ) ;
// just trigger show event
else
onShow ( ) ;
}
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
// clean up to avoid memory leaks in certain versions of IE 6
$ ( window ) . bind ( 'unload' , function ( ) {
self . $tabs . unbind ( '.tabs' ) ;
self . $lis = self . $tabs = self . $panels = null ;
} ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
}
2008-08-15 14:43:44 +00:00
// update selected after add/remove
else
o . selected = this . $lis . index ( this . $lis . filter ( '.' + o . selectedClass ) [ 0 ] ) ;
2008-09-20 02:43:18 +00:00
2008-09-09 09:28:03 +00:00
// set or update cookie after init and add/remove respectively
if ( o . cookie )
2008-10-02 14:20:35 +00:00
this . _cookie ( o . selected , o . cookie ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
// disable tabs
for ( var i = 0 , li ; li = this . $lis [ i ] ; i ++ )
$ ( li ) [ $ . inArray ( i , o . disabled ) != - 1 && ! $ ( li ) . hasClass ( o . selectedClass ) ? 'addClass' : 'removeClass' ] ( o . disabledClass ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// reset cache if switching from cached to not cached
if ( o . cache === false )
this . $tabs . removeData ( 'cache.tabs' ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
// set up animations
var hideFx , showFx , baseFx = { 'min-width' : 0 , duration : 1 } , baseDuration = 'normal' ;
if ( o . fx && o . fx . constructor == Array )
hideFx = o . fx [ 0 ] || baseFx , showFx = o . fx [ 1 ] || baseFx ;
else
hideFx = showFx = o . fx || baseFx ;
2008-09-20 02:43:18 +00:00
2008-10-06 11:41:48 +00:00
// Reset certain styles left over from animation to
// maintain print style sheets and prevent IE's
// ClearType bug...
function resetStyle ( $el , fx ) {
$el . css ( { display : '' } ) ;
if ( $ . browser . msie && fx . opacity )
$el [ 0 ] . style . filter = '' ;
}
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// Hide a tab, animation prevents browser scrolling to fragment,
// $show is optional.
function hideTab ( clicked , $hide , $show ) {
$hide . animate ( hideFx , hideFx . duration || baseDuration , function ( ) { //
2008-10-06 11:41:48 +00:00
$hide . addClass ( o . hideClass ) ;
resetStyle ( $hide , hideFx ) ;
if ( $show ) showTab ( clicked , $show , $hide ) ;
2008-06-04 02:34:33 +00:00
} ) ;
}
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// Show a tab, animation prevents browser scrolling to fragment,
// $hide is optional.
function showTab ( clicked , $show , $hide ) {
2008-10-06 11:41:48 +00:00
if ( showFx === baseFx ) $show . css ( 'display' , 'block' ) ; // prevent occasionally occuring flicker in Firefox caused by gap between showing and hiding the tab panels
2008-06-04 02:34:33 +00:00
$show . animate ( showFx , showFx . duration || baseDuration , function ( ) {
2008-10-06 11:41:48 +00:00
$show . removeClass ( o . hideClass ) ;
resetStyle ( $show , showFx ) ;
2008-08-16 14:51:12 +00:00
self . _trigger ( 'show' , null , self . ui ( clicked , $show [ 0 ] ) ) ;
2008-06-04 02:34:33 +00:00
} ) ;
}
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// switch a tab
function switchTab ( clicked , $li , $hide , $show ) {
/*if (o.bookmarkable && trueClick) { / / add to history only if true click occured , not a triggered click
$ . ajaxHistory . update ( clicked . hash ) ;
} * /
2008-10-04 11:25:28 +00:00
var classes = [ o . selectedClass ] ;
2008-10-08 10:09:55 +00:00
if ( o . deselectable ) classes . push ( o . deselectableClass ) ;
2008-10-04 11:25:28 +00:00
$li . addClass ( classes . join ( ' ' ) ) . siblings ( ) . removeClass ( classes . join ( ' ' ) ) ;
2008-06-04 02:34:33 +00:00
hideTab ( clicked , $hide , $show ) ;
}
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// attach tab event handler, unbind to avoid duplicates from former tabifying...
2008-10-02 14:20:35 +00:00
this . $tabs . unbind ( '.tabs' ) . bind ( o . event + '.tabs' , function ( ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
//var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
var $li = $ ( this ) . parents ( 'li:eq(0)' ) ,
$hide = self . $panels . filter ( ':visible' ) ,
2008-10-02 14:20:35 +00:00
$show = $ ( self . _sanitizeSelector ( this . hash ) ) ;
2008-09-20 02:43:18 +00:00
2008-10-08 10:09:55 +00:00
// If tab is already selected and not deselectable or tab disabled or
2008-06-04 02:34:33 +00:00
// or is already loading or click callback returns false stop here.
// Check if click handler returns false last so that it is not executed
// for a disabled or loading tab!
2008-10-08 10:09:55 +00:00
if ( ( $li . hasClass ( o . selectedClass ) && ! o . deselectable )
2008-09-20 03:23:42 +00:00
|| $li . hasClass ( o . disabledClass )
2008-06-04 02:34:33 +00:00
|| $ ( this ) . hasClass ( o . loadingClass )
2008-08-16 14:51:12 +00:00
|| self . _trigger ( 'select' , null , self . ui ( this , $show [ 0 ] ) ) === false
2008-06-04 02:34:33 +00:00
) {
this . blur ( ) ;
return false ;
}
2008-09-20 02:43:18 +00:00
2008-10-02 14:20:35 +00:00
o . selected = self . $tabs . index ( this ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// if tab may be closed
2008-10-08 10:09:55 +00:00
if ( o . deselectable ) {
2008-06-04 02:34:33 +00:00
if ( $li . hasClass ( o . selectedClass ) ) {
self . options . selected = null ;
2008-10-08 10:09:55 +00:00
$li . removeClass ( [ o . selectedClass , o . deselectableClass ] . join ( ' ' ) ) ;
2008-06-04 02:34:33 +00:00
self . $panels . stop ( ) ;
hideTab ( this , $hide ) ;
this . blur ( ) ;
return false ;
} else if ( ! $hide . length ) {
self . $panels . stop ( ) ;
var a = this ;
self . load ( self . $tabs . index ( this ) , function ( ) {
2008-10-08 10:09:55 +00:00
$li . addClass ( [ o . selectedClass , o . deselectableClass ] . join ( ' ' ) ) ;
2008-06-04 02:34:33 +00:00
showTab ( a , $show ) ;
} ) ;
this . blur ( ) ;
return false ;
}
}
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
if ( o . cookie )
2008-10-02 14:20:35 +00:00
self . _cookie ( o . selected , o . cookie ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// stop possibly running animations
self . $panels . stop ( ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// show new tab
if ( $show . length ) {
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
/ * i f ( $ . b r o w s e r . m s i e & & o . b o o k m a r k a b l e ) {
var showId = this . hash . replace ( '#' , '' ) ;
$show . attr ( 'id' , '' ) ;
setTimeout ( function ( ) {
$show . attr ( 'id' , showId ) ; // restore id
} , 0 ) ;
} * /
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
var a = this ;
2008-09-19 14:20:14 +00:00
self . load ( self . $tabs . index ( this ) , $hide . length ?
2008-06-04 02:34:33 +00:00
function ( ) {
switchTab ( a , $li , $hide , $show ) ;
} :
function ( ) {
$li . addClass ( o . selectedClass ) ;
showTab ( a , $show ) ;
}
) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
/ * v a r s c r o l l X = w i n d o w . p a g e X O f f s e t | | d o c u m e n t . d o c u m e n t E l e m e n t & & d o c u m e n t . d o c u m e n t E l e m e n t . s c r o l l L e f t | | d o c u m e n t . b o d y . s c r o l l L e f t | | 0 ;
var scrollY = window . pageYOffset || document . documentElement && document . documentElement . scrollTop || document . body . scrollTop || 0 ;
setTimeout ( function ( ) {
scrollTo ( scrollX , scrollY ) ;
} , 0 ) ; * /
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
} else
throw 'jQuery UI Tabs: Mismatching fragment identifier.' ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// Prevent IE from keeping other link focussed when using the back button
// and remove dotted border from clicked link. This is controlled in modern
// browsers via CSS, also blur removes focus from address bar in Firefox
// which can become a usability and annoying problem with tabsRotate.
if ( $ . browser . msie )
this . blur ( ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
//return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
return false ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
} ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// disable click if event is configured to something else
2008-10-02 14:20:35 +00:00
if ( o . event != 'click' )
2008-06-04 02:34:33 +00:00
this . $tabs . bind ( 'click.tabs' , function ( ) { return false ; } ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
} ,
add : function ( url , label , index ) {
2008-09-20 03:23:42 +00:00
if ( index == undefined )
2008-06-04 02:34:33 +00:00
index = this . $tabs . length ; // append by default
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
var o = this . options ;
var $li = $ ( o . tabTemplate . replace ( /#\{href\}/g , url ) . replace ( /#\{label\}/g , label ) ) ;
$li . data ( 'destroy.tabs' , true ) ;
2008-09-20 02:43:18 +00:00
2008-08-16 07:34:55 +00:00
var id = url . indexOf ( '#' ) == 0 ? url . replace ( '#' , '' ) : this . _tabId ( $ ( 'a:first-child' , $li ) [ 0 ] ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// try to find an existing element before creating a new one
var $panel = $ ( '#' + id ) ;
if ( ! $panel . length ) {
$panel = $ ( o . panelTemplate ) . attr ( 'id' , id )
. addClass ( o . hideClass )
. data ( 'destroy.tabs' , true ) ;
}
$panel . addClass ( o . panelClass ) ;
if ( index >= this . $lis . length ) {
$li . appendTo ( this . element ) ;
$panel . appendTo ( this . element [ 0 ] . parentNode ) ;
} else {
$li . insertBefore ( this . $lis [ index ] ) ;
$panel . insertBefore ( this . $panels [ index ] ) ;
}
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
o . disabled = $ . map ( o . disabled ,
function ( n , i ) { return n >= index ? ++ n : n } ) ;
2008-09-20 02:43:18 +00:00
2008-08-16 07:34:55 +00:00
this . _tabify ( ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
if ( this . $tabs . length == 1 ) {
$li . addClass ( o . selectedClass ) ;
$panel . removeClass ( o . hideClass ) ;
var href = $ . data ( this . $tabs [ 0 ] , 'load.tabs' ) ;
if ( href )
this . load ( index , href ) ;
}
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// callback
2008-08-16 14:51:12 +00:00
this . _trigger ( 'add' , null , this . ui ( this . $tabs [ index ] , this . $panels [ index ] ) ) ;
2008-06-04 02:34:33 +00:00
} ,
remove : function ( index ) {
var o = this . options , $li = this . $lis . eq ( index ) . remove ( ) ,
$panel = this . $panels . eq ( index ) . remove ( ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// 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 ( o . selectedClass ) && this . $tabs . length > 1 )
this . select ( index + ( index + 1 < this . $tabs . length ? 1 : - 1 ) ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
o . disabled = $ . map ( $ . grep ( o . disabled , function ( n , i ) { return n != index ; } ) ,
function ( n , i ) { return n >= index ? -- n : n } ) ;
2008-09-20 02:43:18 +00:00
2008-08-16 07:34:55 +00:00
this . _tabify ( ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// callback
2008-08-16 14:51:12 +00:00
this . _trigger ( 'remove' , null , this . ui ( $li . find ( 'a' ) [ 0 ] , $panel [ 0 ] ) ) ;
2008-06-04 02:34:33 +00:00
} ,
enable : function ( index ) {
var o = this . options ;
if ( $ . inArray ( index , o . disabled ) == - 1 )
return ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
var $li = this . $lis . eq ( index ) . removeClass ( o . disabledClass ) ;
if ( $ . browser . safari ) { // fix disappearing tab (that used opacity indicating disabling) after enabling in Safari 2...
$li . css ( 'display' , 'inline-block' ) ;
setTimeout ( function ( ) {
$li . css ( 'display' , 'block' ) ;
} , 0 ) ;
}
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
o . disabled = $ . grep ( o . disabled , function ( n , i ) { return n != index ; } ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// callback
2008-08-16 14:51:12 +00:00
this . _trigger ( 'enable' , null , this . ui ( this . $tabs [ index ] , this . $panels [ index ] ) ) ;
2008-06-04 02:34:33 +00:00
} ,
disable : function ( index ) {
var self = this , o = this . options ;
if ( index != o . selected ) { // cannot disable already selected tab
this . $lis . eq ( index ) . addClass ( o . disabledClass ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
o . disabled . push ( index ) ;
o . disabled . sort ( ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// callback
2008-08-16 14:51:12 +00:00
this . _trigger ( 'disable' , null , this . ui ( this . $tabs [ index ] , this . $panels [ index ] ) ) ;
2008-06-04 02:34:33 +00:00
}
} ,
select : function ( index ) {
2008-10-02 14:20:35 +00:00
// TODO make null as argument work
2008-06-04 02:34:33 +00:00
if ( typeof index == 'string' )
index = this . $tabs . index ( this . $tabs . filter ( '[href$=' + index + ']' ) [ 0 ] ) ;
2008-10-02 14:20:35 +00:00
this . $tabs . eq ( index ) . trigger ( this . options . event + '.tabs' ) ;
2008-06-04 02:34:33 +00:00
} ,
load : function ( index , callback ) { // callback is for internal usage only
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
var self = this , o = this . options , $a = this . $tabs . eq ( index ) , a = $a [ 0 ] ,
bypassCache = callback == undefined || callback === false , url = $a . data ( 'load.tabs' ) ;
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
callback = callback || function ( ) { } ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
// no remote or from cache - just finish with callback
if ( ! url || ! bypassCache && $ . data ( a , 'cache.tabs' ) ) {
callback ( ) ;
return ;
}
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// load remote from here on
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
var inner = function ( parent ) {
var $parent = $ ( parent ) , $inner = $parent . find ( '*:last' ) ;
2008-07-06 14:53:40 +00:00
return $inner . length && $inner . is ( ':not(img)' ) && $inner || $parent ;
2008-06-04 02:34:33 +00:00
} ;
var cleanup = function ( ) {
self . $tabs . filter ( '.' + o . loadingClass ) . removeClass ( o . loadingClass )
. each ( function ( ) {
if ( o . spinner )
inner ( this ) . parent ( ) . html ( inner ( this ) . data ( 'label.tabs' ) ) ;
} ) ;
self . xhr = null ;
} ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
if ( o . spinner ) {
var label = inner ( a ) . html ( ) ;
inner ( a ) . wrapInner ( '<em></em>' )
. find ( 'em' ) . data ( 'label.tabs' , label ) . html ( o . spinner ) ;
}
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
var ajaxOptions = $ . extend ( { } , o . ajaxOptions , {
url : url ,
success : function ( r , s ) {
2008-10-02 14:20:35 +00:00
$ ( self . _sanitizeSelector ( a . hash ) ) . html ( r ) ;
2008-06-04 02:34:33 +00:00
cleanup ( ) ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
if ( o . cache )
$ . data ( a , 'cache.tabs' , true ) ; // if loaded once do not load them again
2008-09-20 02:43:18 +00:00
2008-06-04 02:34:33 +00:00
// callbacks
2008-08-16 14:51:12 +00:00
self . _trigger ( 'load' , null , self . ui ( self . $tabs [ index ] , self . $panels [ index ] ) ) ;
2008-10-02 14:20:35 +00:00
try {
o . ajaxOptions . success ( r , s ) ;
}
catch ( e ) { }
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
// This callback is required because the switch has to take
2008-09-19 14:20:14 +00:00
// place after loading has completed. Call last in order to
2008-06-04 02:34:33 +00:00
// fire load before show callback...
callback ( ) ;
}
} ) ;
if ( this . xhr ) {
// terminate pending requests from other tabs and restore tab label
this . xhr . abort ( ) ;
cleanup ( ) ;
}
$a . addClass ( o . loadingClass ) ;
setTimeout ( function ( ) { // timeout is again required in IE, "wait" for id being restored
self . xhr = $ . ajax ( ajaxOptions ) ;
} , 0 ) ;
} ,
url : function ( index , url ) {
this . $tabs . eq ( index ) . removeData ( 'cache.tabs' ) . data ( 'load.tabs' , url ) ;
} ,
destroy : function ( ) {
var o = this . options ;
this . element . unbind ( '.tabs' )
. removeClass ( o . navClass ) . removeData ( 'tabs' ) ;
this . $tabs . each ( function ( ) {
var href = $ . data ( this , 'href.tabs' ) ;
if ( href )
this . href = href ;
var $this = $ ( this ) . unbind ( '.tabs' ) ;
$ . each ( [ 'href' , 'load' , 'cache' ] , function ( i , prefix ) {
$this . removeData ( prefix + '.tabs' ) ;
} ) ;
} ) ;
this . $lis . add ( this . $panels ) . each ( function ( ) {
if ( $ . data ( this , 'destroy.tabs' ) )
$ ( this ) . remove ( ) ;
else
2008-10-08 10:09:55 +00:00
$ ( this ) . removeClass ( [ o . selectedClass , o . deselectableClass ,
2008-06-04 02:34:33 +00:00
o . disabledClass , o . panelClass , o . hideClass ] . join ( ' ' ) ) ;
} ) ;
2008-10-02 14:20:35 +00:00
if ( o . cookie )
this . _cookie ( null , o . cookie ) ;
2008-06-04 02:34:33 +00:00
}
} ) ;
2008-10-08 10:09:55 +00:00
$ . extend ( $ . ui . tabs , {
version : '@VERSION' ,
getter : 'length' ,
defaults : {
// basic setup
deselectable : false ,
event : 'click' ,
disabled : [ ] ,
cookie : null , // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
// Ajax
spinner : 'Loading…' ,
cache : false ,
idPrefix : 'ui-tabs-' ,
ajaxOptions : null ,
// animations
fx : null , // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }
// templates
tabTemplate : '<li><a href="#{href}"><span>#{label}</span></a></li>' ,
panelTemplate : '<div></div>' ,
// CSS class names
navClass : 'ui-tabs-nav' ,
selectedClass : 'ui-tabs-selected' ,
deselectableClass : 'ui-tabs-deselectable' ,
disabledClass : 'ui-tabs-disabled' ,
panelClass : 'ui-tabs-panel' ,
hideClass : 'ui-tabs-hide' ,
loadingClass : 'ui-tabs-loading'
}
} ) ;
2008-06-04 02:34:33 +00:00
/ *
* Tabs Extensions
* /
/ *
* Rotate
* /
$ . extend ( $ . ui . tabs . prototype , {
rotation : null ,
rotate : function ( ms , continuing ) {
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
continuing = continuing || false ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
var self = this , t = this . options . selected ;
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
function start ( ) {
self . rotation = setInterval ( function ( ) {
t = ++ t < self . $tabs . length ? t : 0 ;
self . select ( t ) ;
2008-09-20 03:23:42 +00:00
} , ms ) ;
2008-06-04 02:34:33 +00:00
}
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
function stop ( e ) {
if ( ! e || e . clientX ) { // only in case of a true click
clearInterval ( self . rotation ) ;
}
}
2008-09-19 14:20:14 +00:00
2008-06-04 02:34:33 +00:00
// start interval
if ( ms ) {
start ( ) ;
if ( ! continuing )
2008-10-02 14:20:35 +00:00
this . $tabs . bind ( this . options . event + '.tabs' , stop ) ;
2008-06-04 02:34:33 +00:00
else
2008-10-02 14:20:35 +00:00
this . $tabs . bind ( this . options . event + '.tabs' , function ( ) {
2008-06-04 02:34:33 +00:00
stop ( ) ;
t = self . options . selected ;
start ( ) ;
} ) ;
}
// stop interval
else {
stop ( ) ;
2008-10-02 14:20:35 +00:00
this . $tabs . unbind ( this . options . event + '.tabs' , stop ) ;
2008-06-04 02:34:33 +00:00
}
}
} ) ;
} ) ( jQuery ) ;