/** * Replacement for jQuery's $(document).ready() function. * This is handy in making sure stuff fires after the DOM is ready to be touched. * Stolen from:https://stackoverflow.com/a/53601942/344028 * * @param fn Callback. */ function domReady(fn) { // If we're early to the party document.addEventListener('DOMContentLoaded', fn); // If late; I mean on time. if (document.readyState === 'interactive' || document.readyState === 'complete') { fn(); } } /** * TuiTabs controller */ function tabsController() { // Get all the tab elements (typically li tags). const tabs = document.getElementsByClassName('tui-tab'); if (!tabs.length) { // No tabs found, return early and save a couple CPU cycles. return; } for (const tab of tabs) { // Add click listeners to them. tab.addEventListener('click', function (e) { // Check if the clicked tab is disabled if(e.target.classList.contains("disabled")) { return; } // Remove the 'active' class from any and all tabs. for (const otherTab of tabs) { otherTab.classList.remove('active'); } // Get the content element. const tabContents = document.getElementsByClassName('tui-tab-content'); if (tabContents) { for (const tabContent of tabContents) { // Hide all tab contents. tabContent.style.display = 'none'; } } else { throw 'No tab content elements found.' } // Get the id of the tab contents we want to show. const tabContentId = e.target.getAttribute('data-tab-content'); if (tabContentId) { const tabContent = document.getElementById(tabContentId); if (tabContent) { // Show the tab contents. tabContent.style.display = 'block'; } else { throw 'No tab content element with id "' + tabContentId + '" found.'; } } // We are not going to throw an error here, since we could make the tab do something else that a tab // normally wouldn't do. // Set the clicked tab to have the 'active' class so we can use it in the next part. e.target.classList.add('active'); }); } // Grab the first tab with the active class. const activeTab = document.querySelector('.tui-tab.active'); if (activeTab) { // Now click it 'click' it. activeTab.click(); } else { // Nothing found, just click the first tab foud. tabs[0].click() } } /** * Date/time field controller */ function datetimeController() { // Get date/time elements. const clocks = document.getElementsByClassName('tui-datetime'); if (!clocks.length) { // No date time elements found, return early and save a couple CPU cycles. return; } // Kick off our clock interval stuff. datetimeInterval(); // Synchronize time and set interval to control the clocks setTimeout(() => { setInterval(datetimeInterval, 1000); }, 1000 - new Date().getMilliseconds()); function datetimeInterval() { for (const clock of clocks) { if (clock === null) { continue; } // Get the format we want to display in the element. let format = clock.getAttribute('data-format'); // parse out the date and time into constants. const today = new Date(); const month = (today.getMonth() + '').length === 2 ? today.getMonth() + 1 : '0' + (today.getMonth() + 1); const day = (today.getDay() + '').length === 2 ? today.getDay() + 1 : '0' + (today.getDay() + 1); const year = today.getFullYear() + ''; const hour = (today.getHours() + '').length === 2 ? today.getHours() : '0' + today.getHours(); const hour12 = (parseInt(hour) + 24) % '12' || '12'; const minute = (today.getMinutes() + '').length === 2 ? today.getMinutes() : '0' + today.getMinutes(); const second = (today.getSeconds() + '').length === 2 ? today.getSeconds() : '0' + today.getSeconds(); const ampm = parseInt(hour) >= 12 ? 'PM' : 'AM'; // Replace based on the format. format = format.replace('M', month); format = format.replace('d', day); format = format.replace('y', year); format = format.replace('H', hour); format = format.replace('h', hour12); format = format.replace('m', minute); format = format.replace('s', second); format = format.replace('a', ampm); // Show it in the element. clock.innerHTML = format; } } } /** * Sidenav Controller * There should only side navigation element at the moment. */ function sidenavController() { // Get the side navigation button (there should be only one, but if not, we are getting the first one). const sideNavButton = document.querySelector('.tui-sidenav-button'); if (!sideNavButton) { // No side navigation button found, return early and save a couple CPU cycles. return; } // Add the click event listener to the buttons. sideNavButton.addEventListener('click', () => { // Get the side navigation element (there should be only one, but if not, we are getting the first one). const sideNav = document.querySelector('.tui-sidenav'); if (sideNav) { if (sideNav.classList.contains('active')) { sideNav.classList.remove('active'); } else { sideNav.classList.add('active'); } } else { throw 'No sidenav element found.' } }); } /** * Modal controller */ function modalController() { // Get the overlap (overlay) element (there should be only one, but if not, we are getting the first one). const tuiOverlap = document.querySelector('.tui-overlap'); if (!tuiOverlap) { // No overlap found element, return early and save a couple CPU cycles. return; } // Find modal buttons. const modalButtons = document.getElementsByClassName('tui-modal-button'); for (const modalButton of modalButtons) { // Add the click event listener to the buttons. modalButton.addEventListener('click', (e) => { // Show the overlap. tuiOverlap.classList.add('active'); // Get the display element for the modal. const modalId = e.target.getAttribute('data-modal'); if (modalId) { const modal = document.getElementById(modalId); if (modal) { // Show it. modal.classList.add('active'); } else { throw 'No modal element with id of "' + modalId + '" found.'; } } else { throw 'Modal close button data-modal attribute is empty or not set.' } }); } // Find the close modal buttons. const modalCloseButtons = document.getElementsByClassName('tui-modal-close-button'); if (modalButtons.length > 0 && !modalCloseButtons.length) { // A modal without a close button, is a bad modal. throw 'No modal close buttons found.' } for (const modalCloseButton of modalCloseButtons) { // Add the click event listener to the buttons. modalCloseButton.addEventListener('click', (e) => { // Hide the the overlap. tuiOverlap.classList.remove('active'); // Get the display element id for the modal. const modalId = e.target.getAttribute('data-modal'); if (modalId) { // Get the modal element. const modal = document.getElementById(modalId); if (modal) { // Hide it. modal.classList.remove('active'); } else { throw 'No modal element with id of "' + modalId + '" found.'; } } else { throw 'Modal close button data-modal attribute is empty or not set.' } }); } } /** * Init: This is at the bottom to make sure it is fired correctly. */ domReady(function () { tabsController(); datetimeController(); sidenavController(); modalController(); });