function initSearch() { const form = document.getElementById('searchForm'); if (!form || form.dataset.bound) return; form.dataset.bound = '1'; // Function to render search results from a response object function renderResults(data) { const resultsDiv = document.getElementById('results'); const results = Array.isArray(data.results) ? data.results : []; const total = Number.isFinite(data.total) ? data.total : results.length; const shown = results.length; const remaining = Math.max(0, total - shown); resultsDiv.innerHTML = `
${fileAction}
Anzahl Downloads: ${file.hitcount}
${ (file.performance_date !== undefined && file.performance_date !== null && String(file.performance_date).trim() !== '') ? `Datum: ${file.performance_date}
` : ``} ${ file.transcript_hits !== undefined ? `${fulltextLabel}: ${file.transcript_hits} ${fulltextAction}
` : ``}Keine Treffer gefunden.
`; } } // Restore previous search response if available from localStorage const previousResponse = localStorage.getItem("searchResponse"); if (previousResponse) { try { const data = JSON.parse(previousResponse); renderResults(data); } catch (e) { console.error('Error parsing searchResponse from localStorage:', e); } } // Restore previous search word (Suchwort) if available const previousQuery = localStorage.getItem("searchQuery"); if (previousQuery) { document.getElementById('query').value = previousQuery; } // Restore previous selected category if available, otherwise default remains "Alles" const previousCategory = localStorage.getItem("searchCategory"); if (previousCategory !== null) { const radio = document.querySelector('input[name="category"][value="' + previousCategory + '"]'); if (radio) { radio.checked = true; } } // Restore previously selected filetypes (multi-select). Default to audio if none stored. const previousFiletypes = localStorage.getItem("searchFiletypes"); if (previousFiletypes) { try { const list = JSON.parse(previousFiletypes); document.querySelectorAll('input[name=\"filetype\"]').forEach(cb => { cb.checked = list.includes(cb.value); }); } catch (e) { console.error('Error parsing stored filetypes', e); document.getElementById('filetype-audio').checked = true; } } else { document.getElementById('filetype-audio').checked = true; } // Restore the checkbox state for "Im Transkript suchen" const previousIncludeTranscript = localStorage.getItem("searchIncludeTranscript"); if (previousIncludeTranscript !== null) { document.getElementById('includeTranscript').checked = (previousIncludeTranscript === 'true'); } // Form submission event form.addEventListener('submit', function(e) { e.preventDefault(); const query = document.getElementById('query').value.trim(); const includeTranscript = document.getElementById('includeTranscript').checked; const spinnerTimer = setTimeout(() => { if (typeof showSpinner === 'function') showSpinner(); }, 200); // Get the selected category radio button, if any const categoryRadio = document.querySelector('input[name="category"]:checked'); const category = categoryRadio ? categoryRadio.value : ''; // Get selected filetypes (allow multiple). Default to audio if none selected. const filetypeCheckboxes = document.querySelectorAll('input[name=\"filetype\"]'); let filetypes = Array.from(filetypeCheckboxes).filter(cb => cb.checked).map(cb => cb.value); if (filetypes.length === 0) { // enforce audio as default when user unchecked all document.getElementById('filetype-audio').checked = true; filetypes = ['audio']; } // Prevent accidental re-selection of already selected radio buttons const radios = document.querySelectorAll('input[name="category"]'); radios.forEach(radio => { radio.addEventListener('mousedown', function(e) { this.wasChecked = this.checked; }); radio.addEventListener('click', function(e) { if (this.wasChecked) { this.checked = false; this.wasChecked = false; e.preventDefault(); } }); }); // Prepare form data for the fetch request // Send the query and the category as separate parameters. const formData = new FormData(); formData.append('query', query); formData.append('category', category); formData.append('folder', document.getElementById('folder').value); formData.append('datefrom', document.getElementById('datefrom').value); formData.append('dateto', document.getElementById('dateto').value); formData.append('includeTranscript', includeTranscript); filetypes.forEach(ft => formData.append('filetype', ft)); const settleSpinner = () => { clearTimeout(spinnerTimer); if (typeof hideSpinner === 'function') hideSpinner(); }; const fetchPromise = fetch('/searchcommand', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { // Render the results renderResults(data); // Store the raw response in localStorage try { localStorage.setItem("searchResponse", JSON.stringify(data)); } catch (e) { console.error('Error saving searchResponse to localStorage:', e); } // Save the search word, selected category, and checkbox state in localStorage localStorage.setItem("searchQuery", query); localStorage.setItem("searchCategory", category); localStorage.setItem("searchFiletypes", JSON.stringify(filetypes)); localStorage.setItem("searchIncludeTranscript", includeTranscript); }) .catch(error => { console.error('Error:', error); }); // Always clear/hide spinner once the request settles if (typeof fetchPromise.finally === 'function') { fetchPromise.finally(settleSpinner); } else { fetchPromise.then(settleSpinner, settleSpinner); } }); // Clear button event handler document.getElementById('clearBtn').addEventListener('click', function() { // Remove stored items localStorage.removeItem("searchResponse"); localStorage.removeItem("searchQuery"); localStorage.removeItem("searchCategory"); localStorage.removeItem("searchFiletypes"); localStorage.removeItem("folder"); localStorage.removeItem("datefrom"); localStorage.removeItem("dateto"); localStorage.removeItem("searchIncludeTranscript"); // Reset form fields to defaults document.getElementById('query').value = ''; document.querySelector('input[name="category"][value=""]').checked = true; const otherRadios = document.querySelectorAll('input[name="category"]:not([value=""])'); otherRadios.forEach(radio => radio.checked = false); document.getElementById('filetype-audio').checked = true; const otherFiletypeBoxes = document.querySelectorAll('input[name=\"filetype\"]:not([value=\"audio\"])'); otherFiletypeBoxes.forEach(cb => cb.checked = false); document.getElementById('folder').value = ''; // Reset to "Alle" document.getElementById('datefrom').value = ''; // Reset date from document.getElementById('dateto').value = ''; // Reset date to document.getElementById('includeTranscript').checked = false; // Clear the results div document.getElementById('results').innerHTML = ''; }); // Back button event handler - redirect to the root path document.getElementById('backBtn').addEventListener('click', function() { // window.location.href = '/'; viewMain(); }); } function attachSearchFolderButtons() { document.querySelectorAll('.folder-open-btn').forEach(btn => { btn.addEventListener('click', (e) => { e.preventDefault(); const folder = btn.dataset.folder; const file = btn.dataset.file; openFolderAndHighlight(folder, file); }); }); } function attachSearchSngButtons() { document.querySelectorAll('.open-sng-btn').forEach(btn => { btn.addEventListener('click', (e) => { e.preventDefault(); const path = btn.dataset.path; if (typeof window.openSngModal === 'function') { window.openSngModal(path); } }); }); } function attachSearchFulltextButtons() { document.querySelectorAll('.open-sng-link').forEach(link => { link.addEventListener('click', (e) => { e.preventDefault(); const path = link.dataset.path; if (typeof window.openSngModal === 'function') { window.openSngModal(path); } }); }); } function openFolderAndHighlight(folderPath, filePath) { const targetFolder = folderPath || ''; // Switch back to main view before loading folder viewMain(); loadDirectory(targetFolder).then(() => { const target = document.querySelector(`.play-file[data-url=\"${filePath}\"]`); if (target) { target.classList.add('search-highlight'); target.scrollIntoView({ behavior: 'smooth', block: 'center' }); } }); } function syncThemeColor() { // read the CSS variable from :root (or any selector) const cssVar = getComputedStyle(document.documentElement) .getPropertyValue('--dark-background').trim(); if (cssVar) { document .querySelector('meta[name="theme-color"]') .setAttribute('content', cssVar); } } // sync once on load // syncThemeColor handled by app init. window.initSearch = initSearch;