diff --git a/meshview/templates/nodelist.html b/meshview/templates/nodelist.html
index 65195d3..045b780 100644
--- a/meshview/templates/nodelist.html
+++ b/meshview/templates/nodelist.html
@@ -184,11 +184,15 @@ function saveFavorites(favs) {
}
function toggleFavorite(nodeId) {
- let favs = getFavorites();
- const idx = favs.indexOf(nodeId);
- if (idx >= 0) favs.splice(idx, 1);
- else favs.push(nodeId);
- saveFavorites(favs);
+ let favorites = getFavorites();
+ const index = favorites.indexOf(nodeId);
+ if (index > -1) {
+ favorites.splice(index, 1);
+ } else {
+ favorites.push(nodeId);
+ }
+ saveFavorites(favorites);
+ // Note: applyFilters() will be called by the event listener after this function returns
}
function isFavorite(nodeId) {
@@ -264,6 +268,8 @@ document.addEventListener("DOMContentLoaded", async function() {
e.target.textContent = "★";
}
toggleFavorite(nodeId);
+ // Reapply filters after toggling favorite
+ applyFilters();
}
});
@@ -321,16 +327,33 @@ document.addEventListener("DOMContentLoaded", async function() {
function applyFilters() {
const searchTerm = searchBox.value.trim().toLowerCase();
- let filtered = allNodes.filter(n => {
- const roleMatch = !roleFilter.value || n.role === roleFilter.value;
- const channelMatch = !channelFilter.value || n.channel === channelFilter.value;
- const hwMatch = !hwFilter.value || n.hw_model === hwFilter.value;
- const fwMatch = !firmwareFilter.value || n.firmware === firmwareFilter.value;
- const searchMatch =
- !searchTerm ||
- (n.long_name && n.long_name.toLowerCase().includes(searchTerm)) ||
- (n.short_name && n.short_name.toLowerCase().includes(searchTerm)) ||
- n.node_id.toString().includes(searchTerm);
+ let filtered = allNodes.filter(node => {
+ const roleMatch = !roleFilter.value || node.role === roleFilter.value;
+ const channelMatch = !channelFilter.value || node.channel === channelFilter.value;
+ const hwMatch = !hwFilter.value || node.hw_model === hwFilter.value;
+ const firmwareMatch = !firmwareFilter.value || node.firmware === firmwareFilter.value;
+
+ // Improved search matching that handles null/undefined values properly
+ let searchMatch = true;
+ if (searchTerm) {
+ searchMatch = false;
+ // Check long_name
+ if (node.long_name && typeof node.long_name === 'string' && node.long_name.toLowerCase().includes(searchTerm)) {
+ searchMatch = true;
+ }
+ // Check short_name
+ if (!searchMatch && node.short_name && typeof node.short_name === 'string' && node.short_name.toLowerCase().includes(searchTerm)) {
+ searchMatch = true;
+ }
+ // Check node_id (case-insensitive)
+ if (!searchMatch && node.node_id != null && String(node.node_id).toLowerCase().includes(searchTerm)) {
+ searchMatch = true;
+ }
+ // Check id (case-insensitive)
+ if (!searchMatch && node.id != null && String(node.id).toLowerCase().includes(searchTerm)) {
+ searchMatch = true;
+ }
+ }
const favMatch = !showOnlyFavorites || isFavorite(n.node_id);