Project

General

Profile

1
/**
2
 * SimpleTabs - Unobtrusive Tabs with Ajax
3
 *
4
 * @example
5
 *
6
 *	var tabs = new SimpleTabs($('tab-element'), {
7
 * 		selector: 'h2.tab-tab'
8
 *	});
9
 *
10
 * @version		1.0
11
 *
12
 * @license		MIT License
13
 * @author		Harald Kirschner <mail [at] digitarald.de>
14
 * @copyright	2007 Author
15
 */
16
var SimpleTabs = new Class({
17

    
18
	Implements: [Events, Options],
19

    
20
	/**
21
	 * Options
22
	 */
23
	options: {
24
		show: 0,
25
		selector: '.tab-tab',
26
		classWrapper: 'tab-wrapper',
27
		classMenu: 'tab-menu',
28
		classContainer: 'tab-container',
29
		onSelect: function(toggle, container, index) {
30
			toggle.addClass('tab-selected');
31
			container.setStyle('display', '');
32
		},
33
		onDeselect: function(toggle, container, index) {
34
			toggle.removeClass('tab-selected');
35
			container.setStyle('display', 'none');
36
		},
37
		onRequest: function(toggle, container, index) {
38
			container.addClass('tab-ajax-loading');
39
		},
40
		onComplete: function(toggle, container, index) {
41
			container.removeClass('tab-ajax-loading');
42
		},
43
		onFailure: function(toggle, container, index) {
44
			container.removeClass('tab-ajax-loading');
45
		},
46
		onAdded: Class.empty,
47
		getContent: null,
48
		ajaxOptions: {},
49
		cache: true
50
	},
51

    
52
	/**
53
	 * Constructor
54
	 *
55
	 * @param {Element} The parent Element that holds the tab elements
56
	 * @param {Object} Options
57
	 */
58
	initialize: function(element, options) {
59
		this.element = $(element);
60
		this.setOptions(options);
61
		this.selected = null;
62
		this.build();
63
	},
64

    
65
	build: function() {
66
		this.tabs = [];
67
		this.menu = new Element('ul', {'class': this.options.classMenu});
68
		this.wrapper = new Element('div', {'class': this.options.classWrapper});
69

    
70
		this.element.getElements(this.options.selector).each(function(el) {
71
			var content = el.get('href') || (this.options.getContent ? this.options.getContent.call(this, el) : el.getNext());
72
			this.addTab(el.innerHTML, el.title || el.innerHTML, content);
73
		}, this);
74
		this.element.empty().adopt(this.menu, this.wrapper);
75

    
76
		if (this.tabs.length) this.select(this.options.show);
77
	},
78

    
79
	/**
80
	 * Add a new tab at the end of the tab menu
81
	 *
82
	 * @param {String} inner Text
83
	 * @param {String} Title
84
	 * @param {Element|String} Content Element or URL for Ajax
85
	 */
86
	addTab: function(text, title, content) {
87
		var grab = $(content);
88
		var container = (grab || new Element('div'))
89
			.setStyle('display', 'none')
90
			.addClass(this.options.classContainer)
91
			.inject(this.wrapper);
92
		var pos = this.tabs.length;
93
		var evt = (this.options.hover) ? 'mouseenter' : 'click';
94
		var tab = {
95
			container: container,
96
			toggle: new Element('li').grab(new Element('a', {
97
				href: '#',
98
				title: title
99
			}).grab(
100
				new Element('span', {html: text})
101
			)).addEvent(evt, this.onClick.bindWithEvent(this, [pos])).inject(this.menu)
102
		};
103
		if (!grab && $type(content) == 'string') tab.url = content;
104
		this.tabs.push(tab);
105
		return this.fireEvent('onAdded', [tab.toggle, tab.container, pos]);
106
	},
107

    
108
	onClick: function(evt, index) {
109
		this.select(index);
110
		return false;
111
	},
112

    
113
	/**
114
	 * Select the tab via tab-index
115
	 *
116
	 * @param {Number} Tab-index
117
	 */
118
	select: function(index) {
119
		if (this.selected === index || !this.tabs[index]) return this;
120
		if (this.ajax) this.ajax.cancel().removeEvents();
121
		var tab = this.tabs[index];
122
		var params = [tab.toggle, tab.container, index];
123
		if (this.selected !== null) {
124
			var current = this.tabs[this.selected];
125
			if (this.ajax && this.ajax.running) this.ajax.cancel();
126
			params.extend([current.toggle, current.container, this.selected]);
127
			this.fireEvent('onDeselect', [current.toggle, current.container, this.selected]);
128
		}
129
		this.fireEvent('onSelect', params);
130
		if (tab.url && (!tab.loaded || !this.options.cache)) {
131
			this.ajax = this.ajax || new Request.HTML();
132
			this.ajax.setOptions({
133
				url: tab.url,
134
				method: 'get',
135
				update: tab.container,
136
				onFailure: this.fireEvent.pass(['onFailure', params], this),
137
				onComplete: function(resp) {
138
					tab.loaded = true;
139
					this.fireEvent('onComplete', params);
140
				}.bind(this)
141
			}).setOptions(this.options.ajaxOptions);
142
			this.ajax.send();
143
			this.fireEvent('onRequest', params);
144
		}
145
		this.selected = index;
146
		return this;
147
	}
148

    
149
});
(4-4/21)