284 lines
5.7 KiB
JavaScript
284 lines
5.7 KiB
JavaScript
|
/**
|
||
|
* @license
|
||
|
* jQuery Tools 1.2.5 Tabs- The basics of UI design.
|
||
|
*
|
||
|
* NO COPYRIGHTS OR LICENSES. DO WHAT YOU LIKE.
|
||
|
*
|
||
|
* http://flowplayer.org/tools/tabs/
|
||
|
*
|
||
|
* Since: November 2008
|
||
|
* Date: Wed Sep 22 06:02:10 2010 +0000
|
||
|
*/
|
||
|
(function($) {
|
||
|
|
||
|
// static constructs
|
||
|
$.tools = $.tools || {version: '1.2.5'};
|
||
|
|
||
|
$.tools.tabs = {
|
||
|
|
||
|
conf: {
|
||
|
tabs: 'a',
|
||
|
current: 'current',
|
||
|
onBeforeClick: null,
|
||
|
onClick: null,
|
||
|
effect: 'default',
|
||
|
initialIndex: 0,
|
||
|
event: 'click',
|
||
|
rotate: false,
|
||
|
|
||
|
// 1.2
|
||
|
history: false
|
||
|
},
|
||
|
|
||
|
addEffect: function(name, fn) {
|
||
|
effects[name] = fn;
|
||
|
}
|
||
|
|
||
|
};
|
||
|
|
||
|
var effects = {
|
||
|
|
||
|
// simple "toggle" effect
|
||
|
'default': function(i, done) {
|
||
|
this.getPanes().hide().eq(i).show();
|
||
|
done.call();
|
||
|
},
|
||
|
|
||
|
/*
|
||
|
configuration:
|
||
|
- fadeOutSpeed (positive value does "crossfading")
|
||
|
- fadeInSpeed
|
||
|
*/
|
||
|
fade: function(i, done) {
|
||
|
|
||
|
var conf = this.getConf(),
|
||
|
speed = conf.fadeOutSpeed,
|
||
|
panes = this.getPanes();
|
||
|
|
||
|
if (speed) {
|
||
|
panes.fadeOut(speed);
|
||
|
} else {
|
||
|
panes.hide();
|
||
|
}
|
||
|
|
||
|
panes.eq(i).fadeIn(conf.fadeInSpeed, done);
|
||
|
},
|
||
|
|
||
|
// for basic accordions
|
||
|
slide: function(i, done) {
|
||
|
this.getPanes().slideUp(200);
|
||
|
this.getPanes().eq(i).slideDown(400, done);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* AJAX effect
|
||
|
*/
|
||
|
ajax: function(i, done) {
|
||
|
this.getPanes().eq(0).load(this.getTabs().eq(i).attr("href"), done);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
var w;
|
||
|
|
||
|
/**
|
||
|
* Horizontal accordion
|
||
|
*
|
||
|
* @deprecated will be replaced with a more robust implementation
|
||
|
*/
|
||
|
$.tools.tabs.addEffect("horizontal", function(i, done) {
|
||
|
|
||
|
// store original width of a pane into memory
|
||
|
if (!w) { w = this.getPanes().eq(0).width(); }
|
||
|
|
||
|
// set current pane's width to zero
|
||
|
this.getCurrentPane().animate({width: 0}, function() { $(this).hide(); });
|
||
|
|
||
|
// grow opened pane to it's original width
|
||
|
this.getPanes().eq(i).animate({width: w}, function() {
|
||
|
$(this).show();
|
||
|
done.call();
|
||
|
});
|
||
|
|
||
|
});
|
||
|
|
||
|
|
||
|
function Tabs(root, paneSelector, conf) {
|
||
|
|
||
|
var self = this,
|
||
|
trigger = root.add(this),
|
||
|
tabs = root.find(conf.tabs),
|
||
|
panes = paneSelector.jquery ? paneSelector : root.children(paneSelector),
|
||
|
current;
|
||
|
|
||
|
|
||
|
// make sure tabs and panes are found
|
||
|
if (!tabs.length) { tabs = root.children(); }
|
||
|
if (!panes.length) { panes = root.parent().find(paneSelector); }
|
||
|
if (!panes.length) { panes = $(paneSelector); }
|
||
|
|
||
|
|
||
|
// public methods
|
||
|
$.extend(this, {
|
||
|
click: function(i, e) {
|
||
|
|
||
|
var tab = tabs.eq(i);
|
||
|
|
||
|
if (typeof i == 'string' && i.replace("#", "")) {
|
||
|
tab = tabs.filter("[href*=" + i.replace("#", "") + "]");
|
||
|
i = Math.max(tabs.index(tab), 0);
|
||
|
}
|
||
|
|
||
|
if (conf.rotate) {
|
||
|
var last = tabs.length -1;
|
||
|
if (i < 0) { return self.click(last, e); }
|
||
|
if (i > last) { return self.click(0, e); }
|
||
|
}
|
||
|
|
||
|
if (!tab.length) {
|
||
|
if (current >= 0) { return self; }
|
||
|
i = conf.initialIndex;
|
||
|
tab = tabs.eq(i);
|
||
|
}
|
||
|
|
||
|
// current tab is being clicked
|
||
|
if (i === current) { return self; }
|
||
|
|
||
|
// possibility to cancel click action
|
||
|
e = e || $.Event();
|
||
|
e.type = "onBeforeClick";
|
||
|
trigger.trigger(e, [i]);
|
||
|
if (e.isDefaultPrevented()) { return; }
|
||
|
|
||
|
// call the effect
|
||
|
effects[conf.effect].call(self, i, function() {
|
||
|
|
||
|
// onClick callback
|
||
|
e.type = "onClick";
|
||
|
trigger.trigger(e, [i]);
|
||
|
});
|
||
|
|
||
|
// default behaviour
|
||
|
current = i;
|
||
|
tabs.removeClass(conf.current);
|
||
|
tab.addClass(conf.current);
|
||
|
|
||
|
return self;
|
||
|
},
|
||
|
|
||
|
getConf: function() {
|
||
|
return conf;
|
||
|
},
|
||
|
|
||
|
getTabs: function() {
|
||
|
return tabs;
|
||
|
},
|
||
|
|
||
|
getPanes: function() {
|
||
|
return panes;
|
||
|
},
|
||
|
|
||
|
getCurrentPane: function() {
|
||
|
return panes.eq(current);
|
||
|
},
|
||
|
|
||
|
getCurrentTab: function() {
|
||
|
return tabs.eq(current);
|
||
|
},
|
||
|
|
||
|
getIndex: function() {
|
||
|
return current;
|
||
|
},
|
||
|
|
||
|
next: function() {
|
||
|
return self.click(current + 1);
|
||
|
},
|
||
|
|
||
|
prev: function() {
|
||
|
return self.click(current - 1);
|
||
|
},
|
||
|
|
||
|
destroy: function() {
|
||
|
tabs.unbind(conf.event).removeClass(conf.current);
|
||
|
panes.find("a[href^=#]").unbind("click.T");
|
||
|
return self;
|
||
|
}
|
||
|
|
||
|
});
|
||
|
|
||
|
// callbacks
|
||
|
$.each("onBeforeClick,onClick".split(","), function(i, name) {
|
||
|
|
||
|
// configuration
|
||
|
if ($.isFunction(conf[name])) {
|
||
|
$(self).bind(name, conf[name]);
|
||
|
}
|
||
|
|
||
|
// API
|
||
|
self[name] = function(fn) {
|
||
|
if (fn) { $(self).bind(name, fn); }
|
||
|
return self;
|
||
|
};
|
||
|
});
|
||
|
|
||
|
|
||
|
if (conf.history && $.fn.history) {
|
||
|
$.tools.history.init(tabs);
|
||
|
conf.event = 'history';
|
||
|
}
|
||
|
|
||
|
// setup click actions for each tab
|
||
|
tabs.each(function(i) {
|
||
|
$(this).bind(conf.event, function(e) {
|
||
|
self.click(i, e);
|
||
|
return e.preventDefault();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
// cross tab anchor link
|
||
|
panes.find("a[href^=#]").bind("click.T", function(e) {
|
||
|
self.click($(this).attr("href"), e);
|
||
|
});
|
||
|
|
||
|
// open initial tab
|
||
|
if (location.hash && conf.tabs == "a" && root.find("[href=" +location.hash+ "]").length) {
|
||
|
self.click(location.hash);
|
||
|
|
||
|
} else {
|
||
|
if (conf.initialIndex === 0 || conf.initialIndex > 0) {
|
||
|
self.click(conf.initialIndex);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// jQuery plugin implementation
|
||
|
$.fn.tabs = function(paneSelector, conf) {
|
||
|
|
||
|
// return existing instance
|
||
|
var el = this.data("tabs");
|
||
|
if (el) {
|
||
|
el.destroy();
|
||
|
this.removeData("tabs");
|
||
|
}
|
||
|
|
||
|
if ($.isFunction(conf)) {
|
||
|
conf = {onBeforeClick: conf};
|
||
|
}
|
||
|
|
||
|
// setup conf
|
||
|
conf = $.extend({}, $.tools.tabs.conf, conf);
|
||
|
|
||
|
|
||
|
this.each(function() {
|
||
|
el = new Tabs($(this), paneSelector, conf);
|
||
|
$(this).data("tabs", el);
|
||
|
});
|
||
|
|
||
|
return conf.api ? el: this;
|
||
|
};
|
||
|
|
||
|
}) (jQuery);
|
||
|
|
||
|
|