Update web/templates/entry_view.html

This commit is contained in:
2025-08-23 15:59:04 +00:00
parent e509d35015
commit 37d2531364
+13 -19
View File
@@ -467,10 +467,10 @@ function showToast(message, duration = 3000) {
} }
</script> </script>
<!-- Highlighter: only runs when user pref is enabled and when a last search exists --> <!-- Highlighter: uses exact DB field names -->
<!-- Highlighter: only runs when user pref is enabled and when a last search exists -->
<script> <script>
document.addEventListener("DOMContentLoaded", async () => { document.addEventListener("DOMContentLoaded", async () => {
// Respect per-user toggle
let enabled = true; let enabled = true;
try { try {
const res = await fetch("/api/get-prefs/"); const res = await fetch("/api/get-prefs/");
@@ -478,14 +478,13 @@ document.addEventListener("DOMContentLoaded", async () => {
if (prefs && typeof prefs.highlight_search_hits !== "undefined") { if (prefs && typeof prefs.highlight_search_hits !== "undefined") {
enabled = !!prefs.highlight_search_hits; enabled = !!prefs.highlight_search_hits;
} }
} catch (e) { /* default true */ } } catch (_) {}
if (!enabled) return; if (!enabled) return;
// Prefer the JS-literal fallback first (always valid for our Django output) // Read last search (prefer JS-literal fallback, then JSON blob)
let q = (window.__lastSearchQ || "").trim(); let q = (window.__lastSearchQ || "").trim();
let fields = Array.isArray(window.__lastSearchFields) ? window.__lastSearchFields : []; let fields = Array.isArray(window.__lastSearchFields) ? window.__lastSearchFields : [];
// If not present, fall back to parsing the JSON <script> (for completeness)
if ((!q || !fields.length)) { if ((!q || !fields.length)) {
const dataEl = document.getElementById("last-search-data"); const dataEl = document.getElementById("last-search-data");
if (dataEl) { if (dataEl) {
@@ -493,16 +492,12 @@ document.addEventListener("DOMContentLoaded", async () => {
const payload = JSON.parse(dataEl.textContent || "{}"); const payload = JSON.parse(dataEl.textContent || "{}");
q = (payload.q || "").trim(); q = (payload.q || "").trim();
fields = Array.isArray(payload.fields) ? payload.fields : []; fields = Array.isArray(payload.fields) ? payload.fields : [];
} catch (_) { } catch (_) {}
/* ignore */
} }
} }
}
if (!q || !fields.length) return; if (!q || !fields.length) return;
// Exact field -> selector mapping for your template IDs
// Map search field names -> selectors on this page
const fieldToSelector = { const fieldToSelector = {
subject: "#subject-list", subject: "#subject-list",
illustration: "#illustration-text", illustration: "#illustration-text",
@@ -510,25 +505,23 @@ document.addEventListener("DOMContentLoaded", async () => {
scripture_raw: "#scripture-text", scripture_raw: "#scripture-text",
source: "#source-text", source: "#source-text",
talk_title: "#talk_title-text", talk_title: "#talk_title-text",
talk_number: "#talk_title-text" talk_number: "#talk_title-text",
}; };
// Tokenize similar to your search: quoted phrases kept; remove wildcard chars // Tokenize like your search (keep quoted phrases, strip * and ?)
const tokens = tokenize(q).map(t => t.replaceAll("*","").replaceAll("?","")).filter(Boolean); const tokens = tokenize(q).map(t => t.replaceAll("*","").replaceAll("?","")).filter(Boolean);
if (!tokens.length) return; if (!tokens.length) return;
// Highlight only within fields that were searched
for (const f of fields) { for (const f of fields) {
const sel = fieldToSelector[f]; const sel = fieldToSelector[f];
if (!sel) continue; if (!sel) continue; // ignore fields not shown on page
const container = document.querySelector(sel); const container = document.querySelector(sel);
if (!container) continue; if (!container) continue;
for (const tok of tokens) highlightAll(container, tok);
for (const tok of tokens) {
highlightAll(container, tok);
}
} }
// --- helpers --- // ---- helpers ----
function tokenize(s) { function tokenize(s) {
const out = []; const out = [];
let i = 0, buf = "", inQ = false; let i = 0, buf = "", inQ = false;
@@ -581,4 +574,5 @@ document.addEventListener("DOMContentLoaded", async () => {
} }
}); });
</script> </script>
{% endblock %} {% endblock %}