/*
# ***** BEGIN LICENSE BLOCK *****
# Assets Library - The open source PHP/JavaScript/CSS library of Les Ateliers Pierrot
# Copyleft (c) 2013-2014 Pierre Cassat and contributors
# <www.ateliers-pierrot.fr> - <contact@ateliers-pierrot.fr>
# License GPL-3.0 <http://www.opensource.org/licenses/gpl-3.0.html>
# Sources <http://github.com/atelierspierrot/assets-library>
#
# Ce programme est un logiciel libre distribué sous licence GNU/GPL.
#
# ***** END LICENSE BLOCK ***** */
/**
* Build a set of tabs from a list of handlers links toggling a list of tab contents.
*/
function TabContent() {
// all object default properties
this._selectors_tabs = {};
this._handlers_tabs = {};
this._contents_tabs = {};
this._indexed_tabs_ids = [];
this._silent = false;
this._handler_list_id = 'tabs';
this._handler_list_el = 'ul';
this._handler_item_el = 'li';
this._tab_selector_el = 'a';
this._tab_selector_attribute = 'href';
this._show_class = 'selected';
this._hide_class = 'hide';
this._collapsible = false;
this._cookie_name = 'jstabs';
this._use_cookie = true;
// initialization of the whole TAB object
this.init = function() {
var _cookie, _collapse,
tabList = document.getElementById(this._handler_list_id);
if (tabList) {
// grab the tab links and content divs from the page
var children = tabList.childNodes;
for (var i=0, len=children.length; i<len; i++) {
if (children[i].nodeName.toLowerCase()===this._handler_item_el) {
var tabLink = getFirstChildByTagName( children[i], this._tab_selector_el );
if (tabLink) {
var id = getHash( tabLink.getAttribute(this._tab_selector_attribute) );
if (id) {
this._indexed_tabs_ids.push(id);
this._handlers_tabs[id] = children[i];
this._selectors_tabs[id] = tabLink;
this._contents_tabs[id] = document.getElementById( id );
}
}
}
}
// get the cookie value if so
if (this._use_cookie) {
var _cookie = getCookie( this._cookie_name );
if (_cookie && -1!=_cookie.lastIndexOf(':')) {
_cook_tbl = _cookie.split(":");
_cookie = _cook_tbl[1];
_collapse = _cook_tbl[0];
}
}
// assign onclick events to the tab links
// highlight the first tab
var i=0, _this=this;
for (var id in this._selectors_tabs) {
this._selectors_tabs[id].onclick = function(e,s){ return toggleTabEvent(e, s, _this); };
this._selectors_tabs[id].onfocus = function(e){ this.blur(); };
if (this._use_cookie && _cookie!==null) {
if (_cookie===id) {
if (_collapse!==undefined && _collapse==="collapse") {
this.showTab( getHash( this._selectors_tabs[id].getAttribute(this._tab_selector_attribute) ), true );
}
else {
this.showTab( getHash( this._selectors_tabs[id].getAttribute(this._tab_selector_attribute) ) );
}
}
}
else if (i==0) {
this.showTab( getHash( this._selectors_tabs[id].getAttribute(this._tab_selector_attribute) ) );
}
i++;
}
}
else if (!this._silent) {
throw new Error('Handlers list for TABS not found!');
}
};
// ------------------
// PUBLIC METHODS
// ------------------
// show a specific tab by its ID (and collapse it if "_collapse==true")
this.showTab = function(_sel, _collapse) {
var sel = _sel || getHash( this.getAttribute(this._tab_selector_attribute) );
var collapse = _collapse || false;
// Highlight the selected tab, and dim all others.
// Also show the selected content div, and hide all others.
for (var id in this._contents_tabs) {
if (id===sel) {
if (collapse && this._collapsible && !hasClassName(this._contents_tabs[id], this._hide_class)) {
removeClassName( this._selectors_tabs[id], this._show_class );
removeClassName( this._handlers_tabs[id], this._show_class );
addClassName( this._contents_tabs[id], this._hide_class );
if (this._use_cookie) {
setCookie( 'collapse:'+id, this._cookie_name );
}
}
else {
addClassName( this._selectors_tabs[id], this._show_class );
addClassName( this._handlers_tabs[id], this._show_class );
removeClassName( this._contents_tabs[id], this._hide_class );
if (this._use_cookie) {
setCookie( id, this._cookie_name );
}
}
}
else {
removeClassName( this._selectors_tabs[id], this._show_class );
removeClassName( this._handlers_tabs[id], this._show_class );
addClassName( this._contents_tabs[id], this._hide_class );
}
}
};
// open next tab
this.nextTab = function() {
var j, _selected = this.getSelectedTab();
for (var i=0, len=this._indexed_tabs_ids.length; i<len; i++) {
j = parseInt(i+1);
if (this._indexed_tabs_ids[i]==_selected) {
if (i===len-1) {
return this.showTab(this._indexed_tabs_ids[0]);
}
else {
return this.showTab(this._indexed_tabs_ids[j]);
}
}
}
};
// open previous tab
this.previousTab = function() {
var j, _selected = this.getSelectedTab();
for (var i=0, len=this._indexed_tabs_ids.length; i<len; i++) {
j = parseInt(i-1);
if (this._indexed_tabs_ids[i]==_selected) {
if (i===0) {
return this.showTab(this._indexed_tabs_ids[len-1]);
}
else {
return this.showTab(this._indexed_tabs_ids[j]);
}
}
}
};
// get selected tab ID
this.getSelectedTab = function() {
for (var id in this._contents_tabs) {
if (!hasClassName(this._contents_tabs[id], this._hide_class)) {
return id;
}
}
return false;
};
// ------------------
// PRIVATE METHODS
// ------------------
// toggle the "showTab()" method on click event
var toggleTabEvent = function( e, _sel, _this ) {
var sel = _sel || getHash( e.target.getAttribute(_this._tab_selector_attribute) );
_this.showTab( sel, true );
// stop the browser following the link
return false;
},
getFirstChildByTagName = function( element, tagName ) {
for (var i=0; i<element.childNodes.length; i++) {
if (element.childNodes[i].nodeName.toLowerCase()===tagName) {
return element.childNodes[i];
}
}
},
getHash = function( url ) {
if (url===undefined || url===null) { return false; }
var hashPos = url.lastIndexOf('#');
return url.substring( hashPos+1 );
};
if (arguments.length) { extend(this, arguments[0], '_%s'); }
if (typeof window['_dbg_info'] == 'function')
_dbg_info("[Tab Content] Creating new tabs with :"
+"\n _handler_list_id: "+this._handler_list_id
+"\n _handler_list_el: "+this._handler_list_el
+"\n _handler_item_el: "+this._handler_item_el
+"\n _tab_selector_el: "+this._tab_selector_el
+"\n _tab_selector_attribute: "+this._tab_selector_attribute
+"\n _show_class: "+this._show_class
+"\n _hide_class: "+this._hide_class
+"\n _collapsible: "+this._collapsible
+"\n _use_cookie: "+this._use_cookie
+"\n _cookie_name: "+this._cookie_name
+"\n _silent: "+this._silent
);
this.init();
return this;
};
// Endfile