diff --git a/assets/js/tab_remember.js b/assets/js/tab_remember.js index 7ef45e24..32ecf22b 100644 --- a/assets/js/tab_remember.js +++ b/assets/js/tab_remember.js @@ -1,6 +1,7 @@ "use strict"; import {Tab} from "bootstrap"; +import tab from "bootstrap/js/src/tab"; /** * This listener keeps track of which tab is currently selected (using hash and localstorage) and will try to open @@ -10,8 +11,32 @@ import {Tab} from "bootstrap"; class TabRememberHelper { constructor() { document.addEventListener("turbo:load", this.onLoad.bind(this)); + + //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); + } + + 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'); + } + } onLoad(event) { //Determine which tab should be shown (use hash if specified, otherwise use localstorage) @@ -24,14 +49,8 @@ class TabRememberHelper { if (activeTab) { - let parent = activeTab.parentElement.closest('.tab-pane'); - - //Iterate over each parent tab and show it - while(parent) { - Tab.getOrCreateInstance(parent).show(); - - parent = parent.parentElement.closest('.tab-pane'); - } + //Reveal our tab selector (needed for nested tabs) + this.revealElementOnTab(element); //Finally show the active tab itself Tab.getOrCreateInstance(activeTab).show();