jquery.tabs.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. /**
  2. * EasyUI for jQuery 1.5.5.4
  3. *
  4. * Copyright (c) 2009-2018 www.jeasyui.com. All rights reserved.
  5. *
  6. * Licensed under the freeware license: http://www.jeasyui.com/license_freeware.php
  7. * To use it on other terms please contact us: info@jeasyui.com
  8. *
  9. */
  10. /**
  11. * tabs - EasyUI for jQuery
  12. *
  13. * Dependencies:
  14. * panel
  15. * linkbutton
  16. *
  17. */
  18. (function($){
  19. function getContentWidth(c){
  20. var w = 0;
  21. $(c).children().each(function(){
  22. w += $(this).outerWidth(true);
  23. });
  24. return w;
  25. }
  26. /**
  27. * set the tabs scrollers to show or not,
  28. * dependent on the tabs count and width
  29. */
  30. function setScrollers(container) {
  31. var opts = $.data(container, 'tabs').options;
  32. if (!opts.showHeader){return}
  33. var header = $(container).children('div.tabs-header');
  34. var tool = header.children('div.tabs-tool:not(.tabs-tool-hidden)');
  35. var sLeft = header.children('div.tabs-scroller-left');
  36. var sRight = header.children('div.tabs-scroller-right');
  37. var wrap = header.children('div.tabs-wrap');
  38. if (opts.tabPosition == 'left' || opts.tabPosition == 'right'){
  39. if (!tool.length){return}
  40. tool._outerWidth(header.width());
  41. var toolCss = {
  42. left: opts.tabPosition == 'left' ? 'auto':0,
  43. right: opts.tabPosition == 'left' ? 0 : 'auto',
  44. top: opts.toolPosition == 'top' ? 0 : 'auto',
  45. bottom: opts.toolPosition == 'top' ? 'auto' : 0
  46. };
  47. var wrapCss = {
  48. marginTop: opts.toolPosition == 'top' ? tool.outerHeight() : 0
  49. };
  50. tool.css(toolCss);
  51. wrap.css(wrapCss);
  52. return;
  53. }
  54. // set the tool height
  55. var tHeight = header.outerHeight();
  56. if (opts.plain){
  57. tHeight -= tHeight - header.height();
  58. }
  59. tool._outerHeight(tHeight);
  60. var tabsWidth = getContentWidth(header.find('ul.tabs'));
  61. var cWidth = header.width() - tool._outerWidth();
  62. if (tabsWidth > cWidth) {
  63. sLeft.add(sRight).show()._outerHeight(tHeight);
  64. if (opts.toolPosition == 'left'){
  65. tool.css({
  66. left: sLeft.outerWidth(),
  67. right: ''
  68. });
  69. wrap.css({
  70. marginLeft: sLeft.outerWidth() + tool._outerWidth(),
  71. marginRight: sRight._outerWidth(),
  72. width: cWidth - sLeft.outerWidth() - sRight.outerWidth()
  73. });
  74. } else {
  75. tool.css({
  76. left: '',
  77. right: sRight.outerWidth()
  78. });
  79. wrap.css({
  80. marginLeft: sLeft.outerWidth(),
  81. marginRight: sRight.outerWidth() + tool._outerWidth(),
  82. width: cWidth - sLeft.outerWidth() - sRight.outerWidth()
  83. });
  84. }
  85. } else {
  86. sLeft.add(sRight).hide();
  87. if (opts.toolPosition == 'left'){
  88. tool.css({
  89. left: 0,
  90. right: ''
  91. });
  92. wrap.css({
  93. marginLeft: tool._outerWidth(),
  94. marginRight: 0,
  95. width: cWidth
  96. });
  97. } else {
  98. tool.css({
  99. left: '',
  100. right: 0
  101. });
  102. wrap.css({
  103. marginLeft: 0,
  104. marginRight: tool._outerWidth(),
  105. width: cWidth
  106. });
  107. }
  108. }
  109. }
  110. function addTools(container){
  111. var opts = $.data(container, 'tabs').options;
  112. var header = $(container).children('div.tabs-header');
  113. if (opts.tools) {
  114. if (typeof opts.tools == 'string'){
  115. $(opts.tools).addClass('tabs-tool').appendTo(header);
  116. $(opts.tools).show();
  117. } else {
  118. header.children('div.tabs-tool').remove();
  119. var tools = $('<div class="tabs-tool"><table cellspacing="0" cellpadding="0" style="height:100%"><tr></tr></table></div>').appendTo(header);
  120. var tr = tools.find('tr');
  121. for(var i=0; i<opts.tools.length; i++){
  122. var td = $('<td></td>').appendTo(tr);
  123. var tool = $('<a href="javascript:;"></a>').appendTo(td);
  124. tool[0].onclick = eval(opts.tools[i].handler || function(){});
  125. tool.linkbutton($.extend({}, opts.tools[i], {
  126. plain: true
  127. }));
  128. }
  129. }
  130. } else {
  131. header.children('div.tabs-tool').remove();
  132. }
  133. }
  134. function setSize(container, param) {
  135. var state = $.data(container, 'tabs');
  136. var opts = state.options;
  137. var cc = $(container);
  138. if (!opts.doSize){return}
  139. if (param){
  140. $.extend(opts, {
  141. width: param.width,
  142. height: param.height
  143. });
  144. }
  145. cc._size(opts);
  146. var header = cc.children('div.tabs-header');
  147. var panels = cc.children('div.tabs-panels');
  148. var wrap = header.find('div.tabs-wrap');
  149. var ul = wrap.find('.tabs');
  150. ul.children('li').removeClass('tabs-first tabs-last');
  151. ul.children('li:first').addClass('tabs-first');
  152. ul.children('li:last').addClass('tabs-last');
  153. if (opts.tabPosition == 'left' || opts.tabPosition == 'right'){
  154. header._outerWidth(opts.showHeader ? opts.headerWidth : 0);
  155. panels._outerWidth(cc.width() - header.outerWidth());
  156. header.add(panels)._size('height', isNaN(parseInt(opts.height)) ? '' : cc.height());
  157. wrap._outerWidth(header.width());
  158. ul._outerWidth(wrap.width()).css('height','');
  159. } else {
  160. header.children('div.tabs-scroller-left,div.tabs-scroller-right,div.tabs-tool:not(.tabs-tool-hidden)').css('display', opts.showHeader?'block':'none');
  161. header._outerWidth(cc.width()).css('height','');
  162. if (opts.showHeader){
  163. header.css('background-color','');
  164. wrap.css('height','');
  165. } else {
  166. header.css('background-color','transparent');
  167. header._outerHeight(0);
  168. wrap._outerHeight(0);
  169. }
  170. ul._outerHeight(opts.tabHeight).css('width','');
  171. ul._outerHeight(ul.outerHeight()-ul.height()-1+opts.tabHeight).css('width','');
  172. panels._size('height', isNaN(parseInt(opts.height)) ? '' : (cc.height()-header.outerHeight()));
  173. panels._size('width', cc.width());
  174. }
  175. if (state.tabs.length){
  176. var d1 = ul.outerWidth(true) - ul.width();
  177. var li = ul.children('li:first');
  178. var d2 = li.outerWidth(true) - li.width();
  179. var hwidth = header.width() - header.children('.tabs-tool:not(.tabs-tool-hidden)')._outerWidth();
  180. var justifiedWidth = Math.floor((hwidth-d1-d2*state.tabs.length)/state.tabs.length);
  181. $.map(state.tabs, function(p){
  182. setTabSize(p, (opts.justified && $.inArray(opts.tabPosition,['top','bottom'])>=0) ? justifiedWidth : undefined);
  183. });
  184. if (opts.justified && $.inArray(opts.tabPosition,['top','bottom'])>=0){
  185. var deltaWidth = hwidth - d1 - getContentWidth(ul);
  186. setTabSize(state.tabs[state.tabs.length-1], justifiedWidth+deltaWidth);
  187. }
  188. }
  189. setScrollers(container);
  190. function setTabSize(p, width){
  191. var p_opts = p.panel('options');
  192. var p_t = p_opts.tab.find('a.tabs-inner');
  193. var width = width ? width : (parseInt(p_opts.tabWidth||opts.tabWidth||undefined));
  194. if (width){
  195. p_t._outerWidth(width);
  196. } else {
  197. p_t.css('width', '');
  198. }
  199. p_t._outerHeight(opts.tabHeight);
  200. p_t.css('lineHeight', p_t.height()+'px');
  201. p_t.find('.easyui-fluid:visible').triggerHandler('_resize');
  202. }
  203. }
  204. /**
  205. * set selected tab panel size
  206. */
  207. function setSelectedSize(container){
  208. var opts = $.data(container, 'tabs').options;
  209. var tab = getSelectedTab(container);
  210. if (tab){
  211. var panels = $(container).children('div.tabs-panels');
  212. var width = opts.width=='auto' ? 'auto' : panels.width();
  213. var height = opts.height=='auto' ? 'auto' : panels.height();
  214. tab.panel('resize', {
  215. width: width,
  216. height: height
  217. });
  218. }
  219. }
  220. /**
  221. * wrap the tabs header and body
  222. */
  223. function wrapTabs(container) {
  224. var tabs = $.data(container, 'tabs').tabs;
  225. var cc = $(container).addClass('tabs-container');
  226. var panels = $('<div class="tabs-panels"></div>').insertBefore(cc);
  227. cc.children('div').each(function(){
  228. panels[0].appendChild(this);
  229. });
  230. cc[0].appendChild(panels[0]);
  231. $('<div class="tabs-header">'
  232. + '<div class="tabs-scroller-left"></div>'
  233. + '<div class="tabs-scroller-right"></div>'
  234. + '<div class="tabs-wrap">'
  235. + '<ul class="tabs"></ul>'
  236. + '</div>'
  237. + '</div>').prependTo(container);
  238. cc.children('div.tabs-panels').children('div').each(function(i){
  239. var opts = $.extend({}, $.parser.parseOptions(this), {
  240. disabled: ($(this).attr('disabled') ? true : undefined),
  241. selected: ($(this).attr('selected') ? true : undefined)
  242. });
  243. createTab(container, opts, $(this));
  244. });
  245. cc.children('div.tabs-header').find('.tabs-scroller-left, .tabs-scroller-right').hover(
  246. function(){$(this).addClass('tabs-scroller-over');},
  247. function(){$(this).removeClass('tabs-scroller-over');}
  248. );
  249. cc.bind('_resize', function(e,force){
  250. if ($(this).hasClass('easyui-fluid') || force){
  251. setSize(container);
  252. setSelectedSize(container);
  253. }
  254. return false;
  255. });
  256. }
  257. function bindEvents(container){
  258. var state = $.data(container, 'tabs')
  259. var opts = state.options;
  260. $(container).children('div.tabs-header').unbind().bind('click', function(e){
  261. if ($(e.target).hasClass('tabs-scroller-left')){
  262. $(container).tabs('scrollBy', -opts.scrollIncrement);
  263. } else if ($(e.target).hasClass('tabs-scroller-right')){
  264. $(container).tabs('scrollBy', opts.scrollIncrement);
  265. } else {
  266. var li = $(e.target).closest('li');
  267. if (li.hasClass('tabs-disabled')){return false;}
  268. var a = $(e.target).closest('a.tabs-close');
  269. if (a.length){
  270. closeTab(container, getLiIndex(li));
  271. } else if (li.length){
  272. // selectTab(container, getLiIndex(li));
  273. var index = getLiIndex(li);
  274. var popts = state.tabs[index].panel('options');
  275. if (popts.collapsible){
  276. popts.closed ? selectTab(container, index) : unselectTab(container, index);
  277. } else {
  278. selectTab(container, index);
  279. }
  280. }
  281. return false;
  282. }
  283. }).bind('contextmenu', function(e){
  284. var li = $(e.target).closest('li');
  285. if (li.hasClass('tabs-disabled')){return;}
  286. if (li.length){
  287. opts.onContextMenu.call(container, e, li.find('span.tabs-title').html(), getLiIndex(li));
  288. }
  289. });
  290. function getLiIndex(li){
  291. var index = 0;
  292. li.parent().children('li').each(function(i){
  293. if (li[0] == this){
  294. index = i;
  295. return false;
  296. }
  297. });
  298. return index;
  299. }
  300. }
  301. function setProperties(container){
  302. var opts = $.data(container, 'tabs').options;
  303. var header = $(container).children('div.tabs-header');
  304. var panels = $(container).children('div.tabs-panels');
  305. header.removeClass('tabs-header-top tabs-header-bottom tabs-header-left tabs-header-right');
  306. panels.removeClass('tabs-panels-top tabs-panels-bottom tabs-panels-left tabs-panels-right');
  307. if (opts.tabPosition == 'top'){
  308. header.insertBefore(panels);
  309. } else if (opts.tabPosition == 'bottom'){
  310. header.insertAfter(panels);
  311. header.addClass('tabs-header-bottom');
  312. panels.addClass('tabs-panels-top');
  313. } else if (opts.tabPosition == 'left'){
  314. header.addClass('tabs-header-left');
  315. panels.addClass('tabs-panels-right');
  316. } else if (opts.tabPosition == 'right'){
  317. header.addClass('tabs-header-right');
  318. panels.addClass('tabs-panels-left');
  319. }
  320. if (opts.plain == true) {
  321. header.addClass('tabs-header-plain');
  322. } else {
  323. header.removeClass('tabs-header-plain');
  324. }
  325. header.removeClass('tabs-header-narrow').addClass(opts.narrow?'tabs-header-narrow':'');
  326. var tabs = header.find('.tabs');
  327. tabs.removeClass('tabs-pill').addClass(opts.pill?'tabs-pill':'');
  328. tabs.removeClass('tabs-narrow').addClass(opts.narrow?'tabs-narrow':'');
  329. tabs.removeClass('tabs-justified').addClass(opts.justified?'tabs-justified':'');
  330. if (opts.border == true){
  331. header.removeClass('tabs-header-noborder');
  332. panels.removeClass('tabs-panels-noborder');
  333. } else {
  334. header.addClass('tabs-header-noborder');
  335. panels.addClass('tabs-panels-noborder');
  336. }
  337. opts.doSize = true;
  338. }
  339. function createTab(container, options, pp) {
  340. options = options || {};
  341. var state = $.data(container, 'tabs');
  342. var tabs = state.tabs;
  343. if (options.index == undefined || options.index > tabs.length){options.index = tabs.length}
  344. if (options.index < 0){options.index = 0}
  345. var ul = $(container).children('div.tabs-header').find('ul.tabs');
  346. var panels = $(container).children('div.tabs-panels');
  347. var tab = $(
  348. '<li>' +
  349. '<a href="javascript:;" class="tabs-inner">' +
  350. '<span class="tabs-title"></span>' +
  351. '<span class="tabs-icon"></span>' +
  352. '</a>' +
  353. '</li>');
  354. if (!pp){pp = $('<div></div>');}
  355. if (options.index >= tabs.length){
  356. tab.appendTo(ul);
  357. pp.appendTo(panels);
  358. tabs.push(pp);
  359. } else {
  360. tab.insertBefore(ul.children('li:eq('+options.index+')'));
  361. pp.insertBefore(panels.children('div.panel:eq('+options.index+')'));
  362. tabs.splice(options.index, 0, pp);
  363. }
  364. // create panel
  365. pp.panel($.extend({}, options, {
  366. tab: tab,
  367. border: false,
  368. noheader: true,
  369. closed: true,
  370. doSize: false,
  371. iconCls: (options.icon ? options.icon : undefined),
  372. onLoad: function(){
  373. if (options.onLoad){
  374. options.onLoad.apply(this, arguments);
  375. }
  376. state.options.onLoad.call(container, $(this));
  377. },
  378. onBeforeOpen: function(){
  379. if (options.onBeforeOpen){
  380. if (options.onBeforeOpen.call(this) == false){return false;}
  381. }
  382. var p = $(container).tabs('getSelected');
  383. if (p){
  384. if (p[0] != this){
  385. $(container).tabs('unselect', getTabIndex(container, p));
  386. p = $(container).tabs('getSelected');
  387. if (p){
  388. return false;
  389. }
  390. } else {
  391. setSelectedSize(container);
  392. return false;
  393. }
  394. }
  395. var popts = $(this).panel('options');
  396. popts.tab.addClass('tabs-selected');
  397. // scroll the tab to center position if required.
  398. var wrap = $(container).find('>div.tabs-header>div.tabs-wrap');
  399. var left = popts.tab.position().left;
  400. var right = left + popts.tab.outerWidth();
  401. if (left < 0 || right > wrap.width()){
  402. var deltaX = left - (wrap.width()-popts.tab.width()) / 2;
  403. $(container).tabs('scrollBy', deltaX);
  404. } else {
  405. $(container).tabs('scrollBy', 0);
  406. }
  407. var panel = $(this).panel('panel');
  408. panel.css('display','block');
  409. setSelectedSize(container);
  410. panel.css('display','none');
  411. },
  412. onOpen: function(){
  413. if (options.onOpen){
  414. options.onOpen.call(this);
  415. }
  416. var popts = $(this).panel('options');
  417. var index = getTabIndex(container, this);
  418. // state.selectHis.push(popts.title);
  419. state.selectHis.push(index);
  420. state.options.onSelect.call(container, popts.title, index);
  421. },
  422. onBeforeClose: function(){
  423. if (options.onBeforeClose){
  424. if (options.onBeforeClose.call(this) == false){return false;}
  425. }
  426. $(this).panel('options').tab.removeClass('tabs-selected');
  427. },
  428. onClose: function(){
  429. if (options.onClose){
  430. options.onClose.call(this);
  431. }
  432. var popts = $(this).panel('options');
  433. state.options.onUnselect.call(container, popts.title, getTabIndex(container, this));
  434. }
  435. }));
  436. // only update the tab header
  437. $(container).tabs('update', {
  438. tab: pp,
  439. options: pp.panel('options'),
  440. type: 'header'
  441. });
  442. }
  443. function addTab(container, options) {
  444. var state = $.data(container, 'tabs');
  445. var opts = state.options;
  446. if (options.selected == undefined) options.selected = true;
  447. createTab(container, options);
  448. opts.onAdd.call(container, options.title, options.index);
  449. if (options.selected){
  450. selectTab(container, options.index); // select the added tab panel
  451. }
  452. }
  453. /**
  454. * update tab panel, param has following properties:
  455. * tab: the tab panel to be updated
  456. * options: the tab panel options
  457. * type: the update type, possible values are: 'header','body','all'
  458. */
  459. function updateTab(container, param){
  460. param.type = param.type || 'all';
  461. var selectHis = $.data(container, 'tabs').selectHis;
  462. var pp = param.tab; // the tab panel
  463. var opts = pp.panel('options'); // get the tab panel options
  464. var oldTitle = opts.title;
  465. $.extend(opts, param.options, {
  466. iconCls: (param.options.icon ? param.options.icon : undefined)
  467. });
  468. if (param.type == 'all' || param.type == 'body'){
  469. pp.panel();
  470. }
  471. if (param.type == 'all' || param.type == 'header'){
  472. var tab = opts.tab;
  473. if (opts.header){
  474. tab.find('.tabs-inner').html($(opts.header));
  475. } else {
  476. var s_title = tab.find('span.tabs-title');
  477. var s_icon = tab.find('span.tabs-icon');
  478. s_title.html(opts.title);
  479. s_icon.attr('class', 'tabs-icon');
  480. tab.find('a.tabs-close').remove();
  481. if (opts.closable){
  482. s_title.addClass('tabs-closable');
  483. $('<a href="javascript:;" class="tabs-close"></a>').appendTo(tab);
  484. } else{
  485. s_title.removeClass('tabs-closable');
  486. }
  487. if (opts.iconCls){
  488. s_title.addClass('tabs-with-icon');
  489. s_icon.addClass(opts.iconCls);
  490. } else {
  491. s_title.removeClass('tabs-with-icon');
  492. }
  493. if (opts.tools){
  494. var p_tool = tab.find('span.tabs-p-tool');
  495. if (!p_tool.length){
  496. var p_tool = $('<span class="tabs-p-tool"></span>').insertAfter(tab.find('a.tabs-inner'));
  497. }
  498. if ($.isArray(opts.tools)){
  499. p_tool.empty();
  500. for(var i=0; i<opts.tools.length; i++){
  501. var t = $('<a href="javascript:;"></a>').appendTo(p_tool);
  502. t.addClass(opts.tools[i].iconCls);
  503. if (opts.tools[i].handler){
  504. t.bind('click', {handler:opts.tools[i].handler}, function(e){
  505. if ($(this).parents('li').hasClass('tabs-disabled')){return;}
  506. e.data.handler.call(this);
  507. });
  508. }
  509. }
  510. } else {
  511. $(opts.tools).children().appendTo(p_tool);
  512. }
  513. var pr = p_tool.children().length * 12;
  514. if (opts.closable) {
  515. pr += 8;
  516. p_tool.css('right', '');
  517. } else {
  518. pr -= 3;
  519. p_tool.css('right','5px');
  520. }
  521. s_title.css('padding-right', pr+'px');
  522. } else {
  523. tab.find('span.tabs-p-tool').remove();
  524. s_title.css('padding-right', '');
  525. }
  526. }
  527. // if (oldTitle != opts.title){
  528. // for(var i=0; i<selectHis.length; i++){
  529. // if (selectHis[i] == oldTitle){
  530. // selectHis[i] = opts.title;
  531. // }
  532. // }
  533. // }
  534. }
  535. if (opts.disabled){
  536. opts.tab.addClass('tabs-disabled');
  537. } else {
  538. opts.tab.removeClass('tabs-disabled');
  539. }
  540. setSize(container);
  541. $.data(container, 'tabs').options.onUpdate.call(container, opts.title, getTabIndex(container, pp));
  542. }
  543. /**
  544. * close a tab with specified index or title
  545. */
  546. function closeTab(container, which) {
  547. var state = $.data(container, 'tabs');
  548. var opts = state.options;
  549. var tabs = state.tabs;
  550. var selectHis = state.selectHis;
  551. if (!exists(container, which)) return;
  552. var tab = getTab(container, which);
  553. var title = tab.panel('options').title;
  554. var index = getTabIndex(container, tab);
  555. if (opts.onBeforeClose.call(container, title, index) == false) return;
  556. var tab = getTab(container, which, true);
  557. tab.panel('options').tab.remove();
  558. tab.panel('destroy');
  559. opts.onClose.call(container, title, index);
  560. // setScrollers(container);
  561. setSize(container);
  562. // remove the select history item
  563. var his = [];
  564. for(var i=0; i<selectHis.length; i++){
  565. var tindex = selectHis[i];
  566. if (tindex != index){
  567. his.push(tindex > index ? tindex-1 : tindex);
  568. }
  569. }
  570. state.selectHis = his;
  571. var selected = $(container).tabs('getSelected');
  572. if (!selected && his.length){
  573. index = state.selectHis.pop();
  574. $(container).tabs('select', index);
  575. }
  576. // for(var i=0; i<selectHis.length; i++){
  577. // if (selectHis[i] == title){
  578. // selectHis.splice(i, 1);
  579. // i --;
  580. // }
  581. // }
  582. // // select the nearest tab panel
  583. // var hisTitle = selectHis.pop();
  584. // if (hisTitle){
  585. // selectTab(container, hisTitle);
  586. // } else if (tabs.length){
  587. // selectTab(container, 0);
  588. // }
  589. }
  590. /**
  591. * get the specified tab panel
  592. */
  593. function getTab(container, which, removeit){
  594. var tabs = $.data(container, 'tabs').tabs;
  595. var tab = null;
  596. if (typeof which == 'number'){
  597. if (which >=0 && which < tabs.length){
  598. tab = tabs[which];
  599. if (removeit){
  600. tabs.splice(which, 1);
  601. }
  602. }
  603. } else {
  604. var tmp = $('<span></span>');
  605. for(var i=0; i<tabs.length; i++){
  606. var p = tabs[i];
  607. tmp.html(p.panel('options').title);
  608. var title = tmp.text();
  609. tmp.html(which);
  610. which = tmp.text();
  611. if (title == which){
  612. tab = p;
  613. if (removeit){
  614. tabs.splice(i, 1);
  615. }
  616. break;
  617. }
  618. }
  619. tmp.remove();
  620. }
  621. return tab;
  622. }
  623. function getTabIndex(container, tab){
  624. var tabs = $.data(container, 'tabs').tabs;
  625. for(var i=0; i<tabs.length; i++){
  626. if (tabs[i][0] == $(tab)[0]){
  627. return i;
  628. }
  629. }
  630. return -1;
  631. }
  632. function getSelectedTab(container){
  633. var tabs = $.data(container, 'tabs').tabs;
  634. for(var i=0; i<tabs.length; i++){
  635. var tab = tabs[i];
  636. if (tab.panel('options').tab.hasClass('tabs-selected')){
  637. return tab;
  638. }
  639. }
  640. return null;
  641. }
  642. /**
  643. * do first select action, if no tab is setted the first tab will be selected.
  644. */
  645. function doFirstSelect(container){
  646. var state = $.data(container, 'tabs')
  647. var tabs = state.tabs;
  648. for(var i=0; i<tabs.length; i++){
  649. var opts = tabs[i].panel('options');
  650. if (opts.selected && !opts.disabled){
  651. selectTab(container, i);
  652. return;
  653. }
  654. }
  655. selectTab(container, state.options.selected);
  656. }
  657. function selectTab(container, which){
  658. var p = getTab(container, which);
  659. if (p && !p.is(':visible')){
  660. stopAnimate(container);
  661. if (!p.panel('options').disabled){
  662. p.panel('open');
  663. }
  664. }
  665. }
  666. function unselectTab(container, which){
  667. var p = getTab(container, which);
  668. if (p && p.is(':visible')){
  669. stopAnimate(container);
  670. p.panel('close');
  671. }
  672. }
  673. function stopAnimate(container){
  674. $(container).children('div.tabs-panels').each(function(){
  675. $(this).stop(true, true);
  676. });
  677. }
  678. function exists(container, which){
  679. return getTab(container, which) != null;
  680. }
  681. function showHeader(container, visible){
  682. var opts = $.data(container, 'tabs').options;
  683. opts.showHeader = visible;
  684. $(container).tabs('resize');
  685. }
  686. function showTool(container, visible){
  687. var tool = $(container).find('>.tabs-header>.tabs-tool');
  688. if (visible){
  689. tool.removeClass('tabs-tool-hidden').show();
  690. } else {
  691. tool.addClass('tabs-tool-hidden').hide();
  692. }
  693. $(container).tabs('resize').tabs('scrollBy', 0);
  694. }
  695. $.fn.tabs = function(options, param){
  696. if (typeof options == 'string') {
  697. return $.fn.tabs.methods[options](this, param);
  698. }
  699. options = options || {};
  700. return this.each(function(){
  701. var state = $.data(this, 'tabs');
  702. if (state) {
  703. $.extend(state.options, options);
  704. } else {
  705. $.data(this, 'tabs', {
  706. options: $.extend({},$.fn.tabs.defaults, $.fn.tabs.parseOptions(this), options),
  707. tabs: [],
  708. selectHis: []
  709. });
  710. wrapTabs(this);
  711. }
  712. addTools(this);
  713. setProperties(this);
  714. setSize(this);
  715. bindEvents(this);
  716. doFirstSelect(this);
  717. });
  718. };
  719. $.fn.tabs.methods = {
  720. options: function(jq){
  721. var cc = jq[0];
  722. var opts = $.data(cc, 'tabs').options;
  723. var s = getSelectedTab(cc);
  724. opts.selected = s ? getTabIndex(cc, s) : -1;
  725. return opts;
  726. },
  727. tabs: function(jq){
  728. return $.data(jq[0], 'tabs').tabs;
  729. },
  730. resize: function(jq, param){
  731. return jq.each(function(){
  732. setSize(this, param);
  733. setSelectedSize(this);
  734. });
  735. },
  736. add: function(jq, options){
  737. return jq.each(function(){
  738. addTab(this, options);
  739. });
  740. },
  741. close: function(jq, which){
  742. return jq.each(function(){
  743. closeTab(this, which);
  744. });
  745. },
  746. getTab: function(jq, which){
  747. return getTab(jq[0], which);
  748. },
  749. getTabIndex: function(jq, tab){
  750. return getTabIndex(jq[0], tab);
  751. },
  752. getSelected: function(jq){
  753. return getSelectedTab(jq[0]);
  754. },
  755. select: function(jq, which){
  756. return jq.each(function(){
  757. selectTab(this, which);
  758. });
  759. },
  760. unselect: function(jq, which){
  761. return jq.each(function(){
  762. unselectTab(this, which);
  763. });
  764. },
  765. exists: function(jq, which){
  766. return exists(jq[0], which);
  767. },
  768. update: function(jq, options){
  769. return jq.each(function(){
  770. updateTab(this, options);
  771. });
  772. },
  773. enableTab: function(jq, which){
  774. return jq.each(function(){
  775. var opts = $(this).tabs('getTab', which).panel('options');
  776. opts.tab.removeClass('tabs-disabled');
  777. opts.disabled = false;
  778. });
  779. },
  780. disableTab: function(jq, which){
  781. return jq.each(function(){
  782. var opts = $(this).tabs('getTab', which).panel('options');
  783. opts.tab.addClass('tabs-disabled');
  784. opts.disabled = true;
  785. });
  786. },
  787. showHeader: function(jq){
  788. return jq.each(function(){
  789. showHeader(this, true);
  790. });
  791. },
  792. hideHeader: function(jq){
  793. return jq.each(function(){
  794. showHeader(this, false);
  795. });
  796. },
  797. showTool: function(jq){
  798. return jq.each(function(){
  799. showTool(this, true);
  800. });
  801. },
  802. hideTool: function(jq){
  803. return jq.each(function(){
  804. showTool(this, false);
  805. });
  806. },
  807. scrollBy: function(jq, deltaX){ // scroll the tab header by the specified amount of pixels
  808. return jq.each(function(){
  809. var opts = $(this).tabs('options');
  810. var wrap = $(this).find('>div.tabs-header>div.tabs-wrap');
  811. var pos = Math.min(wrap._scrollLeft() + deltaX, getMaxScrollWidth());
  812. wrap.animate({scrollLeft: pos}, opts.scrollDuration);
  813. function getMaxScrollWidth(){
  814. var w = 0;
  815. var ul = wrap.children('ul');
  816. ul.children('li').each(function(){
  817. w += $(this).outerWidth(true);
  818. });
  819. return w - wrap.width() + (ul.outerWidth() - ul.width());
  820. }
  821. });
  822. }
  823. };
  824. $.fn.tabs.parseOptions = function(target){
  825. return $.extend({}, $.parser.parseOptions(target, [
  826. 'tools','toolPosition','tabPosition',
  827. {fit:'boolean',border:'boolean',plain:'boolean'},
  828. {headerWidth:'number',tabWidth:'number',tabHeight:'number',selected:'number'},
  829. {showHeader:'boolean',justified:'boolean',narrow:'boolean',pill:'boolean'}
  830. ]));
  831. };
  832. $.fn.tabs.defaults = {
  833. width: 'auto',
  834. height: 'auto',
  835. headerWidth: 150, // the tab header width, it is valid only when tabPosition set to 'left' or 'right'
  836. tabWidth: 'auto', // the tab width
  837. // tabHeight: 27, // the tab height
  838. tabHeight: 32, // the tab height
  839. selected: 0, // the initialized selected tab index
  840. showHeader: true,
  841. plain: false,
  842. fit: false,
  843. border: true,
  844. justified: false,
  845. narrow: false,
  846. pill: false,
  847. tools: null,
  848. toolPosition: 'right', // left,right,top,bottom
  849. tabPosition: 'top', // possible values: top,bottom
  850. scrollIncrement: 100,
  851. scrollDuration: 400,
  852. onLoad: function(panel){},
  853. onSelect: function(title, index){},
  854. onUnselect: function(title, index){},
  855. onBeforeClose: function(title, index){},
  856. onClose: function(title, index){},
  857. onAdd: function(title, index){},
  858. onUpdate: function(title, index){},
  859. onContextMenu: function(e, title, index){}
  860. };
  861. })(jQuery);