1
0
mirror of https://github.com/e107inc/e107.git synced 2025-10-10 04:24:45 +02:00
Files
php-e107/e107_files/jslib/core/tabs.js
2008-11-21 16:26:15 +00:00

322 lines
8.1 KiB
JavaScript

/*
* e107 website system
*
* Copyright (c) 2001-2008 e107 Developers (e107.org)
* Released under the terms and conditions of the
* GNU General Public License (http://gnu.org).
*
* e107Widget.Tabs Class
*
* Create tabs, supports ajax/inline content, browser history & bookmarks
* (unobtrusive Javascript)
*
* $Source: /cvs_backup/e107_0.8/e107_files/jslib/core/tabs.js,v $
* $Revision: 1.2 $
* $Date: 2008-11-21 16:26:15 $
* $Author: secretr $
*
*/
/**
* Global prefs
*/
e107Base.setPrefs('core-tabs', {
bookmarkFix: true,
historyNavigation: false,
pageOverlay: false,
elementOverlay: true,
ajaxCache: true
});
e107Widgets.Tabs = Class.create(e107WidgetAbstract, {
Version: '1.0',
initialize: function(container, options) {
this.events = new e107EventManager(this);
var optHandlers = {
show: this.show,
hide: this.hide
}
Object.extend(optHandlers , options || {});
this.global = this;
this.initMod('core-tabs', optHandlers).__initTabData(container);
},
__initTabData: function(container) {
var cstring, celement = $(container);
if(null === celement)
throw('e107Widgets.Tabs: invalid value for container'); //TODO Lan
if(Object.isString(container)) {
cstring = container;
} else if(Object.isElement(container)) {
cstring = celement.identify();
}
this.histotyHash = ('etab-' + cstring).camelize();
if(!this.getModCache('-data')) {
this.setModCache('-data', {});
}
this.tabData = this.getModCache('-data')['ref-' + cstring];
this._observer = this.observer.bindAsEventListener(this); //click observer
if(!this.tabData && !this.___initialized) {
if(this.options.bookmarkFix || this.options.historyNavigation) this.options.history = true;
this.___methods = $w('show hide select tabSelect ajaxSelect visible getPanelId getMenuId startObserve stopObserve getPanelId getPanel getMenuId getMenu');
this.tabData = {
container: celement,
list: $A()
}
celement.select('ul.e-tabs > li').inject(this.tabData.list, function(arr, elitem, i) {
var mid = elitem.identify(),
a = elitem.select('a')[0],
act = a.hash.substr(1),
cid = $(act);
var that = this;
arr[i] = { Index: i, menuId: mid, menu: elitem, menuAction: act, actionItem: a, panel: cid, panelId: cid.id, ajaxUrl: a.readAttribute('rel'), global: that, exec: that._exec.bind(that, i) };
this._extendTab(arr[i]);
return arr;
}.bind(this));
this.exec_recursive('hide').getDefault().select();
this.startEvents();
this.___initialized = true;
this.getModCache('-data')['ref-' + cstring] = this.tabData;
}
},
_extendTab: function(data) {
this.___methods.inject(data, function(obj, method) {
obj[method] = this[method].bind(this, obj);
return obj;
}.bind(this));
data.events = new e107EventManager(this);
data.options = this.options;
data.histotyHash = this.histotyHash;
return this._detectLoad(data);
},
_detectLoad: function(tab) {
if(tab.ajaxUrl) {
var lopts = $w(tab.ajaxUrl).detect(function (values) {
return values.startsWith('ajax-tab');
});
if(lopts) {
var link = tab.actionItem.readAttribute('href').split('#')[0]; //link url
tab.ajaxUrl = link ? link : document.location.href.split('#')[0]; //self url
}
return tab;
}
tab.ajaxUrl = false;
return tab;
},
_exec: function(index, method, options) {
if(!this.___methods.include(method) || !this.tabData.list[index]) {
throw('e107Widgets.Tabs._exec: wrong method or object not found!');
}
this.tabData.list[index][method](options);
return this.tabData.list[index];
},
/**
* Available only in instance' global scope
*/
exec: function(index, method, options) {
this.tabData.list[index].exec(method, options || {});
return this;
},
/**
* Available only in instance' global scope
*/
exec_recursive: function(method, except, options) {
if(except)
this.tabData.list.without(except).invoke('exec', method, options || {});
else
this.tabData.list.invoke('exec', method, options || {});
return this;
},
_getTabByIdnex: function(index) {
return this.tabData.list[index] || null;
},
_getTabByPanelId: function(name) {
return this.tabData.list.find(function(tab_obj) { return tab_obj.getPanelId() == name }) || null;
},
/**
* Available only in instance' global scope
*/
get: function(tab) {
if(Object.isNumber(tab))
return this._getTabByIdnex(tab);
else if(Object.isString(tab))
return this._getTabByPanelId(tab);
return tab;
},
getPanelId: function(tab_obj) {
return tab_obj.panelId;
},
getPanel: function(tab_obj) {
return tab_obj.panel;
},
getMenuId: function(tab_obj) {
return tab_obj.menuId;
},
getMenu: function(tab_obj) {
return tab_obj.menu;
},
/**
* Available only in instance' global scope
*/
getDefault: function() {
var current = e107History.get(this.histotyHash);
if(current) {
var tab = this.get(current) || this.tabData.list[0];
this._active = tab.Index;
return tab;
}
this._active = 0;
return this.tabData.list[0];
},
getActive: function() {
if(!this.global._active) {
var _active = this.tabData.list.find(function(tab_obj) { return tab_obj.visible(); }) || null;
if(_active) {
this.global._active = _active.Index;
}
}
return this.get(this.global._active);
},
visible: function(tab) {
return tab.getPanel().visible();
},
show: function(tab) {
tab.getMenu().addClassName('active');
tab.getPanel().addClassName('active').show();
if(tab.global.options.history)
e107History.set(tab.histotyHash, tab.getPanelId());
return tab;
},
hide: function(tab) {
tab.getMenu().removeClassName('active');
tab.getPanel().removeClassName('active').hide();
return tab;
},
select: function(tab) {
if(!tab.visible()) {
if(tab.ajaxUrl)
return tab.ajaxSelect();
return tab.tabSelect();
}
return tab;
},
ajaxSelect: function(tab) {
if(!tab.ajaxUrl || (this.global.options.ajaxCache && tab.options['ajaxCached']))
return tab.tabSelect();
var ovel = this.global.options.overlayElement === true ? tab.getPanel() : $(this.global.options.overlayElement);
tab.getMenu().addClassName('active');
new e107Ajax.Updater(tab.getPanel(), tab.ajaxUrl, {
overlayPage: this.options.pageOverlay ? tab.getPanel() : false,
overlayElement: ovel || false,
onComplete: function() { tab.options.ajaxCached = this.global.options.ajaxCache; tab.tabSelect(); }.bind(this)
});
return tab;
},
tabSelect: function(tab) {
this.global.events.notify('hideActive', this.global.getActive()); //global trigger
tab.events.notify('hide', this.global.getActive()); // tab object trigger
this.options.hide(this.global.getActive());
this.global.events.notify('showSelected', tab); //global trigger
tab.events.notify('show', tab); // tab object trigger
this.options.show(tab);
this.global._active = tab.Index;
return tab;
},
startEvents: function() {
this.exec_recursive('startObserve');
this._startHistory();
return this;
},
stopEvents: function() {
this.exec_recursive('stopObserve');
this._stopHistory();
return this;
},
startObserve: function(tab) {
tab.actionItem.observe('click', this._observer); return this;
},
stopObserve: function(tab) {
tab.actionItem.stopObserving('click', this._observer); return this;
},
observer: function(event) {
var el = event.findElement('a');
if(el) {
event.stop();
this.get(el.hash.substr(1)).select();
}
},
eventObserve: function(method, callback) {
this.events.observe(method, callback); return this;
},
eventStopObserve: function() {
this.events.stopObserving(method, callback); return this;
},
_startHistory: function() {
if(this.options.historyNavigation) {
e107History.Observer.start();
var that = this;
// set handler for this instance
e107History.Registry.set({
id: this.histotyHash,
onStateChange: function(tab) {
that.get(String(tab)).select();
}
});
}
},
_stopHistory: function() {
e107History.Observer.stop();
e107History.Registry.unset(this.histotyHash);
}
});