From 4d5535d72c4bf9ebeb18c70ab7b82269d52fb78c Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Mon, 17 Feb 2025 22:15:01 +0100 Subject: [PATCH] UI - Sometimes the DOM wasnt ready when tab selection triggered via CSS, which displayed empty tabs on some browsers --- changedetectionio/static/js/tabs.js | 98 +++++++++++-------- .../static/styles/scss/styles.scss | 10 +- changedetectionio/static/styles/styles.css | 5 +- 3 files changed, 60 insertions(+), 53 deletions(-) diff --git a/changedetectionio/static/js/tabs.js b/changedetectionio/static/js/tabs.js index b4ba6e9f..45061d76 100644 --- a/changedetectionio/static/js/tabs.js +++ b/changedetectionio/static/js/tabs.js @@ -1,48 +1,66 @@ -// Rewrite this is a plugin.. is all this JS really 'worth it?' +(function ($) { + $.fn.hashTabs = function (options) { + var settings = $.extend({ + tabContainer: ".tabs ul", + tabSelector: "li a", + tabContent: ".tab-pane-inner", + activeClass: "active", + errorClass: ".messages .error", + bodyClassToggle: "full-width" + }, options); -window.addEventListener('hashchange', function () { - var tabs = document.getElementsByClassName('active'); - while (tabs[0]) { - tabs[0].classList.remove('active'); - document.body.classList.remove('full-width'); - } - set_active_tab(); -}, false); + var $tabs = $(settings.tabContainer).find(settings.tabSelector); -var has_errors = document.querySelectorAll(".messages .error"); -if (!has_errors.length) { - if (document.location.hash == "") { - location.replace(document.querySelector(".tabs ul li:first-child a").hash); - } else { - set_active_tab(); - } -} else { - focus_error_tab(); -} + function setActiveTab() { + var hash = window.location.hash; + var $activeTab = $tabs.filter("[href='" + hash + "']"); -function set_active_tab() { - document.body.classList.remove('full-width'); - var tab = document.querySelectorAll("a[href='" + location.hash + "']"); - if (tab.length) { - tab[0].parentElement.className = "active"; - } + // Remove active class from all tabs + $(settings.tabContainer).find("li").removeClass(settings.activeClass); -} + // Add active class to selected tab + if ($activeTab.length) { + $activeTab.parent().addClass(settings.activeClass); + } -function focus_error_tab() { - // time to use jquery or vuejs really, - // activate the tab with the error - var tabs = document.querySelectorAll('.tabs li a'), i; - for (i = 0; i < tabs.length; ++i) { - var tab_name = tabs[i].hash.replace('#', ''); - var pane_errors = document.querySelectorAll('#' + tab_name + ' .error') - if (pane_errors.length) { - document.location.hash = '#' + tab_name; - return true; + // Show the correct content + $(settings.tabContent).hide(); + if (hash) { + $(hash).show(); + } } - } - return false; -} - + + function focusErrorTab() { + $tabs.each(function () { + var tabName = this.hash.replace("#", ""); + if ($("#" + tabName).find(settings.errorClass).length) { + window.location.hash = "#" + tabName; + return false; // Stop loop on first error tab + } + }); + } + + function initializeTabs() { + if ($(settings.errorClass).length) { + focusErrorTab(); + } else if (!window.location.hash) { + window.location.replace($tabs.first().attr("href")); + } else { + setActiveTab(); + } + } + + // Listen for hash changes + $(window).on("hashchange", setActiveTab); + + // Initialize on page load + initializeTabs(); + + return this; // Enable jQuery chaining + }; +})(jQuery); +$(document).ready(function () { + $(".tabs").hashTabs(); +}); \ No newline at end of file diff --git a/changedetectionio/static/styles/scss/styles.scss b/changedetectionio/static/styles/scss/styles.scss index 4c698088..ab55ae82 100644 --- a/changedetectionio/static/styles/scss/styles.scss +++ b/changedetectionio/static/styles/scss/styles.scss @@ -945,15 +945,7 @@ $form-edge-padding: 20px; } .tab-pane-inner { - - &:not(:target) { - display: none; - } - - &:target { - display: block; - } - + display: none; // doesnt need padding because theres another row of buttons/activity padding: 0px; } diff --git a/changedetectionio/static/styles/styles.css b/changedetectionio/static/styles/styles.css index d49506dc..cdfba562 100644 --- a/changedetectionio/static/styles/styles.css +++ b/changedetectionio/static/styles/styles.css @@ -1159,11 +1159,8 @@ textarea::placeholder { border-radius: 5px; } .tab-pane-inner { + display: none; padding: 0px; } - .tab-pane-inner:not(:target) { - display: none; } - .tab-pane-inner:target { - display: block; } .beta-logo { height: 50px;