| 14 | | eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(4($){$.2k({A:{2r:0}});$.1E.A=4(x,w){2(V x==\'2V\')w=x;w=$.2k({K:(x&&V x==\'1Z\'&&x>0)?--x:0,13:C,I:$.1e?2i:O,1b:O,1o:\'2UO;\',22:\'1b-2D-\',1s:C,1l:C,1i:C,1y:C,1x:\'2t\',2q:C,2n:C,2l:O,2j:C,1f:C,1c:C,1u:\'A-1O\',L:\'A-2a\',18:\'A-13\',19:\'A-24\',1q:\'A-1H\',1K:\'A-2J\',20:\'Z\'},w||{});$.8.1C=$.8.Q&&($.8.1Y&&$.8.1Y<7||/6.0/.2z(2x.2w));4 1F(){1V(0,0)}F 5.S(4(){3 p=5;3 r=$(\'10.\'+w.1u,p);r=r.W()&&r||$(\'>10:9(0)\',p);3 j=$(\'a\',r);2(w.1b){j.S(4(){3 c=w.22+(++$.A.2r),B=\'#\'+c,2g=5.1P;5.1P=B;$(\'<Z P="\'+c+\'" 33="\'+w.19+\'"></Z>\').2e(p);$(5).14(\'1N\',4(e,a){3 b=$(5).J(w.1K),Y=$(\'Y\',5)[0],27=Y.1J;2(w.1o){Y.1J=\'<26>\'+w.1o+\'</26>\'}1p(4(){$(B).2S(2g,4(){2(w.1o){Y.1J=27}b.1a(w.1K);a&&a()})},0)})})}3 n=$(\'Z.\'+w.19,p);n=n.W()&&n||$(\'>\'+w.20,p);r.T(\'.\'+w.1u)||r.J(w.1u);n.S(4(){3 a=$(5);a.T(\'.\'+w.19)||a.J(w.19)});3 s=$(\'z\',r).21($(\'z.\'+w.L,r)[0]);2(s>=0){w.K=s}2(1d.B){j.S(4(i){2(5.B==1d.B){w.K=i;2(($.8.Q||$.8.2E)&&!w.1b){3 a=$(1d.B);3 b=a.17(\'P\');a.17(\'P\',\'\');1p(4(){a.17(\'P\',b)},2C)}1F();F O}})}2($.8.Q){1F()}n.16(\':9(\'+w.K+\')\').1D().1m().2B(\':9(\'+w.K+\')\').J(w.1q);$(\'z\',r).1a(w.L).9(w.K).J(w.L);j.9(w.K).N(\'1N\').1m();2(w.2l){3 l=4(d){3 c=$.2A(n.1k(),4(a){3 h,1A=$(a);2(d){2($.8.1C){a.11.2y(\'1X\');a.11.G=\'\';a.1j=C}h=1A.H({\'1h-G\':\'\'}).G()}E{h=1A.G()}F h}).2v(4(a,b){F b-a});2($.8.1C){n.S(4(){5.1j=c[0]+\'1W\';5.11.2u(\'1X\',\'5.11.G = 5.1j ? 5.1j : "2s"\')})}E{n.H({\'1h-G\':c[0]+\'1W\'})}};l();3 q=p.1U;3 m=p.1v;3 v=$(\'#A-2p-2o-W\').1k(0)||$(\'<Y P="A-2p-2o-W">M</Y>\').H({1T:\'2m\',39:\'38\',37:\'36\'}).2e(U.1S).1k(0);3 o=v.1v;35(4(){3 b=p.1U;3 a=p.1v;3 c=v.1v;2(a>m||b!=q||c!=o){l((b>q||c<o));q=b;m=a;o=c}},34)}3 u={},12={},1R=w.2q||w.1x,1Q=w.2n||w.1x;2(w.1l||w.1s){2(w.1l){u[\'G\']=\'1D\';12[\'G\']=\'1H\'}2(w.1s){u[\'X\']=\'1D\';12[\'X\']=\'1H\'}}E{2(w.1i){u=w.1i}E{u[\'1h-2h\']=0;1R=1}2(w.1y){12=w.1y}E{12[\'1h-2h\']=0;1Q=1}}3 t=w.2j,1f=w.1f,1c=w.1c;j.14(\'2f\',4(){3 c=$(5).15(\'z:9(0)\');2(p.1t||c.T(\'.\'+w.L)||c.T(\'.\'+w.18)){F O}3 a=5.B;2($.8.Q){$(5).N(\'1g\');2(w.I){$.1e.1w(a);1d.B=a.1B(\'#\',\'\')}}E 2($.8.1z){3 b=$(\'<2d 32="\'+a+\'"><Z><31 30="2c" 2Z="h" /></Z></2d>\').1k(0);b.2c();$(5).N(\'1g\');2(w.I){$.1e.1w(a)}}E{2(w.I){1d.B=a.1B(\'#\',\'\')}E{$(5).N(\'1g\')}}});j.14(\'1M\',4(){3 a=$(5).15(\'z:9(0)\');2($.8.1z){a.1n({X:0},1,4(){a.H({X:\'\'})})}a.J(w.18)});2(w.13&&w.13.1L){29(3 i=0,k=w.13.1L;i<k;i++){j.9(--w.13[i]).N(\'1M\').1m()}};j.14(\'28\',4(){3 a=$(5).15(\'z:9(0)\');a.1a(w.18);2($.8.1z){a.1n({X:1},1,4(){a.H({X:\'\'})})}});j.14(\'1g\',4(e){3 g=e.2Y;3 d=5,z=$(5).15(\'z:9(0)\'),D=$(5.B),R=n.16(\':2X\');2(p[\'1t\']||z.T(\'.\'+w.L)||z.T(\'.\'+w.18)||V t==\'4\'&&t(5,D[0],R[0])===O){5.25();F O}p[\'1t\']=2i;2(D.W()){2($.8.Q&&w.I){3 c=5.B.1B(\'#\',\'\');D.17(\'P\',\'\');1p(4(){D.17(\'P\',c)},0)}3 f={1T:\'\',2T:\'\',G:\'\'};2(!$.8.Q){f[\'X\']=\'\'}4 1I(){2(w.I&&g){$.1e.1w(d.B)}R.1n(12,1Q,4(){$(d).15(\'z:9(0)\').J(w.L).2R().1a(w.L);R.J(w.1q).H(f);2(V 1f==\'4\'){1f(d,D[0],R[0])}2(!(w.1l||w.1s||w.1i)){D.H(\'1T\',\'2m\')}D.1n(u,1R,4(){D.1a(w.1q).H(f);2($.8.Q){R[0].11.16=\'\';D[0].11.16=\'\'}2(V 1c==\'4\'){1c(d,D[0],R[0])}p[\'1t\']=C})})}2(!w.1b){1I()}E{$(d).N(\'1N\',[1I])}}E{2Q(\'2P T 2W 2N 24.\')}3 a=1G.2M||U.1r&&U.1r.23||U.1S.23||0;3 b=1G.2L||U.1r&&U.1r.2b||U.1S.2b||0;1p(4(){1G.1V(a,b)},0);5.25();F w.I&&!!g});2(w.I){$.1e.2K(4(){j.9(w.K).N(\'1g\').1m()})}})};3 y=[\'2f\',\'1M\',\'28\'];29(3 i=0;i<y.1L;i++){$.1E[y[i]]=(4(d){F 4(c){F 5.S(4(){3 b=$(\'10.A-1O\',5);b=b.W()&&b||$(\'>10:9(0)\',5);3 a;2(!c||V c==\'1Z\'){a=$(\'z a\',b).9((c&&c>0&&c-1||0))}E 2(V c==\'2I\'){a=$(\'z a[@1P$="#\'+c+\'"]\',b)}a.N(d)})}})(y[i])}$.1E.2H=4(){3 c=[];5.S(4(){3 a=$(\'10.A-1O\',5);a=a.W()&&a||$(\'>10:9(0)\',5);3 b=$(\'z\',a);c.2G(b.21(b.16(\'.A-2a\')[0])+1)});F c[0]}})(2F);',62,196,'||if|var|function|this|||browser|eq||||||||||||||||||||||||||li|tabs|hash|null|toShow|else|return|height|css|bookmarkable|addClass|initial|selectedClass||trigger|false|id|msie|toHide|each|is|document|typeof|size|opacity|span|div|ul|style|hideAnim|disabled|bind|parents|filter|attr|disabledClass|containerClass|removeClass|remote|onShow|location|ajaxHistory|onHide|click|min|fxShow|minHeight|get|fxSlide|end|animate|spinner|setTimeout|hideClass|documentElement|fxFade|locked|navClass|offsetHeight|update|fxSpeed|fxHide|safari|jq|replace|msie6|show|fn|unFocus|window|hide|switchTab|innerHTML|loadingClass|length|disableTab|loadRemoteTab|nav|href|hideSpeed|showSpeed|body|display|offsetWidth|scrollTo|px|behaviour|version|number|tabStruct|index|hashPrefix|scrollLeft|container|blur|em|tabTitle|enableTab|for|selected|scrollTop|submit|form|appendTo|triggerTab|url|width|true|onClick|extend|fxAutoHeight|block|fxHideSpeed|font|watch|fxShowSpeed|remoteCount|1px|normal|setExpression|sort|userAgent|navigator|removeExpression|test|map|not|500|tab|opera|jQuery|push|activeTab|string|loading|initialize|pageYOffset|pageXOffset|such|8230|There|alert|siblings|load|overflow|Loading|object|no|visible|clientX|value|type|input|action|class|50|setInterval|hidden|visibility|absolute|position'.split('|'),0,{})) |
|---|
| | 14 | |
|---|
| | 15 | (function($) { // block scope |
|---|
| | 16 | |
|---|
| | 17 | $.extend({ |
|---|
| | 18 | tabs: { |
|---|
| | 19 | remoteCount: 0 // TODO in Tabs 3 this is going to be more cleanly in one single namespace |
|---|
| | 20 | } |
|---|
| | 21 | }); |
|---|
| | 22 | |
|---|
| | 23 | /** |
|---|
| | 24 | * Create an accessible, unobtrusive tab interface based on a particular HTML structure. |
|---|
| | 25 | * |
|---|
| | 26 | * The underlying HTML has to look like this: |
|---|
| | 27 | * |
|---|
| | 28 | * <div id="container"> |
|---|
| | 29 | * <ul> |
|---|
| | 30 | * <li><a href="#fragment-1">Section 1</a></li> |
|---|
| | 31 | * <li><a href="#fragment-2">Section 2</a></li> |
|---|
| | 32 | * <li><a href="#fragment-3">Section 3</a></li> |
|---|
| | 33 | * </ul> |
|---|
| | 34 | * <div id="fragment-1"> |
|---|
| | 35 | * |
|---|
| | 36 | * </div> |
|---|
| | 37 | * <div id="fragment-2"> |
|---|
| | 38 | * |
|---|
| | 39 | * </div> |
|---|
| | 40 | * <div id="fragment-3"> |
|---|
| | 41 | * |
|---|
| | 42 | * </div> |
|---|
| | 43 | * </div> |
|---|
| | 44 | * |
|---|
| | 45 | * Each anchor in the unordered list points directly to a section below represented by one of the |
|---|
| | 46 | * divs (the URI in the anchor's href attribute refers to the fragment with the corresponding id). |
|---|
| | 47 | * Because such HTML structure is fully functional on its own, e.g. without JavaScript, the tab |
|---|
| | 48 | * interface is accessible and unobtrusive. |
|---|
| | 49 | * |
|---|
| | 50 | * A tab is also bookmarkable via hash in the URL. Use the History/Remote plugin (Tabs will |
|---|
| | 51 | * auto-detect its presence) to fix the back (and forward) button. |
|---|
| | 52 | * |
|---|
| | 53 | * @example $('#container').tabs(); |
|---|
| | 54 | * @desc Create a basic tab interface. |
|---|
| | 55 | * @example $('#container').tabs(2); |
|---|
| | 56 | * @desc Create a basic tab interface with the second tab initially activated. |
|---|
| | 57 | * @example $('#container').tabs({disabled: [3, 4]}); |
|---|
| | 58 | * @desc Create a tab interface with the third and fourth tab being disabled. |
|---|
| | 59 | * @example $('#container').tabs({fxSlide: true}); |
|---|
| | 60 | * @desc Create a tab interface that uses slide down/up animations for showing/hiding tab |
|---|
| | 61 | * content upon tab switching. |
|---|
| | 62 | * |
|---|
| | 63 | * @param Number initial An integer specifying the position of the tab (no zero-based index) that |
|---|
| | 64 | * gets activated at first (on page load). Two alternative ways to specify |
|---|
| | 65 | * the active tab will overrule this argument. First a li element |
|---|
| | 66 | * (representing one single tab) belonging to the selected tab class, e.g. |
|---|
| | 67 | * set the selected tab class (default: "tabs-selected", see option |
|---|
| | 68 | * selectedClass) for one of the unordered li elements in the HTML source. |
|---|
| | 69 | * In addition if a fragment identifier/hash in the URL of the page refers |
|---|
| | 70 | * to the id of a tab container of a tab interface the corresponding tab will |
|---|
| | 71 | * be activated and both the initial argument as well as an eventually |
|---|
| | 72 | * declared class attribute will be overruled. Defaults to 1 if omitted. |
|---|
| | 73 | * @param Object settings An object literal containing key/value pairs to provide optional settings. |
|---|
| | 74 | * @option Array<Number> disabled An array containing the position of the tabs (no zero-based index) |
|---|
| | 75 | * that should be disabled on initialization. Default value: null. |
|---|
| | 76 | * A tab can also be disabled by simply adding the disabling class |
|---|
| | 77 | * (default: "tabs-disabled", see option disabledClass) to the li |
|---|
| | 78 | * element representing that particular tab. |
|---|
| | 79 | * @option Boolean bookmarkable Boolean flag indicating if support for bookmarking and history (via |
|---|
| | 80 | * changing hash in the URL of the browser) is enabled. Default value: |
|---|
| | 81 | * false, unless the History/Remote plugin is included. In that case the |
|---|
| | 82 | * default value becomes true. @see $.ajaxHistory.initialize |
|---|
| | 83 | * @option Boolean remote Boolean flag indicating that tab content has to be loaded remotely from |
|---|
| | 84 | * the url given in the href attribute of the tab menu anchor elements. |
|---|
| | 85 | * @option String spinner The content of this string is shown in a tab while remote content is loading. |
|---|
| | 86 | * Insert plain text as well as an img here. To turn off this notification |
|---|
| | 87 | * pass an empty string or null. Default: "Loading…". |
|---|
| | 88 | * @option String hashPrefix A String that is used for constructing the hash the link's href attribute |
|---|
| | 89 | * of a remote tab gets altered to, such as "#remote-1". |
|---|
| | 90 | * Default value: "remote-tab-". |
|---|
| | 91 | * @option Boolean fxFade Boolean flag indicating whether fade in/out animations are used for tab |
|---|
| | 92 | * switching. Can be combined with fxSlide. Will overrule fxShow/fxHide. |
|---|
| | 93 | * Default value: false. |
|---|
| | 94 | * @option Boolean fxSlide Boolean flag indicating whether slide down/up animations are used for tab |
|---|
| | 95 | * switching. Can be combined with fxFade. Will overrule fxShow/fxHide. |
|---|
| | 96 | * Default value: false. |
|---|
| | 97 | * @option String|Number fxSpeed A string representing one of the three predefined speeds ("slow", |
|---|
| | 98 | * "normal", or "fast") or the number of milliseconds (e.g. 1000) to |
|---|
| | 99 | * run an animation. Default value: "normal". |
|---|
| | 100 | * @option Object fxShow An object literal of the form jQuery's animate function expects for making |
|---|
| | 101 | * your own, custom animation to reveal a tab upon tab switch. Unlike fxFade |
|---|
| | 102 | * or fxSlide this animation is independent from an optional hide animation. |
|---|
| | 103 | * Default value: null. @see animate |
|---|
| | 104 | * @option Object fxHide An object literal of the form jQuery's animate function expects for making |
|---|
| | 105 | * your own, custom animation to hide a tab upon tab switch. Unlike fxFade |
|---|
| | 106 | * or fxSlide this animation is independent from an optional show animation. |
|---|
| | 107 | * Default value: null. @see animate |
|---|
| | 108 | * @option String|Number fxShowSpeed A string representing one of the three predefined speeds |
|---|
| | 109 | * ("slow", "normal", or "fast") or the number of milliseconds |
|---|
| | 110 | * (e.g. 1000) to run the animation specified in fxShow. |
|---|
| | 111 | * Default value: fxSpeed. |
|---|
| | 112 | * @option String|Number fxHideSpeed A string representing one of the three predefined speeds |
|---|
| | 113 | * ("slow", "normal", or "fast") or the number of milliseconds |
|---|
| | 114 | * (e.g. 1000) to run the animation specified in fxHide. |
|---|
| | 115 | * Default value: fxSpeed. |
|---|
| | 116 | * @option Boolean fxAutoHeight Boolean flag that if set to true causes all tab heights |
|---|
| | 117 | * to be constant (being the height of the tallest tab). |
|---|
| | 118 | * Default value: false. |
|---|
| | 119 | * @option Function onClick A function to be invoked upon tab switch, immediatly after a tab has |
|---|
| | 120 | * been clicked, e.g. before the other's tab content gets hidden. The |
|---|
| | 121 | * function gets passed three arguments: the first one is the clicked |
|---|
| | 122 | * tab (e.g. an anchor element), the second one is the DOM element |
|---|
| | 123 | * containing the content of the clicked tab (e.g. the div), the third |
|---|
| | 124 | * argument is the one of the tab that gets hidden. If this callback |
|---|
| | 125 | * returns false, the tab switch is canceled (use to disallow tab |
|---|
| | 126 | * switching for the reason of a failed form validation for example). |
|---|
| | 127 | * Default value: null. |
|---|
| | 128 | * @option Function onHide A function to be invoked upon tab switch, immediatly after one tab's |
|---|
| | 129 | * content got hidden (with or without an animation) and right before the |
|---|
| | 130 | * next tab is revealed. The function gets passed three arguments: the |
|---|
| | 131 | * first one is the clicked tab (e.g. an anchor element), the second one |
|---|
| | 132 | * is the DOM element containing the content of the clicked tab, (e.g. the |
|---|
| | 133 | * div), the third argument is the one of the tab that gets hidden. |
|---|
| | 134 | * Default value: null. |
|---|
| | 135 | * @option Function onShow A function to be invoked upon tab switch. This function is invoked |
|---|
| | 136 | * after the new tab has been revealed, e.g. after the switch is completed. |
|---|
| | 137 | * The function gets passed three arguments: the first one is the clicked |
|---|
| | 138 | * tab (e.g. an anchor element), the second one is the DOM element |
|---|
| | 139 | * containing the content of the clicked tab, (e.g. the div), the third |
|---|
| | 140 | * argument is the one of the tab that gets hidden. Default value: null. |
|---|
| | 141 | * @option String navClass A CSS class that is used to identify the tabs unordered list by class if |
|---|
| | 142 | * the required HTML structure differs from the default one. |
|---|
| | 143 | * Default value: "tabs-nav". |
|---|
| | 144 | * @option String selectedClass The CSS class attached to the li element representing the |
|---|
| | 145 | * currently selected (active) tab. Default value: "tabs-selected". |
|---|
| | 146 | * @option String disabledClass The CSS class attached to the li element representing a disabled |
|---|
| | 147 | * tab. Default value: "tabs-disabled". |
|---|
| | 148 | * @option String containerClass A CSS class that is used to identify tab containers by class if |
|---|
| | 149 | * the required HTML structure differs from the default one. |
|---|
| | 150 | * Default value: "tabs-container". |
|---|
| | 151 | * @option String hideClass The CSS class used for hiding inactive tabs. A class is used instead |
|---|
| | 152 | * of "display: none" in the style attribute to maintain control over |
|---|
| | 153 | * visibility in other media types than screen, most notably print. |
|---|
| | 154 | * Default value: "tabs-hide". |
|---|
| | 155 | * @option String loadingClass The CSS class used for indicating that an Ajax tab is currently |
|---|
| | 156 | * loading, for example by showing a spinner. |
|---|
| | 157 | * Default value: "tabs-loading". |
|---|
| | 158 | * @option String tabStruct @deprecated A CSS selector or basic XPath expression reflecting a |
|---|
| | 159 | * nested HTML structure that is different from the default single div |
|---|
| | 160 | * structure (one div with an id inside the overall container holds one |
|---|
| | 161 | * tab's content). If for instance an additional div is required to wrap |
|---|
| | 162 | * up the several tab containers such a structure is expressed by "div>div". |
|---|
| | 163 | * Default value: "div". |
|---|
| | 164 | * @type jQuery |
|---|
| | 165 | * |
|---|
| | 166 | * @name tabs |
|---|
| | 167 | * @cat Plugins/Tabs |
|---|
| | 168 | * @author Klaus Hartl/klaus.hartl@stilbuero.de |
|---|
| | 169 | */ |
|---|
| | 170 | $.fn.tabs = function(initial, settings) { |
|---|
| | 171 | |
|---|
| | 172 | // settings |
|---|
| | 173 | if (typeof initial == 'object') settings = initial; // no initial tab given but a settings object |
|---|
| | 174 | settings = $.extend({ |
|---|
| | 175 | initial: (initial && typeof initial == 'number' && initial > 0) ? --initial : 0, |
|---|
| | 176 | disabled: null, |
|---|
| | 177 | bookmarkable: $.ajaxHistory ? true : false, |
|---|
| | 178 | remote: false, |
|---|
| | 179 | spinner: 'Loading…', |
|---|
| | 180 | hashPrefix: 'remote-tab-', |
|---|
| | 181 | fxFade: null, |
|---|
| | 182 | fxSlide: null, |
|---|
| | 183 | fxShow: null, |
|---|
| | 184 | fxHide: null, |
|---|
| | 185 | fxSpeed: 'normal', |
|---|
| | 186 | fxShowSpeed: null, |
|---|
| | 187 | fxHideSpeed: null, |
|---|
| | 188 | fxAutoHeight: false, |
|---|
| | 189 | onClick: null, |
|---|
| | 190 | onHide: null, |
|---|
| | 191 | onShow: null, |
|---|
| | 192 | navClass: 'tabs-nav', |
|---|
| | 193 | selectedClass: 'tabs-selected', |
|---|
| | 194 | disabledClass: 'tabs-disabled', |
|---|
| | 195 | containerClass: 'tabs-container', |
|---|
| | 196 | hideClass: 'tabs-hide', |
|---|
| | 197 | loadingClass: 'tabs-loading', |
|---|
| | 198 | tabStruct: 'div' |
|---|
| | 199 | }, settings || {}); |
|---|
| | 200 | |
|---|
| | 201 | $.browser.msie6 = $.browser.msie && ($.browser.version && $.browser.version < 7 || /6.0/.test(navigator.userAgent)); |
|---|
| | 202 | |
|---|
| | 203 | // helper to prevent scroll to fragment |
|---|
| | 204 | function unFocus() { |
|---|
| | 205 | scrollTo(0, 0); |
|---|
| | 206 | } |
|---|
| | 207 | |
|---|
| | 208 | // initialize tabs |
|---|
| | 209 | return this.each(function() { |
|---|
| | 210 | |
|---|
| | 211 | // remember wrapper for later |
|---|
| | 212 | var container = this; |
|---|
| | 213 | |
|---|
| | 214 | // setup nav |
|---|
| | 215 | var nav = $('ul.' + settings.navClass, container); |
|---|
| | 216 | nav = nav.size() && nav || $('>ul:eq(0)', container); // fallback to default structure |
|---|
| | 217 | var tabs = $('a', nav); |
|---|
| | 218 | |
|---|
| | 219 | // prepare remote tabs |
|---|
| | 220 | if (settings.remote) { |
|---|
| | 221 | tabs.each(function() { |
|---|
| | 222 | var id = settings.hashPrefix + (++$.tabs.remoteCount), hash = '#' + id, url = this.href; |
|---|
| | 223 | this.href = hash; |
|---|
| | 224 | $('<div id="' + id + '" class="' + settings.containerClass + '"></div>').appendTo(container); |
|---|
| | 225 | |
|---|
| | 226 | $(this).bind('loadRemoteTab', function(e, callback) { |
|---|
| | 227 | var $$ = $(this).addClass(settings.loadingClass), span = $('span', this)[0], tabTitle = span.innerHTML; |
|---|
| | 228 | if (settings.spinner) { |
|---|
| | 229 | // TODO if spinner is image |
|---|
| | 230 | span.innerHTML = '<em>' + settings.spinner + '</em>'; // WARNING: html(...) crashes Safari with jQuery 1.1.2 |
|---|
| | 231 | } |
|---|
| | 232 | setTimeout(function() { // Timeout is again required in IE, "wait" for id being restored |
|---|
| | 233 | $(hash).load(url, function() { |
|---|
| | 234 | if (settings.spinner) { |
|---|
| | 235 | span.innerHTML = tabTitle; // WARNING: html(...) crashes Safari with jQuery 1.1.2 |
|---|
| | 236 | } |
|---|
| | 237 | $$.removeClass(settings.loadingClass); |
|---|
| | 238 | callback && callback(); |
|---|
| | 239 | }); |
|---|
| | 240 | }, 0); |
|---|
| | 241 | }); |
|---|
| | 242 | |
|---|
| | 243 | }); |
|---|
| | 244 | } |
|---|
| | 245 | |
|---|
| | 246 | // set up containers |
|---|
| | 247 | var containers = $('div.' + settings.containerClass, container); |
|---|
| | 248 | containers = containers.size() && containers || $('>' + settings.tabStruct, container); // fallback to default structure |
|---|
| | 249 | |
|---|
| | 250 | // attach classes for styling if not present |
|---|
| | 251 | nav.is('.' + settings.navClass) || nav.addClass(settings.navClass); |
|---|
| | 252 | containers.each(function() { |
|---|
| | 253 | var $$ = $(this); |
|---|
| | 254 | $$.is('.' + settings.containerClass) || $$.addClass(settings.containerClass); |
|---|
| | 255 | }); |
|---|
| | 256 | |
|---|
| | 257 | // try to retrieve active tab from class in HTML |
|---|
| | 258 | var hasSelectedClass = $('li', nav).index( $('li.' + settings.selectedClass, nav)[0] ); |
|---|
| | 259 | if (hasSelectedClass >= 0) { |
|---|
| | 260 | settings.initial = hasSelectedClass; |
|---|
| | 261 | } |
|---|
| | 262 | |
|---|
| | 263 | // try to retrieve active tab from hash in url, will override class in HTML |
|---|
| | 264 | if (location.hash) { |
|---|
| | 265 | tabs.each(function(i) { |
|---|
| | 266 | if (this.hash == location.hash) { |
|---|
| | 267 | settings.initial = i; |
|---|
| | 268 | // prevent page scroll to fragment |
|---|
| | 269 | if (($.browser.msie || $.browser.opera) && !settings.remote) { |
|---|
| | 270 | var toShow = $(location.hash); |
|---|
| | 271 | var toShowId = toShow.attr('id'); |
|---|
| | 272 | toShow.attr('id', ''); |
|---|
| | 273 | setTimeout(function() { |
|---|
| | 274 | toShow.attr('id', toShowId); // restore id |
|---|
| | 275 | }, 500); |
|---|
| | 276 | } |
|---|
| | 277 | unFocus(); |
|---|
| | 278 | return false; // break |
|---|
| | 279 | } |
|---|
| | 280 | }); |
|---|
| | 281 | } |
|---|
| | 282 | if ($.browser.msie) { |
|---|
| | 283 | unFocus(); // fix IE focussing bottom of the page for some unknown reason |
|---|
| | 284 | } |
|---|
| | 285 | |
|---|
| | 286 | // highlight tab accordingly |
|---|
| | 287 | containers.filter(':eq(' + settings.initial + ')').show().end().not(':eq(' + settings.initial + ')').addClass(settings.hideClass); |
|---|
| | 288 | $('li', nav).removeClass(settings.selectedClass).eq(settings.initial).addClass(settings.selectedClass); // we need to remove classes eventually if hash takes precedence over class |
|---|
| | 289 | // trigger load of initial tab |
|---|
| | 290 | tabs.eq(settings.initial).trigger('loadRemoteTab').end(); |
|---|
| | 291 | |
|---|
| | 292 | // setup auto height |
|---|
| | 293 | if (settings.fxAutoHeight) { |
|---|
| | 294 | // helper |
|---|
| | 295 | var _setAutoHeight = function(reset) { |
|---|
| | 296 | // get tab heights in top to bottom ordered array |
|---|
| | 297 | var heights = $.map(containers.get(), function(el) { |
|---|
| | 298 | var h, jq = $(el); |
|---|
| | 299 | if (reset) { |
|---|
| | 300 | if ($.browser.msie6) { |
|---|
| | 301 | el.style.removeExpression('behaviour'); |
|---|
| | 302 | el.style.height = ''; |
|---|
| | 303 | el.minHeight = null; |
|---|
| | 304 | } |
|---|
| | 305 | h = jq.css({'min-height': ''}).height(); // use jQuery's height() to get hidden element values |
|---|
| | 306 | } else { |
|---|
| | 307 | h = jq.height(); // use jQuery's height() to get hidden element values |
|---|
| | 308 | } |
|---|
| | 309 | return h; |
|---|
| | 310 | }).sort(function(a, b) { |
|---|
| | 311 | return b - a; |
|---|
| | 312 | }); |
|---|
| | 313 | if ($.browser.msie6) { |
|---|
| | 314 | containers.each(function() { |
|---|
| | 315 | this.minHeight = heights[0] + 'px'; |
|---|
| | 316 | this.style.setExpression('behaviour', 'this.style.height = this.minHeight ? this.minHeight : "1px"'); // using an expression to not make print styles useless |
|---|
| | 317 | }); |
|---|
| | 318 | } else { |
|---|
| | 319 | containers.css({'min-height': heights[0] + 'px'}); |
|---|
| | 320 | } |
|---|
| | 321 | }; |
|---|
| | 322 | // call once for initialization |
|---|
| | 323 | _setAutoHeight(); |
|---|
| | 324 | // trigger auto height adjustment if needed |
|---|
| | 325 | var cachedWidth = container.offsetWidth; |
|---|
| | 326 | var cachedHeight = container.offsetHeight; |
|---|
| | 327 | var watchFontSize = $('#tabs-watch-font-size').get(0) || $('<span id="tabs-watch-font-size">M</span>').css({display: 'block', position: 'absolute', visibility: 'hidden'}).appendTo(document.body).get(0); |
|---|
| | 328 | var cachedFontSize = watchFontSize.offsetHeight; |
|---|
| | 329 | setInterval(function() { |
|---|
| | 330 | var currentWidth = container.offsetWidth; |
|---|
| | 331 | var currentHeight = container.offsetHeight; |
|---|
| | 332 | var currentFontSize = watchFontSize.offsetHeight; |
|---|
| | 333 | if (currentHeight > cachedHeight || currentWidth != cachedWidth || currentFontSize != cachedFontSize) { |
|---|
| | 334 | _setAutoHeight((currentWidth > cachedWidth || currentFontSize < cachedFontSize)); // if heights gets smaller reset min-height |
|---|
| | 335 | cachedWidth = currentWidth; |
|---|
| | 336 | cachedHeight = currentHeight; |
|---|
| | 337 | cachedFontSize = currentFontSize; |
|---|
| | 338 | } |
|---|
| | 339 | }, 50); |
|---|
| | 340 | } |
|---|
| | 341 | |
|---|
| | 342 | // setup animations |
|---|
| | 343 | var showAnim = {}, hideAnim = {}, showSpeed = settings.fxShowSpeed || settings.fxSpeed, hideSpeed = settings.fxHideSpeed || settings.fxSpeed; |
|---|
| | 344 | if (settings.fxSlide || settings.fxFade) { |
|---|
| | 345 | if (settings.fxSlide) { |
|---|
| | 346 | showAnim['height'] = 'show'; |
|---|
| | 347 | hideAnim['height'] = 'hide'; |
|---|
| | 348 | } |
|---|
| | 349 | if (settings.fxFade) { |
|---|
| | 350 | showAnim['opacity'] = 'show'; |
|---|
| | 351 | hideAnim['opacity'] = 'hide'; |
|---|
| | 352 | } |
|---|
| | 353 | } else { |
|---|
| | 354 | if (settings.fxShow) { |
|---|
| | 355 | showAnim = settings.fxShow; |
|---|
| | 356 | } else { // use some kind of animation to prevent browser scrolling to the tab |
|---|
| | 357 | showAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox |
|---|
| | 358 | showSpeed = 1; // as little as 1 is sufficient |
|---|
| | 359 | } |
|---|
| | 360 | if (settings.fxHide) { |
|---|
| | 361 | hideAnim = settings.fxHide; |
|---|
| | 362 | } else { // use some kind of animation to prevent browser scrolling to the tab |
|---|
| | 363 | hideAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox |
|---|
| | 364 | hideSpeed = 1; // as little as 1 is sufficient |
|---|
| | 365 | } |
|---|
| | 366 | } |
|---|
| | 367 | |
|---|
| | 368 | // callbacks |
|---|
| | 369 | var onClick = settings.onClick, onHide = settings.onHide, onShow = settings.onShow; |
|---|
| | 370 | |
|---|
| | 371 | // attach activateTab event, required for activating a tab programmatically |
|---|
| | 372 | tabs.bind('triggerTab', function() { |
|---|
| | 373 | |
|---|
| | 374 | // if the tab is already selected or disabled or animation is still running stop here |
|---|
| | 375 | var li = $(this).parents('li:eq(0)'); |
|---|
| | 376 | if (container.locked || li.is('.' + settings.selectedClass) || li.is('.' + settings.disabledClass)) { |
|---|
| | 377 | return false; |
|---|
| | 378 | } |
|---|
| | 379 | |
|---|
| | 380 | var hash = this.hash; |
|---|
| | 381 | |
|---|
| | 382 | if ($.browser.msie) { |
|---|
| | 383 | |
|---|
| | 384 | $(this).trigger('click'); |
|---|
| | 385 | if (settings.bookmarkable) { |
|---|
| | 386 | $.ajaxHistory.update(hash); |
|---|
| | 387 | location.hash = hash.replace('#', ''); |
|---|
| | 388 | } |
|---|
| | 389 | |
|---|
| | 390 | } else if ($.browser.safari) { |
|---|
| | 391 | |
|---|
| | 392 | // Simply setting location.hash puts Safari into the eternal load state... ugh! Submit a form instead. |
|---|
| | 393 | var tempForm = $('<form action="' + hash + '"><div><input type="submit" value="h" /></div></form>').get(0); // no need to append it to the body |
|---|
| | 394 | tempForm.submit(); // does not trigger the form's submit event... |
|---|
| | 395 | $(this).trigger('click'); // ...thus do stuff here |
|---|
| | 396 | if (settings.bookmarkable) { |
|---|
| | 397 | $.ajaxHistory.update(hash); |
|---|
| | 398 | } |
|---|
| | 399 | |
|---|
| | 400 | } else { |
|---|
| | 401 | |
|---|
| | 402 | if (settings.bookmarkable) { |
|---|
| | 403 | location.hash = hash.replace('#', ''); |
|---|
| | 404 | } else { |
|---|
| | 405 | $(this).trigger('click'); |
|---|
| | 406 | } |
|---|
| | 407 | |
|---|
| | 408 | } |
|---|
| | 409 | |
|---|
| | 410 | }); |
|---|
| | 411 | |
|---|
| | 412 | // attach disable event, required for disabling a tab |
|---|
| | 413 | tabs.bind('disableTab', function() { |
|---|
| | 414 | var li = $(this).parents('li:eq(0)'); |
|---|
| | 415 | if ($.browser.safari) { /* fix opacity of tab after disabling in Safari... */ |
|---|
| | 416 | li.animate({ opacity: 0 }, 1, function() { |
|---|
| | 417 | li.css({opacity: ''}); |
|---|
| | 418 | }); |
|---|
| | 419 | } |
|---|
| | 420 | li.addClass(settings.disabledClass); |
|---|
| | 421 | |
|---|
| | 422 | }); |
|---|
| | 423 | |
|---|
| | 424 | // disabled from settings |
|---|
| | 425 | if (settings.disabled && settings.disabled.length) { |
|---|
| | 426 | for (var i = 0, k = settings.disabled.length; i < k; i++) { |
|---|
| | 427 | tabs.eq(--settings.disabled[i]).trigger('disableTab').end(); |
|---|
| | 428 | } |
|---|
| | 429 | }; |
|---|
| | 430 | |
|---|
| | 431 | // attach enable event, required for reenabling a tab |
|---|
| | 432 | tabs.bind('enableTab', function() { |
|---|
| | 433 | var li = $(this).parents('li:eq(0)'); |
|---|
| | 434 | li.removeClass(settings.disabledClass); |
|---|
| | 435 | if ($.browser.safari) { /* fix disappearing tab after enabling in Safari... */ |
|---|
| | 436 | li.animate({ opacity: 1 }, 1, function() { |
|---|
| | 437 | li.css({opacity: ''}); |
|---|
| | 438 | }); |
|---|
| | 439 | } |
|---|
| | 440 | }); |
|---|
| | 441 | |
|---|
| | 442 | // attach click event |
|---|
| | 443 | tabs.bind('click', function(e) { |
|---|
| | 444 | |
|---|
| | 445 | var trueClick = e.clientX; // add to history only if true click occured, not a triggered click |
|---|
| | 446 | var clicked = this, li = $(this).parents('li:eq(0)'), toShow = $(this.hash), toHide = containers.filter(':visible'); |
|---|
| | 447 | |
|---|
| | 448 | // if animation is still running, tab is selected or disabled or onClick callback returns false stop here |
|---|
| | 449 | // check if onClick returns false last so that it is not executed for a disabled tab |
|---|
| | 450 | if (container['locked'] || li.is('.' + settings.selectedClass) || li.is('.' + settings.disabledClass) || typeof onClick == 'function' && onClick(this, toShow[0], toHide[0]) === false) { |
|---|
| | 451 | this.blur(); |
|---|
| | 452 | return false; |
|---|
| | 453 | } |
|---|
| | 454 | |
|---|
| | 455 | container['locked'] = true; |
|---|
| | 456 | |
|---|
| | 457 | // show new tab |
|---|
| | 458 | if (toShow.size()) { |
|---|
| | 459 | |
|---|
| | 460 | // prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled |
|---|
| | 461 | if ($.browser.msie && settings.bookmarkable) { |
|---|
| | 462 | var toShowId = this.hash.replace('#', ''); |
|---|
| | 463 | toShow.attr('id', ''); |
|---|
| | 464 | setTimeout(function() { |
|---|
| | 465 | toShow.attr('id', toShowId); // restore id |
|---|
| | 466 | }, 0); |
|---|
| | 467 | } |
|---|
| | 468 | |
|---|
| | 469 | var resetCSS = { display: '', overflow: '', height: '' }; |
|---|
| | 470 | if (!$.browser.msie) { // not in IE to prevent ClearType font issue |
|---|
| | 471 | resetCSS['opacity'] = ''; |
|---|
| | 472 | } |
|---|
| | 473 | |
|---|
| | 474 | // switch tab, animation prevents browser scrolling to the fragment |
|---|
| | 475 | function switchTab() { |
|---|
| | 476 | if (settings.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click |
|---|
| | 477 | $.ajaxHistory.update(clicked.hash); |
|---|
| | 478 | } |
|---|
| | 479 | toHide.animate(hideAnim, hideSpeed, function() { // |
|---|
| | 480 | $(clicked).parents('li:eq(0)').addClass(settings.selectedClass).siblings().removeClass(settings.selectedClass); |
|---|
| | 481 | toHide.addClass(settings.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc. |
|---|
| | 482 | if (typeof onHide == 'function') { |
|---|
| | 483 | onHide(clicked, toShow[0], toHide[0]); |
|---|
| | 484 | } |
|---|
| | 485 | if (!(settings.fxSlide || settings.fxFade || settings.fxShow)) { |
|---|
| | 486 | toShow.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab containers |
|---|
| | 487 | } |
|---|
| | 488 | toShow.animate(showAnim, showSpeed, function() { |
|---|
| | 489 | toShow.removeClass(settings.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc. |
|---|
| | 490 | if ($.browser.msie) { |
|---|
| | 491 | toHide[0].style.filter = ''; |
|---|
| | 492 | toShow[0].style.filter = ''; |
|---|
| | 493 | } |
|---|
| | 494 | if (typeof onShow == 'function') { |
|---|
| | 495 | onShow(clicked, toShow[0], toHide[0]); |
|---|
| | 496 | } |
|---|
| | 497 | container['locked'] = null; |
|---|
| | 498 | }); |
|---|
| | 499 | }); |
|---|
| | 500 | } |
|---|
| | 501 | |
|---|
| | 502 | if (!settings.remote) { |
|---|
| | 503 | switchTab(); |
|---|
| | 504 | } else { |
|---|
| | 505 | $(clicked).trigger('loadRemoteTab', [switchTab]); |
|---|
| | 506 | } |
|---|
| | 507 | |
|---|
| | 508 | } else { |
|---|
| | 509 | alert('There is no such container.'); |
|---|
| | 510 | } |
|---|
| | 511 | |
|---|
| | 512 | // Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash |
|---|
| | 513 | var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0; |
|---|
| | 514 | var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0; |
|---|
| | 515 | setTimeout(function() { |
|---|
| | 516 | window.scrollTo(scrollX, scrollY); |
|---|
| | 517 | }, 0); |
|---|
| | 518 | |
|---|
| | 519 | this.blur(); // prevent IE from keeping other link focussed when using the back button |
|---|
| | 520 | |
|---|
| | 521 | return settings.bookmarkable && !!trueClick; // convert undefined to Boolean for IE |
|---|
| | 522 | |
|---|
| | 523 | }); |
|---|
| | 524 | |
|---|
| | 525 | // enable history support if bookmarking and history is turned on |
|---|
| | 526 | if (settings.bookmarkable) { |
|---|
| | 527 | $.ajaxHistory.initialize(function() { |
|---|
| | 528 | tabs.eq(settings.initial).trigger('click').end(); |
|---|
| | 529 | }); |
|---|
| | 530 | } |
|---|
| | 531 | |
|---|
| | 532 | }); |
|---|
| | 533 | |
|---|
| | 534 | }; |
|---|
| | 535 | |
|---|
| | 536 | /** |
|---|
| | 537 | * Activate a tab programmatically with the given position (no zero-based index) |
|---|
| | 538 | * or its id, e.g. the URL's fragment identifier/hash representing a tab, as if the tab |
|---|
| | 539 | * itself were clicked. |
|---|
| | 540 | * |
|---|
| | 541 | * @example $('#container').triggerTab(2); |
|---|
| | 542 | * @desc Activate the second tab of the tab interface contained in <div id="container">. |
|---|
| | 543 | * @example $('#container').triggerTab(1); |
|---|
| | 544 | * @desc Activate the first tab of the tab interface contained in <div id="container">. |
|---|
| | 545 | * @example $('#container').triggerTab(); |
|---|
| | 546 | * @desc Activate the first tab of the tab interface contained in <div id="container">. |
|---|
| | 547 | * @example $('#container').triggerTab('fragment-2'); |
|---|
| | 548 | * @desc Activate a tab via its URL fragment identifier representation. |
|---|
| | 549 | * |
|---|
| | 550 | * @param String|Number tab Either a string that matches the id of the tab (the URL's |
|---|
| | 551 | * fragment identifier/hash representing a tab) or an integer |
|---|
| | 552 | * specifying the position of the tab (no zero-based index) to |
|---|
| | 553 | * be activated. If this parameter is omitted, the first tab |
|---|
| | 554 | * will be activated. |
|---|
| | 555 | * @type jQuery |
|---|
| | 556 | * |
|---|
| | 557 | * @name triggerTab |
|---|
| | 558 | * @cat Plugins/Tabs |
|---|
| | 559 | * @author Klaus Hartl/klaus.hartl@stilbuero.de |
|---|
| | 560 | */ |
|---|
| | 561 | |
|---|
| | 562 | /** |
|---|
| | 563 | * Disable a tab, so that clicking it has no effect. |
|---|
| | 564 | * |
|---|
| | 565 | * @example $('#container').disableTab(2); |
|---|
| | 566 | * @desc Disable the second tab of the tab interface contained in <div id="container">. |
|---|
| | 567 | * |
|---|
| | 568 | * @param String|Number tab Either a string that matches the id of the tab (the URL's |
|---|
| | 569 | * fragment identifier/hash representing a tab) or an integer |
|---|
| | 570 | * specifying the position of the tab (no zero-based index) to |
|---|
| | 571 | * be disabled. If this parameter is omitted, the first tab |
|---|
| | 572 | * will be disabled. |
|---|
| | 573 | * @type jQuery |
|---|
| | 574 | * |
|---|
| | 575 | * @name disableTab |
|---|
| | 576 | * @cat Plugins/Tabs |
|---|
| | 577 | * @author Klaus Hartl/klaus.hartl@stilbuero.de |
|---|
| | 578 | */ |
|---|
| | 579 | |
|---|
| | 580 | /** |
|---|
| | 581 | * Enable a tab that has been disabled. |
|---|
| | 582 | * |
|---|
| | 583 | * @example $('#container').enableTab(2); |
|---|
| | 584 | * @desc Enable the second tab of the tab interface contained in <div id="container">. |
|---|
| | 585 | * |
|---|
| | 586 | * @param String|Number tab Either a string that matches the id of the tab (the URL's |
|---|
| | 587 | * fragment identifier/hash representing a tab) or an integer |
|---|
| | 588 | * specifying the position of the tab (no zero-based index) to |
|---|
| | 589 | * be enabled. If this parameter is omitted, the first tab |
|---|
| | 590 | * will be enabled. |
|---|
| | 591 | * @type jQuery |
|---|
| | 592 | * |
|---|
| | 593 | * @name enableTab |
|---|
| | 594 | * @cat Plugins/Tabs |
|---|
| | 595 | * @author Klaus Hartl/klaus.hartl@stilbuero.de |
|---|
| | 596 | */ |
|---|
| | 597 | |
|---|
| | 598 | var tabEvents = ['triggerTab', 'disableTab', 'enableTab']; |
|---|
| | 599 | for (var i = 0; i < tabEvents.length; i++) { |
|---|
| | 600 | $.fn[tabEvents[i]] = (function(tabEvent) { |
|---|
| | 601 | return function(tab) { |
|---|
| | 602 | return this.each(function() { |
|---|
| | 603 | var nav = $('ul.tabs-nav' , this); |
|---|
| | 604 | nav = nav.size() && nav || $('>ul:eq(0)', this); // fallback to default structure |
|---|
| | 605 | var a; |
|---|
| | 606 | if (!tab || typeof tab == 'number') { |
|---|
| | 607 | a = $('li a', nav).eq((tab && tab > 0 && tab - 1 || 0)); // fall back to 0 |
|---|
| | 608 | } else if (typeof tab == 'string') { |
|---|
| | 609 | a = $('li a[@href$="#' + tab + '"]', nav); |
|---|
| | 610 | } |
|---|
| | 611 | a.trigger(tabEvent); |
|---|
| | 612 | }); |
|---|
| | 613 | }; |
|---|
| | 614 | })(tabEvents[i]); |
|---|
| | 615 | } |
|---|
| | 616 | |
|---|
| | 617 | /** |
|---|
| | 618 | * Get the position of the currently selected tab (no zero-based index). |
|---|
| | 619 | * |
|---|
| | 620 | * @example $('#container').activeTab(); |
|---|
| | 621 | * @desc Get the position of the currently selected tab of an interface |
|---|
| | 622 | * contained in <div id="container">. |
|---|
| | 623 | * |
|---|
| | 624 | * @type Number |
|---|
| | 625 | * |
|---|
| | 626 | * @name activeTab |
|---|
| | 627 | * @cat Plugins/Tabs |
|---|
| | 628 | * @author Klaus Hartl/klaus.hartl@stilbuero.de |
|---|
| | 629 | */ |
|---|
| | 630 | |
|---|
| | 631 | $.fn.activeTab = function() { |
|---|
| | 632 | var selectedTabs = []; |
|---|
| | 633 | this.each(function() { |
|---|
| | 634 | var nav = $('ul.tabs-nav' , this); |
|---|
| | 635 | nav = nav.size() && nav || $('>ul:eq(0)', this); //fallback to default structure |
|---|
| | 636 | var lis = $('li', nav); |
|---|
| | 637 | selectedTabs.push(lis.index( lis.filter('.tabs-selected')[0] ) + 1); |
|---|
| | 638 | }); |
|---|
| | 639 | return selectedTabs[0]; |
|---|
| | 640 | }; |
|---|
| | 641 | |
|---|
| | 642 | })(jQuery); |
|---|