/priv/public/js/tools.tabs.js
JavaScript | 285 lines | 172 code | 70 blank | 43 comment | 27 complexity | a54d536acf5861bf57733d019a2e5575 MD5 | raw file
Possible License(s): Apache-2.0, MIT
- /**
- * tools.tabs 1.0.4 - Tabs done right.
- *
- * Copyright (c) 2009 Tero Piirainen
- * http://flowplayer.org/tools/tabs.html
- *
- * Dual licensed under MIT and GPL 2+ licenses
- * http://www.opensource.org/licenses
- *
- * Launch : November 2008
- * Date: ${date}
- * Revision: ${revision}
- */
- (function($) {
-
- // static constructs
- $.tools = $.tools || {};
-
- $.tools.tabs = {
- version: '1.0.4',
-
- conf: {
- tabs: 'a',
- current: 'current',
- onBeforeClick: null,
- onClick: null,
- effect: 'default',
- initialIndex: 0,
- event: 'click',
- api:false,
- rotate: 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);
- },
- // simple AJAX effect
- ajax: function(i, done) {
- this.getPanes().eq(0).load(this.getTabs().eq(i).attr("href"), done);
- }
-
- };
-
- var w;
-
- // this is how you add effects
- $.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(tabs, panes, conf) {
-
- var self = this, $self = $(this), current;
- // bind all callbacks from configuration
- $.each(conf, function(name, fn) {
- if ($.isFunction(fn)) { $self.bind(name, fn); }
- });
-
-
- // public methods
- $.extend(this, {
- click: function(i, e) {
-
- var pane = self.getCurrentPane();
- 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";
- $self.trigger(e, [i]);
- if (e.isDefaultPrevented()) { return; }
-
- // call the effect
- effects[conf.effect].call(self, i, function() {
- // onClick callback
- e.type = "onClick";
- $self.trigger(e, [i]);
- });
-
- // onStart
- e.type = "onStart";
- $self.trigger(e, [i]);
- if (e.isDefaultPrevented()) { return; }
-
- // 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);
- },
-
- bind: function(name, fn) {
- $self.bind(name, fn);
- return self;
- },
-
- onBeforeClick: function(fn) {
- return this.bind("onBeforeClick", fn);
- },
-
- onClick: function(fn) {
- return this.bind("onClick", fn);
- },
-
- unbind: function(name) {
- $self.unbind(name);
- return self;
- }
-
- });
-
-
- // setup click actions for each tab
- tabs.each(function(i) {
- $(this).bind(conf.event, function(e) {
- self.click(i, e);
- return false;
- });
- });
- // if no pane is visible --> click on the first tab
- if (location.hash) {
- self.click(location.hash);
- } else {
- if (conf.initialIndex === 0 || conf.initialIndex > 0) {
- self.click(conf.initialIndex);
- }
- }
-
- // cross tab anchor link
- panes.find("a[href^=#]").click(function(e) {
- self.click($(this).attr("href"), e);
- });
- }
-
-
- // jQuery plugin implementation
- $.fn.tabs = function(query, conf) {
-
- // return existing instance
- var el = this.eq(typeof conf == 'number' ? conf : 0).data("tabs");
- if (el) { return el; }
- if ($.isFunction(conf)) {
- conf = {onBeforeClick: conf};
- }
-
- // setup options
- var globals = $.extend({}, $.tools.tabs.conf), len = this.length;
- conf = $.extend(globals, conf);
-
- // install tabs for each items in jQuery
- this.each(function(i) {
- var root = $(this);
-
- // find tabs
- var els = root.find(conf.tabs);
-
- if (!els.length) {
- els = root.children();
- }
-
- // find panes
- var panes = query.jquery ? query : root.children(query);
-
- if (!panes.length) {
- panes = len == 1 ? $(query) : root.parent().find(query);
- }
-
- el = new Tabs(els, panes, conf);
- root.data("tabs", el);
-
- });
-
- return conf.api ? el: this;
- };
-
- }) (jQuery);