commit 0c50f105fcf0a895f43115cf024c0094c94ea446
parent 57c84094b4fb57d63aa8ec95856c4d15aaefedca
Author: breadcat <breadcat@users.noreply.github.com>
Date: Tue, 28 Apr 2026 19:23:28 +0100
Add property and tag list filter script
Diffstat:
4 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/static/list-filter.js b/static/list-filter.js
@@ -0,0 +1,66 @@
+(() => {
+ // filter input HTML
+ const input = document.createElement("input");
+ input.type = "search";
+ input.id = "list-filter";
+ input.placeholder = "Filter...";
+ input.autocomplete = "off";
+ input.className = "list-filter-input";
+ const firstDetails = document.querySelector("details");
+ if (!firstDetails) return;
+ firstDetails.parentNode.insertBefore(input, firstDetails);
+
+ // filter logic
+ function filter(query) {
+ const q = query.trim().toLowerCase();
+ const allDetails = document.querySelectorAll("details");
+
+ allDetails.forEach((details) => {
+ const summary = details.querySelector("summary");
+ const items = details.querySelectorAll("li");
+ const categoryText = summary ? summary.textContent.toLowerCase() : "";
+
+ if (!q) {
+ // reset
+ details.removeAttribute("open");
+ details.style.display = "";
+ items.forEach((li) => (li.style.display = ""));
+ return;
+ }
+
+ const categoryMatches = categoryText.includes(q);
+
+ let anyItemVisible = false;
+ items.forEach((li) => {
+ const matches = categoryMatches || li.textContent.toLowerCase().includes(q);
+ li.style.display = matches ? "" : "none";
+ if (matches) anyItemVisible = true;
+ });
+
+ const visible = categoryMatches || anyItemVisible;
+ details.style.display = visible ? "" : "none";
+
+ // open on match
+ if (visible) {
+ details.setAttribute("open", "");
+ } else {
+ details.removeAttribute("open");
+ }
+ });
+ }
+
+ // debounce timer
+ let debounceTimer;
+ input.addEventListener("input", () => {
+ clearTimeout(debounceTimer);
+ debounceTimer = setTimeout(() => filter(input.value), 150);
+ });
+
+ // escape to clear
+ input.addEventListener("keydown", (e) => {
+ if (e.key === "Escape") {
+ input.value = "";
+ filter("");
+ }
+ });
+})();
diff --git a/static/style.css b/static/style.css
@@ -3,7 +3,7 @@ body,button{background:#1a1a1a;color:#cfcfcf;font-family:sans-serif;margin:0;pos
body details {text-transform: capitalize}
body details div.file-item a {text-transform: none}
a{color:#add8e6;text-decoration:none}
-input[type="url"], input[type="text"] {background:#1a1a1a;color:#cfcfcf;border:1px solid gray;margin: 8px;padding:8px;outline: none; box-sizing: border-box}
+input[type="url"], input[type="text"], .list-filter-input {background:#1a1a1a;color:#cfcfcf;border:1px solid gray;margin: 8px;padding:8px;outline: none; box-sizing: border-box}
input[type="url"]:focus, input[type="text"]:focus{border:1px solid white;background-color:#3a3a3a}
div#search-container {border-left:1px solid gray; display: flex; align-items: center}
span.required {color: red}
@@ -186,3 +186,6 @@ div.config-split {flex: 1}
.dropdown-empty{padding:10px;color:#666;font-size:14px}
.operation-name{font-weight:700}
.operation-desc{font-size:12px;color:#666}
+
+/* list filter input box */
+.list-filter-input {display: block; margin: 1rem 0; padding: 0.4rem 0.6rem; font-size: 1rem; width: 100%; max-width: 400px}
+\ No newline at end of file
diff --git a/templates/properties.html b/templates/properties.html
@@ -13,4 +13,6 @@
<p>No properties have been computed yet. Visit the <a href="/admin">Admin</a> page to compute them.</p>
{{end}}
+<script src="/static/list-filter.js" defer></script>
+
{{template "_footer"}}
diff --git a/templates/tags.html b/templates/tags.html
@@ -11,4 +11,6 @@
</details>
{{end}}
+<script src="/static/list-filter.js" defer></script>
+
{{template "_footer"}}
\ No newline at end of file