2022-03-06 14:45:01 +01:00
|
|
|
"use strict";
|
|
|
|
|
2022-07-29 23:26:30 +02:00
|
|
|
import {Tab} from "bootstrap";
|
2022-08-02 00:23:55 +02:00
|
|
|
import tab from "bootstrap/js/src/tab";
|
2022-07-29 23:26:30 +02:00
|
|
|
|
2022-03-06 14:45:01 +01:00
|
|
|
/**
|
|
|
|
* This listener keeps track of which tab is currently selected (using hash and localstorage) and will try to open
|
|
|
|
* that tab on reload. That means that if the user changes something, he does not have to switch back to the tab
|
|
|
|
* where he was before submit.
|
|
|
|
*/
|
2022-07-29 22:52:58 +02:00
|
|
|
class TabRememberHelper {
|
2022-03-06 14:45:01 +01:00
|
|
|
constructor() {
|
2022-07-29 23:26:30 +02:00
|
|
|
document.addEventListener("turbo:load", this.onLoad.bind(this));
|
2022-08-02 00:23:55 +02:00
|
|
|
|
|
|
|
//Capture is important here, as invalid events normally does not bubble
|
|
|
|
document.addEventListener("invalid", this.onInvalid.bind(this), {capture: true});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This functions is called when the browser side input validation fails on an input, jump to the tab to show this up
|
|
|
|
* @param event
|
|
|
|
*/
|
|
|
|
onInvalid(event) {
|
|
|
|
this.revealElementOnTab(event.target);
|
2022-07-29 22:52:58 +02:00
|
|
|
}
|
2022-03-06 14:45:01 +01:00
|
|
|
|
2022-08-02 00:23:55 +02:00
|
|
|
revealElementOnTab(element) {
|
|
|
|
let parent = element.closest('.tab-pane');
|
|
|
|
|
|
|
|
//Iterate over each parent tab and show it
|
|
|
|
while(parent) {
|
|
|
|
//Invoker can either be a button or a element
|
|
|
|
let tabInvoker = document.querySelector("button[data-content='#" + parent.id + "']")
|
|
|
|
?? document.querySelector("a[href='#" + parent.id + "']");
|
|
|
|
Tab.getOrCreateInstance(tabInvoker).show();
|
|
|
|
|
|
|
|
parent = parent.parentElement.closest('.tab-pane');
|
|
|
|
}
|
|
|
|
}
|
2022-03-06 14:45:01 +01:00
|
|
|
|
2022-07-29 22:52:58 +02:00
|
|
|
onLoad(event) {
|
|
|
|
//Determine which tab should be shown (use hash if specified, otherwise use localstorage)
|
2022-07-29 23:26:30 +02:00
|
|
|
let activeTab = null;
|
2022-07-29 22:52:58 +02:00
|
|
|
if (location.hash) {
|
2022-07-29 23:26:30 +02:00
|
|
|
activeTab = document.querySelector('[href=\'' + location.hash + '\']');
|
2022-07-29 22:52:58 +02:00
|
|
|
} else if (localStorage.getItem('activeTab')) {
|
2022-07-29 23:26:30 +02:00
|
|
|
activeTab = document.querySelector('[href="' + localStorage.getItem('activeTab') + '"]');
|
2022-07-29 22:52:58 +02:00
|
|
|
}
|
|
|
|
|
2022-07-29 23:26:30 +02:00
|
|
|
if (activeTab) {
|
|
|
|
|
2022-08-02 00:23:55 +02:00
|
|
|
//Reveal our tab selector (needed for nested tabs)
|
2022-08-02 00:25:45 +02:00
|
|
|
this.revealElementOnTab(activeTab);
|
2022-07-29 23:26:30 +02:00
|
|
|
|
2022-07-29 22:52:58 +02:00
|
|
|
//Finally show the active tab itself
|
2022-07-29 23:26:30 +02:00
|
|
|
Tab.getOrCreateInstance(activeTab).show();
|
2022-07-29 22:52:58 +02:00
|
|
|
}
|
|
|
|
|
2022-07-29 23:26:30 +02:00
|
|
|
//Register listener for tab change
|
|
|
|
document.addEventListener('shown.bs.tab', this.onTabChange.bind(this));
|
|
|
|
}
|
2022-07-29 22:52:58 +02:00
|
|
|
|
2022-07-29 23:26:30 +02:00
|
|
|
onTabChange(event) {
|
|
|
|
const tab = event.target;
|
|
|
|
|
|
|
|
let tab_name = tab.getAttribute('href')
|
|
|
|
if (history.replaceState) {
|
|
|
|
history.replaceState(null, null, tab_name)
|
|
|
|
} else {
|
|
|
|
location.hash = tab_name
|
|
|
|
}
|
|
|
|
localStorage.setItem('activeTab', tab_name)
|
2022-03-06 14:45:01 +01:00
|
|
|
}
|
2022-07-29 22:52:58 +02:00
|
|
|
|
2022-03-06 14:45:01 +01:00
|
|
|
}
|
|
|
|
|
2022-07-29 22:52:58 +02:00
|
|
|
export default new TabRememberHelper();
|