/** * Creates scaffolding for tabs. * Requires a format similar to: * * <div class="tab-links"> * <button data-tab="one">Tab 1</button> * <button data-tab="two">Tab 2</button> * </div> * <div class="tab-contents"> * <div id="one"> * Tab contents for button 1 * </div> * <div id="two"> * Tab contents for button 2 * </div> * </div> * * Where the links have a `data-tab` property, and the contents * have an id that matches those properties. They must be immediate * children of the parent containers. * @param {HTMLElement} tabLinks - container for the tab buttons * @param {HTMLElement} tabContents - container for the tab contents * @param {string} defaultTab - optional - id for the tab that should be visible by default. Otherwise, defaults to the first tab */ function createTabs(tabLinks, tabContents, defaultTab) { const children = tabLinks.children for (let child of children) { if (child.tagName.toLowerCase() === 'button') { if (!defaultTab) { defaultTab = child.dataset.tab } // add a function child.onclick = () => { hideAllTabContents(tabContents) setActiveTabLink(tabLinks, child.dataset.tab) showTab(tabContents, child.dataset.tab) } } } hideAllTabContents(tabContents) showTab(tabContents, defaultTab) setActiveTabLink(tabLinks, defaultTab) } function hideAllTabContents(tabContents) { for (let tabContent of tabContents.children) { tabContent.style.display = 'none' } } function showTab(tabContents, tabId) { let tab = tabContents.querySelector('#' + tabId) if (!tab) { console.warn('Trying to show nonexistent tab') return } tab.style.display = 'block' } function setActiveTabLink(tabLinks, activeTabId) { for (let tabLink of tabLinks.children) { tabLink.className = tabLink.className.replace(' active', '') if (tabLink.dataset.tab === activeTabId) { tabLink.className += ' active' } } }