/**
* jquery.mtabify.js - insert tabs over or under a group of block elements.
*
* @name mTabify
* @description Make tabs over or under a group of panel elements. Tabs can be
* automatically constructed or exist in the document as
lists.
* If the page url has a hash matching a panel id, that panel and tab are
* made active. Panels without ids are automatically assigned one.
* A callback function can be specified to execute before activating
* a tab. Its argument is the panel id to activate and "this" is the tab
* being clicked. Returning false cancels the tab's click() event.
* @version .31
* @requires jquery 1.6
*
* @usage $('#div1,#div2,#div3').mTabify('Tab Name 1,Tab Name 2,Tab Name 3');
* @usage $('#div1,#div2,#div3').mTabify(['Tab Name 1','Tab Name 2','Tab Name 3']);
* @usage $('#div1,#div2,#div3').mTabify({
* names: ['Tab Name 1','Tab Name 2','Tab Name 3'],
* titles: ['Tab Title 1','Tab Title 2','Tab Title 3'],
* callback: function(){ // code executed when tab clicked just before showing tab },
* before: selector,
* after: selector,
* });
*
* @author Mack Pexton
* @author-email mack@mackpexton.com
* @author-website http://www.mackpexton.com
*
* @license MIT License - http://www.opensource.org/licenses/mit-license.php
* @credits Jan Jarfalk for jquery.tabify.js
*/
(function($){
var default_options = {
names : [], // names displayed on tabs
titles : [], // popup tool-tips
callback : function(){return true;}, // function called before showing tab panel
before : null, // insert tabs before element
after : null, // append tabs after element
tabs : null, // selector of optional pre-defined tab element(s)
tabs_class : 'tabs', // class associated with list of tabs
tab_class_active : 'active', // class added to tab when active
tab_class_inactive : '', // class added to tab when in-active
panel_class_active : 'active', // class added to panel element when visible
panel_class_inactive : '', // class added to panel element when hidden
},
tabs_index = 0,
make_tabs_id = function(index) {
return 'tabs' + (tabs_index++);
},
panels_index = 0,
make_panel_id = function(index) {
return 'panel' + (panels_index++);
};
$.fn.mTabify = function(arg) {
var opt = $.extend({},default_options,(
(arg == null) ? {}
: (typeof arg == 'string') ? { 'names' : arg.split(',') }
: (typeof arg == 'array') ? { 'names' : arg }
: (typeof arg == 'object') ? arg
: {}
)),
$panels = $(this),
$tabs = opt['tabs'] ? $(opt['tabs']) : $(''),
$before_tabs = $(),
$after_tabs = $(),
active_id = (location.hash && $(this).is(location.hash)) ? location.hash.substr(1) : '',
is_active = function(panel_id,index){
return active_id ? (active_id == panel_id) : (index == 0);
},
inactivate_tab = function($tab){
if (opt['tab_class_active']) $tab.removeClass(opt['tab_class_active']);
if (opt['tab_class_inactive']) $tab.addClass(opt['tab_class_inactive']);
},
inactivate_panel = function($panel){
if (opt['panel_class_active']) $panel.removeClass(opt['panel_class_active']);
if (opt['panel_class_inactive']) $panel.addClass(opt['panel_class_inactive']);
$panel.hide();
},
activate_tab = function($tab){
if (opt['tab_class_inactive']) $tab.removeClass(opt['tab_class_inactive']);
if (opt['tab_class_active']) $tab.addClass(opt['tab_class_active']);
},
activate_panel = function($panel){
if (opt['panel_class_inactive']) $panel.removeClass(opt['panel_class_inactive']);
if (opt['panel_class_active']) $panel.addClass(opt['panel_class_active']);
$panel.show();
};
if (opt['tabs_class']) $tabs.addClass(opt['tabs_class']);
// Scan panels and construct tabs html.
$panels.each(function(index){
if (!this.id) this.id = make_panel_id(index);
var name = opt['names'][index] ? opt['names'][index] : this.id,
tab_title_html = opt['titles'][index] ? ' title="'+opt['titles'][index]+'"' : '',
tab_class_html, tab_class, panel_class,
$this = $(this);
if (is_active(this.id,index)) {
tab_class = opt['tab_class_active'];
panel_class = opt['panel_class_active'];
$this.show();
}
else {
tab_class = opt['tab_class_inactive'];
panel_class = opt['panel_class_inactive'];
$this.hide();
}
if (opt['tabs']) {
if (tab_class) {
$tabs.each(function(){
$('li',this).eq(index).addClass(tab_class);
});
}
}
else {
tab_class_html = tab_class ? ' class="'+tab_class+'"' : '';
$tabs.append('- '+name+'
');
}
// Set initial panel class.
if (panel_class) { $this.addClass(panel_class); }
});
// Assign click handler to tabs links.
$('a',$tabs).click(function(e){
var panel_id = $(this).prop('href').replace(/.*#/,''); // strip '#' off of href
if (typeof opt['callback'] == 'function' && opt['callback'].apply(e.target.parentNode,[panel_id]) === false) return false;
$tabs.find('li').each(function(){inactivate_tab($(this))});
$panels.each(function(){inactivate_panel($(this))});
$tabs.find('[href=#'+panel_id+']').each(function(index){
activate_tab($(this).parent());
});
activate_panel($('#'+panel_id));
return false;
});
if (opt['tabs']) return; // tabs already in document
// Insert tabs into document.
if (opt['before']) {
$before_tabs = $tabs;
$before_tabs.insertBefore(opt['before']);
}
if (opt['after']) {
$after_tabs = opt['before'] ? $tabs.clone(true) : $tabs;
$after_tabs.insertAfter(opt['after']);
if (opt['before']) $tabs = $tabs.add($after_tabs);
}
if (!(opt['before'] || opt['after'])) {
$before_tabs = $tabs;
$before_tabs.insertBefore($panels.get(0));
}
// Assign ids to each group of tabs to facilitate CSS.
$tabs.each(function(index){
if (! $(this).prop('id')) $(this).prop('id',make_tabs_id(index));
});
};
})(jQuery);