/** * tabs - jQuery EasyUI * * Licensed under the GPL terms * To use it on other terms please contact us * * Copyright(c) 2009-2012 stworthy [ stworthy@gmail.com ] * * Dependencies: * panel * linkbutton * */ (function($){ /** * get the max tabs scroll width(scope) */ function getMaxScrollWidth(container) { var header = $(container).children('div.tabs-header'); var tabsWidth = 0; // all tabs width $('ul.tabs li', header).each(function(){ tabsWidth += $(this).outerWidth(true); }); var wrapWidth = header.children('div.tabs-wrap').width(); var padding = parseInt(header.find('ul.tabs').css('padding-left')); return tabsWidth - wrapWidth + padding; } /** * set the tabs scrollers to show or not, * dependent on the tabs count and width */ function setScrollers(container) { var opts = $.data(container, 'tabs').options; var header = $(container).children('div.tabs-header'); var tool = header.children('div.tabs-tool'); var sLeft = header.children('div.tabs-scroller-left'); var sRight = header.children('div.tabs-scroller-right'); var wrap = header.children('div.tabs-wrap'); // set the tool height tool._outerHeight(header.outerHeight() - (opts.plain ? 2 : 0)); var tabsWidth = 0; $('ul.tabs li', header).each(function(){ tabsWidth += $(this).outerWidth(true); }); var cWidth = header.width() - tool._outerWidth(); if (tabsWidth > cWidth) { sLeft.show(); sRight.show(); tool.css('right', sRight.outerWidth()); wrap.css({ marginLeft: sLeft.outerWidth(), marginRight: sRight.outerWidth() + tool._outerWidth(), left: 0, width: cWidth - sLeft.outerWidth() - sRight.outerWidth() }); } else { sLeft.hide(); sRight.hide(); tool.css('right', 0); wrap.css({ marginLeft:0, marginRight:tool._outerWidth(), left: 0, width: cWidth }); wrap.scrollLeft(0); } } function addTools(container){ var opts = $.data(container, 'tabs').options; var header = $(container).children('div.tabs-header'); if (opts.tools) { if (typeof opts.tools == 'string'){ $(opts.tools).addClass('tabs-tool').appendTo(header); $(opts.tools).show(); } else { header.children('div.tabs-tool').remove(); var tools = $('
').appendTo(header); for(var i=0; i').appendTo(tools); tool[0].onclick = eval(opts.tools[i].handler || function(){}); tool.linkbutton($.extend({}, opts.tools[i], { plain: true })); } } } else { header.children('div.tabs-tool').remove(); } } function setSize(container) { var opts = $.data(container, 'tabs').options; var cc = $(container); if (opts.fit == true){ var p = cc.parent(); p.addClass('panel-noscroll'); if (p[0].tagName == 'BODY') $('html').addClass('panel-fit'); opts.width = p.width(); opts.height = p.height(); } cc.width(opts.width).height(opts.height); var header = $(container).children('div.tabs-header'); header._outerWidth(opts.width); setScrollers(container); var panels = $(container).children('div.tabs-panels'); var height = opts.height; if (!isNaN(height)) { panels._outerHeight(height - header.outerHeight()); } else { panels.height('auto'); } var width = opts.width; if (!isNaN(width)){ panels._outerWidth(width); } else { panels.width('auto'); } } /** * set selected tab panel size */ function setSelectedSize(container){ var opts = $.data(container, 'tabs').options; var tab = getSelectedTab(container); if (tab){ var panels = $(container).children('div.tabs-panels'); var width = opts.width=='auto' ? 'auto' : panels.width(); var height = opts.height=='auto' ? 'auto' : panels.height(); tab.panel('resize', { width: width, height: height }); } } /** * wrap the tabs header and body */ function wrapTabs(container) { var tabs = $.data(container, 'tabs').tabs; var cc = $(container); cc.addClass('tabs-container'); cc.wrapInner('
'); $('
' + '
' + '
' + '
' + '
    ' + '
    ' + '
    ').prependTo(container); cc.children('div.tabs-panels').children('div').each(function(i){ var opts = $.extend({}, $.parser.parseOptions(this), { selected: ($(this).attr('selected') ? true : undefined) }); var pp = $(this); tabs.push(pp); createTab(container, pp, opts); }); cc.children('div.tabs-header').find('.tabs-scroller-left, .tabs-scroller-right').hover( function(){$(this).addClass('tabs-scroller-over');}, function(){$(this).removeClass('tabs-scroller-over');} ); cc.bind('_resize', function(e,force){ var opts = $.data(container, 'tabs').options; if (opts.fit == true || force){ setSize(container); setSelectedSize(container); } return false; }); } function setProperties(container){ var opts = $.data(container, 'tabs').options; var header = $(container).children('div.tabs-header'); var panels = $(container).children('div.tabs-panels'); if (opts.plain == true) { header.addClass('tabs-header-plain'); } else { header.removeClass('tabs-header-plain'); } if (opts.border == true){ header.removeClass('tabs-header-noborder'); panels.removeClass('tabs-panels-noborder'); } else { header.addClass('tabs-header-noborder'); panels.addClass('tabs-panels-noborder'); } $('.tabs-scroller-left', header).unbind('.tabs').bind('click.tabs', function(){ var wrap = $('.tabs-wrap', header); var pos = wrap.scrollLeft() - opts.scrollIncrement; wrap.animate({scrollLeft:pos}, opts.scrollDuration); }); $('.tabs-scroller-right', header).unbind('.tabs').bind('click.tabs', function(){ var wrap = $('.tabs-wrap', header); var pos = Math.min( wrap.scrollLeft() + opts.scrollIncrement, getMaxScrollWidth(container) ); wrap.animate({scrollLeft:pos}, opts.scrollDuration); }); } function createTab(container, pp, options) { var state = $.data(container, 'tabs'); options = options || {}; // create panel pp.panel($.extend({}, options, { border: false, noheader: true, closed: true, doSize: false, iconCls: (options.icon ? options.icon : undefined), onLoad: function(){ if (options.onLoad){ options.onLoad.call(this, arguments); } state.options.onLoad.call(container, $(this)); } })); var opts = pp.panel('options'); var tabs = $(container).children('div.tabs-header').find('ul.tabs'); opts.tab = $('
  • ').appendTo(tabs); // set the tab object in panel options opts.tab.append( '' + '' + '' + '' ); opts.tab.unbind('.tabs').bind('click.tabs', {p:pp}, function(e){ if ($(this).hasClass('tabs-disabled')){return;} selectTab(container, getTabIndex(container, e.data.p)); }).bind('contextmenu.tabs', {p:pp}, function(e){ if ($(this).hasClass('tabs-disabled')){return;} state.options.onContextMenu.call(container, e, $(this).find('span.tabs-title').html(), getTabIndex(container, e.data.p)); }); updateTab(container, { tab: pp, options: opts }); } function addTab(container, options) { var opts = $.data(container, 'tabs').options; var tabs = $.data(container, 'tabs').tabs; if (options.selected == undefined) options.selected = true; var pp = $('
    ').appendTo($(container).children('div.tabs-panels')); tabs.push(pp); createTab(container, pp, options); opts.onAdd.call(container, options.title, tabs.length-1); setScrollers(container); if (options.selected){ selectTab(container, tabs.length-1); // select the added tab panel } } /** * update tab panel, param has following properties: * tab: the tab panel to be updated * options: the tab panel options */ function updateTab(container, param){ var selectHis = $.data(container, 'tabs').selectHis; var pp = param.tab; // the tab panel var oldTitle = pp.panel('options').title; pp.panel($.extend({}, param.options, { iconCls: (param.options.icon ? param.options.icon : undefined) })); var opts = pp.panel('options'); // get the tab panel options var tab = opts.tab; var s_title = tab.find('span.tabs-title'); var s_icon = tab.find('span.tabs-icon'); s_title.html(opts.title); s_icon.attr('class', 'tabs-icon'); tab.find('a.tabs-close').remove(); if (opts.closable){ s_title.addClass('tabs-closable'); var a_close = $('').appendTo(tab); a_close.bind('click.tabs', {p:pp}, function(e){ if ($(this).parent().hasClass('tabs-disabled')){return;} closeTab(container, getTabIndex(container, e.data.p)); return false; }); } else{ s_title.removeClass('tabs-closable'); } if (opts.iconCls){ s_title.addClass('tabs-with-icon'); s_icon.addClass(opts.iconCls); } else { s_title.removeClass('tabs-with-icon'); } if (oldTitle != opts.title){ for(var i=0; i').insertAfter(tab.find('a.tabs-inner')); if (typeof opts.tools == 'string'){ $(opts.tools).children().appendTo(p_tool); } else { for(var i=0; i').appendTo(p_tool); t.addClass(opts.tools[i].iconCls); if (opts.tools[i].handler){ // t.bind('click', eval(opts.tools[i].handler)); t.bind('click', {handler:opts.tools[i].handler}, function(e){ if ($(this).parents('li').hasClass('tabs-disabled')){return;} e.data.handler.call(this); }); } } } var pr = p_tool.children().length * 12; if (opts.closable) { pr += 8; } else { pr -= 3; p_tool.css('right','5px'); } s_title.css('padding-right', pr+'px'); } // setProperties(container); setScrollers(container); $.data(container, 'tabs').options.onUpdate.call(container, opts.title, getTabIndex(container, pp)); } /** * close a tab with specified index or title */ function closeTab(container, which) { var opts = $.data(container, 'tabs').options; var tabs = $.data(container, 'tabs').tabs; var selectHis = $.data(container, 'tabs').selectHis; if (!exists(container, which)) return; var tab = getTab(container, which); var title = tab.panel('options').title; var index = getTabIndex(container, tab); if (opts.onBeforeClose.call(container, title, index) == false) return; var tab = getTab(container, which, true); tab.panel('options').tab.remove(); tab.panel('destroy'); opts.onClose.call(container, title, index); setScrollers(container); // remove the select history item for(var i=0; i= tabs.length){ return null; } else { var tab = tabs[which]; if (removeit) { tabs.splice(which, 1); } return tab; } } for(var i=0; idiv.tabs-header div.tabs-wrap'); var leftPos = tab.position().left + wrap.scrollLeft(); var left = leftPos - wrap.scrollLeft(); var right = left + tab.outerWidth(); if (left < 0 || right > wrap.innerWidth()) { var pos = Math.min( leftPos - (wrap.width()-tab.width()) / 2, getMaxScrollWidth(container) ); wrap.animate({scrollLeft:pos}, opts.scrollDuration); } else { var pos = Math.min( wrap.scrollLeft(), getMaxScrollWidth(container) ); wrap.animate({scrollLeft:pos}, opts.scrollDuration); } setSelectedSize(container); opts.onSelect.call(container, title, getTabIndex(container, panel)); } function exists(container, which){ return getTab(container, which) != null; } $.fn.tabs = function(options, param){ if (typeof options == 'string') { return $.fn.tabs.methods[options](this, param); } options = options || {}; return this.each(function(){ var state = $.data(this, 'tabs'); var opts; if (state) { opts = $.extend(state.options, options); state.options = opts; } else { $.data(this, 'tabs', { options: $.extend({},$.fn.tabs.defaults, $.fn.tabs.parseOptions(this), options), tabs: [], selectHis: [] }); wrapTabs(this); } addTools(this); setProperties(this); setSize(this); doFirstSelect(this); }); }; $.fn.tabs.methods = { options: function(jq){ return $.data(jq[0], 'tabs').options; }, tabs: function(jq){ return $.data(jq[0], 'tabs').tabs; }, resize: function(jq){ return jq.each(function(){ setSize(this); setSelectedSize(this); }); }, add: function(jq, options){ return jq.each(function(){ addTab(this, options); }); }, close: function(jq, which){ return jq.each(function(){ closeTab(this, which); }); }, getTab: function(jq, which){ return getTab(jq[0], which); }, getTabIndex: function(jq, tab){ return getTabIndex(jq[0], tab); }, getSelected: function(jq){ return getSelectedTab(jq[0]); }, select: function(jq, which){ return jq.each(function(){ selectTab(this, which); }); }, exists: function(jq, which){ return exists(jq[0], which); }, update: function(jq, options){ return jq.each(function(){ updateTab(this, options); }); }, enableTab: function(jq, which){ return jq.each(function(){ $(this).tabs('getTab', which).panel('options').tab.removeClass('tabs-disabled'); }); }, disableTab: function(jq, which){ return jq.each(function(){ $(this).tabs('getTab', which).panel('options').tab.addClass('tabs-disabled'); }); } }; $.fn.tabs.parseOptions = function(target){ return $.extend({}, $.parser.parseOptions(target, [ 'width','height','tools', {fit:'boolean',border:'boolean',plain:'boolean'} ])); }; $.fn.tabs.defaults = { width: 'auto', height: 'auto', plain: false, fit: false, border: true, tools: null, scrollIncrement: 100, scrollDuration: 400, onLoad: function(panel){}, onSelect: function(title, index){}, onBeforeClose: function(title, index){}, onClose: function(title, index){}, onAdd: function(title, index){}, onUpdate: function(title, index){}, onContextMenu: function(e, title, index){} }; })(jQuery);