/**
* @author Rafael Ostertag <rafael.ostertag@math.uzh.ch>
*/
/* global $ */
/* global console */
/* global EventEmitter */
/* @depend QfqEvents.js */
/**
* Qfq Namespace
*
* @namespace QfqNS
*/
var QfqNS = QfqNS || {};
(function (n) {
'use strict';
/**
* Tab Constructor.
*
* Programatically access Bootstrap nav-tabs.
*
* @param {string} tabId HTML id of the element having `nav` and `nav-tabs` classes
* @constructor
*
* @name QfqNS.BSTabs
*/
n.BSTabs = function (tabId) {
this.tabId = tabId;
this._tabContainerLinkSelector = '#' + this.tabId + ' a[data-toggle="tab"]';
this._tabActiveSelector = '#' + this.tabId + ' .active a[data-toggle="tab"]';
this.tabs = {};
this.currentTab = this.getActiveTabFromDOM();
this.eventEmitter = new EventEmitter();
// Fill this.tabs
this.fillTabInformation();
// Enable update of current tab field
this.installTabHandlers();
};
n.BSTabs.prototype.on = n.EventEmitter.onMixin;
/**
* Get active tab from DOM.
*
* Used upon object creation to fill the currentTab. It gets the ID of the currently shown tab. It does
it, by
* targeting the element in the navigator having the `active` class set.
*
* @private
*/
n.BSTabs.prototype.getActiveTabFromDOM = function () {
var activeTabAnchors = $(this._tabActiveSelector);
if (activeTabAnchors.length < 1) {
// This could be due to the DOM not fully loaded. If that's really the case, then the active tab
// attribute should be set by the show.bs.tab handler
return null;
}
return activeTabAnchors[0].hash.slice(1);
};
/**
* Fill tabs object.
*
* Fill the tabs object using the tab HTML id as attribute name
*
* @private
*/
n.BSTabs.prototype.fillTabInformation = function () {
var tabLinks = $(this._tabContainerLinkSelector);
if ($(tabLinks).length === 0) {
throw new Error("Unable to find a BootStrap container matching: " + this._tabContainerLinkSelector);
}
var that = this;
tabLinks.each(function (index, element) {
if (element.hash !== "") {
var tabId = element.hash.slice(1);
that.tabs[tabId] = {
index: index,
element: element
};
}
}
);
};
/**
* @private
*/
n.BSTabs.prototype.installTabHandlers = function () {
$(this._tabContainerLinkSelector)
.on('show.bs.tab', this.tabShowHandler.bind(this));
};
/**
* Tab Show handler.
*
* Sets this.currentTab to the clicked tab and calls all registered tab click handlers.
*
* @private
* @param event
*/
n.BSTabs.prototype.tabShowHandler = function (event) {
n.Log.debug('Enter: BSTabs.tabShowHandler()');
this.currentTab = event.target.hash.slice(1);
n.Log.debug("BSTabs.tabShowHandler(): invoke user handler(s)");
this.eventEmitter.emitEvent('bootstrap.tab.shown', n.EventEmitter.makePayload(this, null));
n.Log.debug('Exit: BSTabs.tabShowHandler()');
};
/**
* Get all tab IDs.
*
* @returns {Array}
*
* @public
*/
n.BSTabs.prototype.getTabIds = function () {
var tabIds = [];
for (var tabId in this.tabs) {
if (this.tabs.hasOwnProperty(tabId)) {
tabIds.push(tabId);
}
}
return tabIds;
};
/**
*
* @returns {Array}
*
* @public
*/
n.BSTabs.prototype.getTabAnchors = function () {
var tabLinks = [];
for (var tabId in this.tabs) {
if (this.tabs.hasOwnProperty(tabId)) {
tabLinks.push(this.tabs[tabId].element);
}
}
return tabLinks;
};
/**
* Activate a given tab.
*
* @param {string} tabId Id of the tab to activate
*
*/
n.BSTabs.prototype.activateTab = function (tabId) {
if (!this.tabs[tabId]) {
console.error("Unable to find tab with id: " + tabId);
return false;
}
$(this.tabs[tabId].element).tab('show');
return true;
};
n.BSTabs.prototype.getCurrentTab = function () {
return this.currentTab;
};
n.BSTabs.prototype.getTabName = function (tabId) {
if (!this.tabs[tabId]) {
console.error("Unable to find tab with id: " + tabId);
return null;
}
return $(this.tabs[tabId].element).text().trim();
};
n.BSTabs.prototype.getActiveTab = function () {
return this.currentTab;
};
n.BSTabs.prototype.getContainingTabIdForFormControl = function (formControlName) {
var $formControl = $("[name='" + formControlName + "']");
if ($formControl.length === 0) {
n.Log.debug("BSTabs.getContainingTabForFormControl(): unable to find form control with name '" +
formControlName + "'");
return null;
}
var iterator = $formControl[0];
while (iterator !== null) {
if (iterator.hasAttribute('role') &&
iterator.getAttribute('role') === 'tabpanel') {
return iterator.id || null;
}
iterator = iterator.parentElement;
}
return null;
};
})(QfqNS);