xbase-2.x-dev/js/libraries/jquery.xtabs/jquery.xtabs.js
js/libraries/jquery.xtabs/jquery.xtabs.js
/*
* jQuery xTabs.
* Simple alternative for jQuery UI Tabs.
*/
;(function($, window, document, undefined) {
'use strict';
var pluginName = 'xtabs';
var defaults = {};
function Plugin(element, options) {
this.element = element;
this.settings = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
$.extend(Plugin.prototype, {
/**
* Plugin init.
*/
init: function() {
var pluginInstance = this;
var $element = $(pluginInstance.element);
// Change navigation links anchor
$element.find('.tabs__nav-link').each(function () {
var $navLink = $(this);
var navLinkHref = $navLink.attr('href');
if (navLinkHref.substring(0, 1) == '#') {
$navLink.attr('href', '#tab-' + navLinkHref.substring(1));
}
});
// Navigation link "click" callback
$element.find('.tabs__nav-link').on('click.xtabs', function (event, addHash) {
var $selectedNavLink = $(this);
addHash = (typeof addHash !== 'undefined') ? addHash : true;
if ($selectedNavLink.attr('href').substring(0, 1) == '#') {
var $selectedNavItem = $selectedNavLink.parent('.tabs__nav-item');
var selectedTabId = $selectedNavItem.data('tabs-target');
pluginInstance.selectTab(selectedTabId, addHash);
event.preventDefault();
}
});
// Select tab after window change hash
$(window).on('hashchange', function () {
pluginInstance.locationHashChanged();
});
// Select default tab
if (location.hash) {
pluginInstance.locationHashChanged();
}
if ($element.find('.tabs__nav-item--active').length == 0) {
var firstTabId = $element.find('.tabs__panel:first').attr('id');
pluginInstance.emulateClickToTabLink(firstTabId, false);
}
},
/**
* Select tab.
*/
selectTab: function (tabId, addHash) {
var pluginInstance = this;
var $element = $(pluginInstance.element);
var $selectedNavItem = pluginInstance.getNavItemByTabId(tabId);
if ($selectedNavItem.length) {
var $selectedPanel = pluginInstance.getPanelByTabId(tabId);
var $prevSelectedNavItem = $element.find('.tabs__nav-item--active');
// Remove "active" class
$prevSelectedNavItem.removeClass('tabs__nav-item--active');
$element.find('.tabs__panel--active').removeClass('tabs__panel--active');
// Add "active" class
$selectedNavItem.addClass('tabs__nav-item--active');
$selectedPanel.addClass('tabs__panel--active');
// Add hash to location
if (addHash) {
location.hash = '#tab-' + tabId;
}
}
},
/**
* Emulate click to tab link.
*/
emulateClickToTabLink: function (tabId, addHash, callback) {
var pluginInstance = this;
var $navItem = pluginInstance.getNavItemByTabId(tabId);
if ($navItem.length) {
setTimeout(function () {
$navItem.find('.tabs__nav-link').trigger('click', [addHash]);
if (callback) {
callback();
}
}, 10);
}
},
/**
* Select tab by window hash.
*/
locationHashChanged: function () {
var pluginInstance = this;
var $element = $(pluginInstance.element);
var idFromHash = location.hash.substring(1);
if (!idFromHash) {
return;
}
// Situation 1 - hash contains string in format "tab-[tab-id]"
if (idFromHash.substring(0, 4) == 'tab-') {
pluginInstance.emulateClickToTabLink(idFromHash.substring(4), false);
}
// Situation 2 - hash contains panel id
var $panel = pluginInstance.getPanelByTabId(idFromHash);
if ($panel.length) {
pluginInstance.emulateClickToTabLink(idFromHash, false);
}
// Situation 3 - hash contains id in panel content
var $targetElement = $element.find('.tabs__panel-content #' + idFromHash);
if ($targetElement.length) {
var tabId = $targetElement.closest('.tabs__panel').attr('id');
pluginInstance.emulateClickToTabLink(tabId, false, function () {
$targetElement[0].scrollIntoView({
block: 'center',
behavior: 'smooth',
});
});
}
},
/**
* Return navigation item by tab id.
*/
getNavItemByTabId: function (tabId) {
var pluginInstance = this;
var $element = $(pluginInstance.element);
return $element.find('.tabs__nav-item[data-tabs-target="' + tabId + '"]');
},
/**
* Return panel by tab id.
*/
getPanelByTabId: function (tabId) {
var pluginInstance = this;
var $element = $(pluginInstance.element);
return $element.find('.tabs__panel#' + tabId);
},
/**
* Change window hash without scroll.
*/
changeWindowHashWithoutScroll: function (hash) {
history.replaceState(null, null, hash);
},
});
$.fn[pluginName] = function(options) {
return this.each(function() {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
}
});
};
})(jQuery, window, document);
