Jake Vanderwerf
2026-06-29 4089ba01e0881c89a72332e13bc3a80b6bddec2a
assets/js/concise/Tabs.js
@@ -10,6 +10,7 @@
      this.tabs = new Map();
      this.hasHash = false;
      this.shouldNotify = true;
      this.init();
   }
   init() {
@@ -37,6 +38,9 @@
         const tab = e.target.closest(this.selectors.tab);
         if (tab) {
            if (tab.dataset.skip) {
               delete config.preCheck;
            }
            this.switchTab(tab.dataset.tab, config);
         }
      }
@@ -61,6 +65,9 @@
         console.error('No tab navigation or section found');
         return false;
      }
      if (ui.nav.previousElementSibling && ui.nav.previousElementSibling.classList.contains('form-progress')) {
      }
      let tabsId = window.generateID('tab');
      container.dataset.tabsId = tabsId;
@@ -69,7 +76,7 @@
      ui.sections.forEach(section => {
         if (section.querySelector('.tabs')) {
            options.hasChildren = true;
            this.registerTab(section, {parent: tabsId});
            this.registerTab(section, {parent: tabsId, ... options});
         }
      });
@@ -80,15 +87,21 @@
      let config = {
         id: tabsId,
         ui: ui,
         updateURL: options.updateURL ?? true
         updateURL: options.updateURL ?? true,
         ... options
      };
      if (Object.hasOwn(options, 'preCheck')) {
         config.preCheck = options.preCheck;
      }
      //Add listeners
      ui.nav.addEventListener('click', this.clickHandler);
      ui.select?.addEventListener('change', this.changeHandler);
      this.tabs.set(tabsId, config);
      this.shouldNotify = false;
      this.determineActiveTab(config);
      this.shouldNotify = true;
      return config;
   }
@@ -147,12 +160,15 @@
      config = (typeof config === 'string') ? this.tabs.get(config) : config;
      if (!config) return;
      let activeTab = config.ui.sections.filter(section => section.classList.contains('active'));
      if (Object.hasOwn(config, 'preCheck') && !config.preCheck(activeTab[0], tab, config)) return;
      if (Object.hasOwn(config, 'preCheck') && !config.preCheck(activeTab[0], config)) return;
      if (document.activeElement && this.isInTabs(document.activeElement, config)) document.activeElement.blur();
      config.ui.buttons.forEach((btn, index) => {
      config.ui.buttons.forEach(btn => {
         btn.classList.remove('active', 'previous', 'next');
      });
      config.ui.buttons.forEach((btn, index) => {
         let isActive = btn.dataset.tab === tab;
         btn.setAttribute('aria-selected', isActive);
         if (isActive) {
@@ -187,7 +203,9 @@
      if (config?.updateURL) this.updateURL(config);
      if (config.ui.select) this.maybeUpdateSelect(tab, config);
      this.a11y.announce(`Switched to ${tab} tab`);
      if (this.shouldNotify) {
         this.a11y.announce(`Switched to ${tab} tab`);
      }
   }
   updateChildTabs(id) {
      Array.from(this.tabs.values()).filter(conf => conf.parent === id).forEach(inst => {