/* * Project: jquery.responsiveTabs.js * Description: A plugin that creates responsive tabs, optimized for all devices * Author: Jelle Kralt (jelle@jellekralt.nl) * Version: 1.4.0 * License: MIT */ ;(function ( $, window, undefined ) { /** Default settings */ var defaults = { active: null, disabled: [], collapsible: 'accordion', startCollapsed: false, rotate: false, setHash: false, animation: 'default', duration: 500, activate: function(){}, deactivate: function(){}, load: function(){}, activateState: function(){}, classes: { stateDefault: 'r-tabs-state-default', stateActive: 'r-tabs-state-active', stateDisabled: 'r-tabs-state-disabled', stateExcluded: 'r-tabs-state-excluded', tab: 'r-tabs-tab', anchor: 'r-tabs-anchor', panel: 'r-tabs-panel', accordionTitle: 'r-tabs-accordion-title' } }; /** * Responsive Tabs * @constructor * @param {object} element - The HTML element the validator should be bound to * @param {object} options - An option map */ function ResponsiveTabs(element, options) { this.element = element; // Selected DOM element this.$element = $(element); // Selected jQuery element this.tabs = []; // Create tabs array this.state = ''; // Define the plugin state (tabs/accordion) this.rotateInterval = 0; // Define rotate interval this.$queue = $({}); // Extend the defaults with the passed options this.options = $.extend( {}, defaults, options); this.init(); } /** * This function initializes the tab plugin */ ResponsiveTabs.prototype.init = function () { var _this = this; // Load all the elements this.tabs = this._loadElements(); this._loadClasses(); this._loadEvents(); // Window resize bind to check state $(window).on('resize', function(e) { _this._setState(e); }); // Hashchange event $(window).on('hashchange', function(e) { var tabRef = _this._getTabRefBySelector(window.location.hash); var oTab = _this._getTab(tabRef); // Check if a tab is found that matches the hash if(tabRef >= 0 && !oTab._ignoreHashChange && !oTab.disabled) { // If so, open the tab and auto close the current one _this._openTab(e, _this._getTab(tabRef), true); } }); // Start rotate event if rotate option is defined if(this.options.rotate !== false) { this.startRotation(); } // -------------------- // Define plugin events // // Activate: this event is called when a tab is selected this.$element.bind('tabs-activate', function(e, oTab) { _this.options.activate.call(this, e, oTab); }); // Deactivate: this event is called when a tab is closed this.$element.bind('tabs-deactivate', function(e, oTab) { _this.options.deactivate.call(this, e, oTab); }); // Activate State: this event is called when the plugin switches states this.$element.bind('tabs-activate-state', function(e, state) { _this.options.activateState.call(this, e, state); }); // Load: this event is called when the plugin has been loaded this.$element.bind('tabs-load', function(e) { var tabRef = _this._getTabRefBySelector(window.location.hash); var firstTab; _this._setState(e); // Set state // Check if the panel should be collaped on load if(_this.options.startCollapsed !== true && !(_this.options.startCollapsed === 'accordion' && _this.state === 'accordion')) { // Check if the page has a hash set that is linked to a tab if(tabRef >= 0 && !_this._getTab(tabRef).disabled) { // If so, set the current tab to the linked tab firstTab = _this._getTab(tabRef); } else if(_this.options.active > 0 && !_this._getTab(_this.options.active).disabled) { firstTab = _this._getTab(_this.options.active); } else { // If not, just get the first one firstTab = _this._getTab(0); } // Open the initial tab _this._openTab(e, firstTab); // Open first tab // Call the callback function _this.options.load.call(this, e, firstTab); // Call the load callback } }); // Trigger loaded event this.$element.trigger('tabs-load'); }; // // PRIVATE FUNCTIONS // /** * This function loads the tab elements and stores them in an array * @returns {Array} Array of tab elements */ ResponsiveTabs.prototype._loadElements = function() { var _this = this; var $ul = this.$element.children('ul'); var tabs = []; var id = 0; // Add the classes to the basic html elements this.$element.addClass('r-tabs'); // Tab container $ul.addClass('r-tabs-nav'); // List container // Get tab buttons and store their data in an array $('li', $ul).each(function() { var $tab = $(this); var isExcluded = $tab.hasClass(_this.options.classes.stateExcluded); var $anchor, $panel, $accordionTab, $accordionAnchor, panelSelector; // Check if the tab should be excluded if(!isExcluded) { $anchor = $('a', $tab); panelSelector = $anchor.attr('href'); $panel = $(panelSelector); $accordionTab = $('
').insertBefore($panel); $accordionAnchor = $('').attr('href', panelSelector).html($anchor.html()).appendTo($accordionTab); var oTab = { _ignoreHashChange: false, id: id, disabled: ($.inArray(id, _this.options.disabled) !== -1), tab: $(this), anchor: $('a', $tab), panel: $panel, selector: panelSelector, accordionTab: $accordionTab, accordionAnchor: $accordionAnchor, active: false }; // 1up the ID id++; // Add to tab array tabs.push(oTab); } }); return tabs; }; /** * This function adds classes to the tab elements based on the options */ ResponsiveTabs.prototype._loadClasses = function() { for (var i=0; i