gitlab-org--gitlab-foss/app/assets/javascripts/lib/utils/bootstrap_linked_tabs.js

122 lines
2.7 KiB
JavaScript
Raw Normal View History

import $ from 'jquery';
2016-11-23 09:44:05 -05:00
/**
* Linked Tabs
*
* Handles persisting and restores the current tab selection and content.
* Reusable component for static content.
*
* ### Example Markup
*
* <ul class="nav-links tab-links">
* <li class="active">
* <a data-action="tab1" data-target="#tab1" data-toggle="tab" href="/path/tab1">
* Tab 1
* </a>
* </li>
* <li class="groups-tab">
* <a data-action="tab2" data-target="#tab2" data-toggle="tab" href="/path/tab2">
* Tab 2
* </a>
* </li>
*
*
* <div class="tab-content">
* <div class="tab-pane" id="tab1">
* Tab 1 Content
* </div>
* <div class="tab-pane" id="tab2">
* Tab 2 Content
* </div>
* </div>
*
*
* ### How to use
*
* new LinkedTabs({
2016-11-23 09:44:05 -05:00
* action: "#{controller.action_name}",
* defaultAction: 'tab1',
* parentEl: '.tab-links'
* });
*/
export default class LinkedTabs {
/**
* Binds the events and activates de default tab.
*
* @param {Object} options
*/
constructor(options = {}) {
this.options = options;
2016-11-23 09:44:05 -05:00
this.defaultAction = this.options.defaultAction;
this.action = this.options.action || this.defaultAction;
this.hashedTabs = this.options.hashedTabs || false;
2016-11-23 09:44:05 -05:00
if (this.action === 'show') {
this.action = this.defaultAction;
}
2016-11-23 09:44:05 -05:00
this.currentLocation = window.location;
2016-11-29 05:35:53 -05:00
if (this.hashedTabs) {
this.action = this.currentLocation.hash || this.action;
}
const tabSelector = `${this.options.parentEl} a[data-toggle="tab"]`;
2016-11-29 05:35:53 -05:00
// since this is a custom event we need jQuery :(
$(document)
.off('shown.bs.tab', tabSelector)
.on('shown.bs.tab', tabSelector, e => this.tabShown(e));
2016-11-23 09:44:05 -05:00
this.activateTab(this.action);
}
2016-11-23 09:44:05 -05:00
/**
* Handles the `shown.bs.tab` event to set the currect url action.
*
* @param {type} evt
* @return {Function}
*/
tabShown(evt) {
const source = evt.target.getAttribute('href');
2016-11-23 09:44:05 -05:00
return this.setCurrentAction(source);
}
2016-11-23 09:44:05 -05:00
/**
* Updates the URL with the path that matched the given action.
*
* @param {String} source
* @return {String}
*/
setCurrentAction(source) {
const copySource = source;
2016-11-23 09:44:05 -05:00
copySource.replace(/\/+$/, '');
2016-11-23 09:44:05 -05:00
const newState = this.hashedTabs
? copySource
: `${copySource}${this.currentLocation.search}${this.currentLocation.hash}`;
2016-11-23 09:44:05 -05:00
2018-10-10 02:25:43 -04:00
window.history.replaceState(
{
url: newState,
},
document.title,
newState,
);
return newState;
}
2016-11-23 09:44:05 -05:00
/**
* Given the current action activates the correct tab.
* http://getbootstrap.com/javascript/#tab-show
* Note: Will trigger `shown.bs.tab`
*/
activateTab() {
return $(`${this.options.parentEl} a[data-action='${this.action}']`).tab('show');
}
}