/** * PWS Tabs jQuery Plugin * Author: Alex Chizhov * Author Website: http://alexchizhov.com/pwstabs * GitHub: https://github.com/alexchizhovcom/pwstabs * Version: 1.4.0 * Version from: 06.03.2016 * Licensed under the MIT license */ ; (function ($, window, document, undefined) { var pluginName = "pwstabs", defaults = { effect: 'scale', // You can change effects of your tabs container: scale / slideleft / slideright / slidetop / slidedown / none defaultTab: 1, // The tab we want to be opened by default containerWidth: '100%', // Set custom container width if not set then 100% is used tabsPosition: 'horizontal', // Tabs position: horizontal / vertical horizontalPosition: 'top', // Tabs horizontal position: top / bottom verticalPosition: 'left', // Tabs vertical position: left / right responsive: false, // BETA: Make tabs container responsive: true / false - boolean theme: '', // Theme name, you can add your own and define it here. This way you dont have to change default CSS. theme: 'name' - string rtl: false // Right to left support: true/ false }; function Plugin(element, options) { this.element = $(element); this.$elem = $(this.element); this.settings = $.extend({}, defaults, options); this._defaults = defaults; this._name = pluginName; this.init(); } Plugin.prototype = { // Constructing Tabs Plugin init: function () { // Array of effects @1.3.0 var arEffects = [ 'scale', 'slideleft', 'slideright', 'slidetop', 'slidedown', 'none' ]; // Variable for our selector @1.3.0 var selector = this.$elem; // Tabs variable @1.4.0 var tabs = selector.children('[data-pws-tab]'); // Add class to our selector selector.addClass('pws_tabs_list'); // Place selector into container @1.2.0 selector.wrap('
'); // Container variable @1.3.0 var container = selector.closest('.pws_tabs_container'); /* * Settings: container width * Default: 100% */ if (this.settings.containerWidth !== '100%') container.css('width', this.settings.containerWidth); /* * Settings: Position * Default: horizontal */ if (this.settings.tabsPosition == 'vertical') { /* * We need to check if current container is nested, * if so, add width style equals to parents tab width * @1.4.0 */ if (container.closest('.pws_tab_single').length) { var parentWidth = container.closest('.pws_tab_single').innerWidth() container.css('width', parentWidth); } this.settings.verticalPosition == 'left' ? container.addClass('pws_tabs_vertical pws_tabs_vertical_left') : container.addClass('pws_tabs_vertical pws_tabs_vertical_right'); } else { this.settings.horizontalPosition == 'top' ? container.addClass('pws_tabs_horizontal pws_tabs_horizontal_top') : container.addClass('pws_tabs_horizontal pws_tabs_horizontal_bottom'); } /* * Settings: Right to left support * Default: false */ if (this.settings.rtl) container.addClass('pws_tabs_rtl'); /* * Settings: If effect is none */ if (this.settings.effect == 'none') container.addClass('pws_tabs_noeffect'); /* * Settings: Theme * Default: '' */ if (this.settings.theme) container.addClass(this.settings.theme); /* * Check if effect exists @1.3.0 * If effect doesnt exist add scale by default */ if ($.inArray(this.settings.effect, arEffects) >= 0) container.addClass('pws_' + this.settings.effect); else container.addClass('pws_scale'); /* * Hide tabs content @1.4.0 */ tabs.addClass('pws_hide').hide(); /* * Add controlls */ if (this.settings.tabsPosition == 'vertical') { this.settings.verticalPosition == 'left' ? container.prepend('') : container.append(''); } else { // Horizontal this.settings.horizontalPosition == 'top' ? container.prepend('') : container.append(''); } // Controlls variable @1.4.0 var controlls = container.children('.pws_tabs_controll'); /* * Create Tabs controlls for each Tab * (div with HTML5 data attribute) */ var counter = 1; tabs.each(function () { // Set Data attributes with tab id number 1+ $(this).attr('data-pws-tab-id', counter); // Tab Id @1.3.0 var id = $(this).data('pws-tab'); // Tab Title @1.3.0 var title = $(this).data('pws-tab-name'); // Add LIs and A controls controlls.append('
  • ' + title + '
  • '); // Adding class to our selector children (Tabs) $(this).addClass('pws_tab_single'); counter++; }); // Controller variable @1.3.0 var controller = controlls.find('a'); // Controller li variable @1.3.0 var controllerLi = controlls.find('li'); // Default tab variable @1.4.0 var defaultTab = selector.children('[data-pws-tab-id="' + this.settings.defaultTab + '"]'); /* * Check if a controller has icon data @1.1.4 */ selector.children('[data-pws-tab-icon]').each(function () { var tabId = $(this).attr('data-pws-tab'); var tabName = $(this).attr('data-pws-tab-name'); var iconData = $(this).attr('data-pws-tab-icon'); // If no tab name is set if (tabName == '') { controlls.find('[data-tab-id="' + tabId + '"]') .addClass('pws_tab_noname'); } // Add icon to the tab controlls.find('[data-tab-id="' + tabId + '"]') .prepend(''); }); /** * Width and height settings for verticaly positioned tabs */ if (this.settings.tabsPosition == 'vertical') { var coefficient = container.innerWidth() / 450; var letterSize = parseInt(controller.css('font-size')) / coefficient; // @1.4.0 var controllerPaddings = parseInt(controller.css('padding-left')) + parseInt(controller.css('padding-right')); // @1.4.0. var verticalTabsWidth = controller.html().length*letterSize+controllerPaddings; // @1.4.0 var verticalTabsHeight = controlls.outerHeight(); var verticalContentWidth = container.outerWidth() - verticalTabsWidth; var verticalContentHeight = selector.outerHeight(); // Set tabs width controlls.width(verticalTabsWidth); // Set content width selector.outerWidth(verticalContentWidth); /* * if selectors height less than controlls height * make selector the same height as controlls */ if (verticalContentHeight < verticalTabsHeight) selector.css('min-height', verticalTabsHeight); } // Show default tab @1.4.0 defaultTab.addClass('pws_show').show(); /* * Add active class to default tabs controller */ controlls.find('[data-tab-id="' + defaultTab.data('pws-tab') + '"]') .addClass('pws_tab_active'); /* * Controller click function */ controller.on('click', function (e) { // Prevent use of href attribute; e.preventDefault(); // Remove active class from all controllers controller.removeClass('pws_tab_active'); // Add active class to current controller $(this).addClass('pws_tab_active'); var tabId = $(this).data('tab-id'); var currentTab = selector.children('[data-pws-tab="' + tabId + '"]'); // Add an effect to a tab on click @1.4.0 tabs.removeClass('pws_show'); setTimeout(function () { tabs.hide(); currentTab.show(); }, 400); setTimeout(function () { currentTab.addClass('pws_show'); }, 450); }); /** * ########################################################### * CODE TO MAKE TABS RESPONSIVE @1.2.0 * ########################################################### */ if (this.settings.responsive) { // Add Responsive class to Tabs container container.addClass('pws_tabs_responsive'); // Lets count LI's var pwsResponsiveControllLiCounter = parseInt(controlls.children('li').length); var pwsResponsiveControllLiPercentage = 100 / pwsResponsiveControllLiCounter; // Get highest LI var pwsResponsiveControllLiMaxHeight = Math.max.apply(null, controllerLi.map(function () { return $(this).height(); }).get()); $(window).on('resize load', {pluginSettings: this.settings}, function (e) { var $pluginSettings = e.data.pluginSettings; var tabsPosition = $pluginSettings.tabsPosition; var containerWidth = $pluginSettings.containerWidth; // Check window width if less than 60em ( 960px ) then: if ($(window).width() <= 960) { // Remove container width style container.width(''); // Add width to LIs controllerLi.css('width', pwsResponsiveControllLiPercentage + '%'); // Add height to each LIs controller.each(function () { $(this).height(pwsResponsiveControllLiMaxHeight); }); // If vertical, make it horizontal if (tabsPosition == 'vertical') { controlls.width(''); selector.width(''); selector.css('min-height', ''); selector.height(defaultTab.height()); } } if ($(window).width() <= 600) { if (container.find('.pws_responsive_small_menu').length < 1) { // Add new button to trigger tabs menu $('
    ').insertBefore(controlls); } // Add new class to UL controll controlls.addClass('pws_tabs_menu_popup'); controller.height(''); controllerLi.width(''); // Hide popup menu container.find('ul.pws_tabs_menu_popup').hide(); // Popup tabs menu trigger container.find('.pws_responsive_small_menu a').click(function (e) { e.preventDefault(); // We will add data atribute and check it 0/1 if ($(this).attr('data-visible') == '0') { container.find('ul.pws_tabs_menu_popup').show(); $(this).attr('data-visible', '1'); } else { container.find('ul.pws_tabs_menu_popup').hide(); $(this).attr('data-visible', '0'); } }); // Hide menu on tab pick container.find('ul.pws_tabs_menu_popup li a').on('click', function (e) { e.preventDefault(); $(this).closest('.pws_tabs_menu_popup').hide(); container.find('.pws_responsive_small_menu a').attr('data-visible', '0'); }); } else if ($(window).width() > 960) { container.css('width', containerWidth); controllerLi.width(''); controller.height(''); container.find('.pws_responsive_small_menu').remove(); controlls.removeClass('pws_tabs_menu_popup'); controlls.show(); } else if ($(window).width() > 600) { // Remove 600px screen menu container.find('.pws_responsive_small_menu').remove(); controlls.removeClass('pws_tabs_menu_popup'); controlls.show(); controller.on('click', function (e) { e.preventDefault(); $(this).parent().parent().show(); }); } }); } // EOF: IF RESPONSIVE } // Init function END }; $.fn[pluginName] = function (options) { return this.each(function () { new Plugin(this, options); }); }; })(jQuery, window, document);