From: Giorgio Ravera Date: Tue, 9 Jun 2026 13:06:17 +0000 (+0200) Subject: Different searchbard for mobile and deskop X-Git-Tag: v0.0.2~18 X-Git-Url: http://git.giorgioravera.it/?a=commitdiff_plain;h=fd4f0c24c2b0e49f56e55edf94ebe8898713ce4b;p=network-manager.git Different searchbard for mobile and deskop --- diff --git a/frontend/aliases.html b/frontend/aliases.html index 303b02b..f957687 100644 --- a/frontend/aliases.html +++ b/frontend/aliases.html @@ -66,6 +66,7 @@
+

@@ -77,22 +78,34 @@
- -
+ +
+ aria-label="Search alias">
+ +
+ +
+ + +
+
+ + +
+ +

@@ -134,11 +157,25 @@ - - - - - + + + + + + + + + diff --git a/frontend/devices.html b/frontend/devices.html index 6ca3e36..0009357 100644 --- a/frontend/devices.html +++ b/frontend/devices.html @@ -66,6 +66,7 @@
+

@@ -77,22 +78,34 @@
- -
+ +
+ aria-label="Search device">
+ +
+ +
+ + +
+
+ + +
+ +

@@ -134,13 +157,33 @@
Alias Target DescriptionOptions Actions + Alias + + Target + + Description + + Options + + Actions +
- - - - - - - + + + + + + + + + + + + + diff --git a/frontend/hosts.html b/frontend/hosts.html index 8195198..15a2875 100644 --- a/frontend/hosts.html +++ b/frontend/hosts.html @@ -66,6 +66,7 @@
+

@@ -77,22 +78,34 @@
- -
+ +
+ aria-label="Search hosts">
+ +
+ +
+ + +
+
+ + +
+ +

@@ -134,12 +157,29 @@
IP Address MAC AddressHostname DescriptionState Active Actions + IP Address + + MAC Address + + Hostname + + Description + + State + + Active + + Actions +
- - - - - - + + + + + + + + + + + diff --git a/frontend/js/aliases.js b/frontend/js/aliases.js index a5a0cd0..042d0b1 100644 --- a/frontend/js/aliases.js +++ b/frontend/js/aliases.js @@ -1,5 +1,5 @@ // Import common js -import { loadModals, showToast, sortTable, initSortableTable, resetSorting, filterTable, clearSearch, handleReload } from './common.js'; +import { loadModals, showToast, sortTable, initSortableTable, resetSorting, handleSearch, filterTable, clearSearch, handleReload } from './common.js'; // Import services import { serviceReloadDNS, serviceReloadDHCP, serviceGetAliases, serviceGetAlias, serviceCreateAlias, serviceUpdateAlias, serviceDeleteAlias } from './services.js'; @@ -231,12 +231,11 @@ function updateTable () { tableWrapper.classList.remove("d-none"); // apply current search filter - const searchInput = document.getElementById("searchInput"); - if (searchInput) { - const term = searchInput.value.trim().toLowerCase(); - if (term) { - filterTable(term); - } + const term = + document.getElementById('searchInput')?.value || + document.getElementById('searchInputMobile')?.value; + if (term) { + handleSearch(term); } } @@ -490,16 +489,20 @@ function initUI() { // SEARCH // ----------------------------- function initSearch() { - // search bar - const input = document.getElementById("searchInput"); - if (!input) return; - - // clean input on load - input.value = ""; - // live filter for each keystroke - input.addEventListener("input", (e) => { - const term = e.target.value.trim().toLowerCase(); - filterTable(term); + + ["searchInput", "searchInputMobile"].forEach(id => { + + const input = document.getElementById(id); + + if (!input) return; + + // clean input on load + input.value = ""; + + // live filter + input.addEventListener("input", (e) => { + handleSearch(e.target.value); + }); }); } @@ -608,7 +611,8 @@ function handleKeyboard(e) { const tag = (e.target.tagName || "").toLowerCase(); const isTypingField = tag === "input" || tag === "textarea" || tag === "select" || e.target.isContentEditable; - const isSearchInput = e.target.id === "searchInput"; + const isSearchInput = + e.target.id === "searchInput" || e.target.id === "searchInputMobile"; // ESC should clear search and reset sorting only if not focused on a typing field, or if focused on the search input (to allow quick clearing of search) if (!isTypingField || isSearchInput) { diff --git a/frontend/js/common.js b/frontend/js/common.js index 6f73280..f77e278 100644 --- a/frontend/js/common.js +++ b/frontend/js/common.js @@ -329,6 +329,21 @@ export function initSortableTable() { ths.forEach(th => th.setAttribute("aria-sort", "none")); } +/** + * search handler + */ +export function handleSearch(value, callback) { + const desktopSearch = document.getElementById('searchInput'); + const mobileSearch = document.getElementById('searchInputMobile'); + + // sync valori + desktopSearch.value = value; + mobileSearch.value = value; + + const term = value.trim().toLowerCase(); + callback(term); +} + /** * Live filter: mostra solo le righe che contengono il testo di ricerca (case-insensitive) */ @@ -345,10 +360,15 @@ export function filterTable(term) { * Clear search input and reset table filter */ export function clearSearch() { - const input = document.getElementById("searchInput"); - if (input) { - input.value = ""; - input.blur(); + const desktopSearch = document.getElementById("searchInput"); + if (desktopSearch) { + desktopSearch.value = ""; + desktopSearch.blur(); + } + const mobileSearch = document.getElementById("searchInputMobile"); + if (mobileSearch) { + mobileSearch.value = ""; + mobileSearch.blur(); } } diff --git a/frontend/js/devices.js b/frontend/js/devices.js index ad00407..d8273e3 100644 --- a/frontend/js/devices.js +++ b/frontend/js/devices.js @@ -1,5 +1,5 @@ // Import common js -import { loadModals, isValidIPv4, isValidIPv6, isValidMAC, showToast, sortTable, initSortableTable, resetSorting, filterTable, clearSearch, handleReload } from './common.js'; +import { loadModals, isValidIPv4, isValidIPv6, isValidMAC, showToast, sortTable, initSortableTable, resetSorting, handleSearch, filterTable, clearSearch, handleReload } from './common.js'; // Import services import { serviceReloadDNS, serviceReloadDHCP, serviceGetDHCPLeases, serviceGetDHCPLease, serviceDeleteDHCPLease, serviceGetDevices, serviceGetHost, serviceCreateHost, serviceUpdateHost, serviceDeleteHost } from './services.js'; @@ -292,12 +292,11 @@ function updateTable () { tableWrapper.classList.remove("d-none"); // apply current search filter - const searchInput = document.getElementById("searchInput"); - if (searchInput) { - const term = searchInput.value.trim().toLowerCase(); - if (term) { - filterTable(term); - } + const term = + document.getElementById('searchInput')?.value || + document.getElementById('searchInputMobile')?.value; + if (term) { + handleSearch(term, filterTable); } } @@ -619,16 +618,20 @@ function initUI() { // SEARCH // ----------------------------- function initSearch() { - // search bar - const input = document.getElementById("searchInput"); - if (!input) return; - - // clean input on load - input.value = ""; - // live filter for each keystroke - input.addEventListener("input", (e) => { - const term = e.target.value.trim().toLowerCase(); - filterTable(term); + + ["searchInput", "searchInputMobile"].forEach(id => { + + const input = document.getElementById(id); + + if (!input) return; + + // clean input on load + input.value = ""; + + // live filter + input.addEventListener("input", (e) => { + handleSearch(e.target.value, filterTable); + }); }); } @@ -737,7 +740,8 @@ function handleKeyboard(e) { const tag = (e.target.tagName || "").toLowerCase(); const isTypingField = tag === "input" || tag === "textarea" || tag === "select" || e.target.isContentEditable; - const isSearchInput = e.target.id === "searchInput"; + const isSearchInput = + e.target.id === "searchInput" || e.target.id === "searchInputMobile"; // ESC should clear search and reset sorting only if not focused on a typing field, or if focused on the search input (to allow quick clearing of search) if (!isTypingField || isSearchInput) { diff --git a/frontend/js/hosts.js b/frontend/js/hosts.js index e9b6d6e..daf4569 100644 --- a/frontend/js/hosts.js +++ b/frontend/js/hosts.js @@ -1,5 +1,5 @@ // Import common js -import { loadModals, isValidIPv4, isValidIPv6, isValidMAC, showToast, sortTable, initSortableTable, resetSorting, filterTable, clearSearch, handleReload } from './common.js'; +import { loadModals, isValidIPv4, isValidIPv6, isValidMAC, showToast, sortTable, initSortableTable, resetSorting, handleSearch, filterTable, clearSearch, handleReload } from './common.js'; // Import services import { serviceReloadDNS, serviceReloadDHCP, serviceGetHosts, serviceGetHost, serviceCreateHost, serviceUpdateHost, serviceDeleteHost } from './services.js'; @@ -241,12 +241,11 @@ function updateTable () { tableWrapper.classList.remove("d-none"); // apply current search filter - const searchInput = document.getElementById("searchInput"); - if (searchInput) { - const term = searchInput.value.trim().toLowerCase(); - if (term) { - filterTable(term); - } + const term = + document.getElementById('searchInput')?.value || + document.getElementById('searchInputMobile')?.value; + if (term) { + handleSearch(term, filterTable); } } @@ -515,16 +514,20 @@ function initUI() { // SEARCH // ----------------------------- function initSearch() { - // search bar - const input = document.getElementById("searchInput"); - if (!input) return; - - // clean input on load - input.value = ""; - // live filter for each keystroke - input.addEventListener("input", (e) => { - const term = e.target.value.trim().toLowerCase(); - filterTable(term); + + ["searchInput", "searchInputMobile"].forEach(id => { + + const input = document.getElementById(id); + + if (!input) return; + + // clean input on load + input.value = ""; + + // live filter + input.addEventListener("input", (e) => { + handleSearch(e.target.value, filterTable); + }); }); } @@ -633,7 +636,8 @@ function handleKeyboard(e) { const tag = (e.target.tagName || "").toLowerCase(); const isTypingField = tag === "input" || tag === "textarea" || tag === "select" || e.target.isContentEditable; - const isSearchInput = e.target.id === "searchInput"; + const isSearchInput = + e.target.id === "searchInput" || e.target.id === "searchInputMobile"; // ESC should clear search and reset sorting only if not focused on a typing field, or if focused on the search input (to allow quick clearing of search) if (!isTypingField || isSearchInput) { diff --git a/frontend/js/leases.js b/frontend/js/leases.js index 36b6daa..77504e1 100644 --- a/frontend/js/leases.js +++ b/frontend/js/leases.js @@ -1,5 +1,5 @@ // Import common js -import { loadModals, isValidIPv4, isValidIPv6, isValidMAC, showToast, sortTable, initSortableTable, resetSorting, filterTable, clearSearch, handleReload } from './common.js'; +import { loadModals, isValidIPv4, isValidIPv6, isValidMAC, showToast, sortTable, initSortableTable, resetSorting, handleSearch, filterTable, clearSearch, handleReload } from './common.js'; // Import services import { serviceReloadDNS, serviceReloadDHCP, serviceGetDHCPLeases, serviceDeleteDHCPLease, serviceGetDHCPLease, serviceCreateHost} from './services.js'; @@ -256,12 +256,11 @@ function updateTable () { tableWrapper.classList.remove("d-none"); // apply current search filter - const searchInput = document.getElementById("searchInput"); - if (searchInput) { - const term = searchInput.value.trim().toLowerCase(); - if (term) { - filterTable(term); - } + const term = + document.getElementById('searchInput')?.value || + document.getElementById('searchInputMobile')?.value; + if (term) { + handleSearch(term, filterTable); } } @@ -515,16 +514,20 @@ function initUI() { // SEARCH // ----------------------------- function initSearch() { - // search bar - const input = document.getElementById("searchInput"); - if (!input) return; - - // clean input on load - input.value = ""; - // live filter for each keystroke - input.addEventListener("input", (e) => { - const term = e.target.value.trim().toLowerCase(); - filterTable(term); + + ["searchInput", "searchInputMobile"].forEach(id => { + + const input = document.getElementById(id); + + if (!input) return; + + // clean input on load + input.value = ""; + + // live filter + input.addEventListener("input", (e) => { + handleSearch(e.target.value, filterTable); + }); }); } @@ -625,7 +628,8 @@ function handleKeyboard(e) { const tag = (e.target.tagName || "").toLowerCase(); const isTypingField = tag === "input" || tag === "textarea" || tag === "select" || e.target.isContentEditable; - const isSearchInput = e.target.id === "searchInput"; + const isSearchInput = + e.target.id === "searchInput" || e.target.id === "searchInputMobile"; // ESC should clear search and reset sorting only if not focused on a typing field, or if focused on the search input (to allow quick clearing of search) if (!isTypingField || isSearchInput) { diff --git a/frontend/js/settings.js b/frontend/js/settings.js index a3a42f1..59d2def 100644 --- a/frontend/js/settings.js +++ b/frontend/js/settings.js @@ -1,5 +1,5 @@ // Import common js -import { loadModals, showToast, clearSearch, showConfirmModal, handleReload } from './common.js'; +import { loadModals, showToast, handleSearch, clearSearch, showConfirmModal, handleReload } from './common.js'; // Import services import { serviceGetConfigs, serviceGetConfig, serviceUpdateConfig, serviceResetConfig, serviceRestartApp, serviceIsAlive } from './services.js'; @@ -214,12 +214,10 @@ async function restartApp(button) { // ----------------------------- // Update table with current configs // ----------------------------- -function updateTable () { +function updateTable (filter = null) { const loader = document.getElementById("loader"); const tableWrapper = document.getElementById("tableWrapper"); - const searchInput = document.getElementById("searchInput"); - const term = searchInput?.value?.trim().toLowerCase(); - const hasSearch = !!term; + const hasSearch = !!filter; const expandBtn = document.getElementById("expandAllBtn"); const collapseBtn = document.getElementById("collapseAllBtn"); @@ -280,24 +278,24 @@ function updateTable () { let rows = grouped[group]; - if (term) { + if (filter) { rows = rows.filter(c => { return ( - (c.key ?? "").toString().toLowerCase().includes(term) || - (c.value ?? "").toString().toLowerCase().includes(term) || - (c.description ?? "").toString().toLowerCase().includes(term) + (c.key ?? "").toString().toLowerCase().includes(filter) || + (c.value ?? "").toString().toLowerCase().includes(filter) || + (c.description ?? "").toString().toLowerCase().includes(filter) ); }); } // skip group if no result - if (term && rows.length === 0) return; + if (filter && rows.length === 0) return; // GROUP HEADER tdGroup.colSpan = 7; trGroup.className = "table-group-header"; trGroup.setAttribute("data-group", groupKey); - tdGroup.innerHTML = term + tdGroup.innerHTML = filter ? '' : ''; tdGroup.appendChild( @@ -315,7 +313,7 @@ function updateTable () { tr.setAttribute("data-parent-group", groupKey); // show only filtered keys - if (!term) { + if (!filter) { tr.classList.add("d-none"); } @@ -744,16 +742,20 @@ function initUI() { // SEARCH // ----------------------------- function initSearch() { - // search bar - const input = document.getElementById("searchInput"); - if (!input) return; - - // clean input on load - input.value = ""; - // live filter for each keystroke - input.addEventListener("input", (e) => { - const term = e.target.value.trim().toLowerCase(); - updateTable(); + + ["searchInput", "searchInputMobile"].forEach(id => { + + const input = document.getElementById(id); + + if (!input) return; + + // clean input on load + input.value = ""; + + // live filter + input.addEventListener("input", (e) => { + handleSearch(e.target.value, updateTable); + }); }); } @@ -869,7 +871,8 @@ function handleKeyboard(e) { const tag = (e.target.tagName || "").toLowerCase(); const isTypingField = tag === "input" || tag === "textarea" || tag === "select" || e.target.isContentEditable; - const isSearchInput = e.target.id === "searchInput"; + const isSearchInput = + e.target.id === "searchInput" || e.target.id === "searchInputMobile"; // ESC should clear search only if not focused on a typing field, or if focused on the search input (to allow quick clearing of search) if (!isTypingField || isSearchInput) { diff --git a/frontend/leases.html b/frontend/leases.html index ddcbebe..31afc21 100644 --- a/frontend/leases.html +++ b/frontend/leases.html @@ -66,6 +66,7 @@
+

@@ -77,22 +78,34 @@
- -
+ +
+ aria-label="Search lease">
+ +
+ +
+ + +
+
+ + +
+ +

@@ -134,13 +157,33 @@
Hostname IP Address MAC Address Description Options Actions + Hostname + + IP Address + + MAC Address + + Description + + Options + + Actions +
- - - - - - - + + + + + + + + + + + + + diff --git a/frontend/settings.html b/frontend/settings.html index 43cd2a1..98df7d2 100644 --- a/frontend/settings.html +++ b/frontend/settings.html @@ -66,6 +66,7 @@
+

@@ -77,30 +78,42 @@
- -
+ +
+ aria-label="Search config">
- + +
+ +
+ + +
+ + +
+ + +
+ +

@@ -132,10 +155,21 @@
IP AddressMAC Hostname Start End State Actions + IP Address + + MAC + + Hostname + + Start + + End + + State + + Actions +
- - - - + + + + + + +
Parameter Value DescriptionActions + Parameter + + Value + + Description + + Actions +