(function () { const DEBOUNCE_MS = 300; function debounce(fn, delay) { let timer; return function (...args) { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, args), delay); }; } function buildUrl(form) { const params = new URLSearchParams(); new FormData(form).forEach((value, key) => { if (value) { params.append(key, value); } }); const action = form.getAttribute('action') || window.location.pathname; const query = params.toString(); return query ? action + '?' + query : action; } function runSearch(form) { const target = document.querySelector(form.dataset.liveTarget); if (!target) { return; } const url = buildUrl(form); fetch(url, { headers: { 'X-Requested-With': 'XMLHttpRequest' }, }) .then((response) => { if (!response.ok) { throw new Error('search failed'); } return response.text(); }) .then((html) => { target.innerHTML = html; history.replaceState(null, '', url); }) .catch(() => {}); } document.addEventListener('DOMContentLoaded', function () { document.querySelectorAll('form[data-live-search]').forEach(function (form) { const search = debounce(function () { runSearch(form); }, DEBOUNCE_MS); form.querySelectorAll('input, select').forEach(function (field) { field.addEventListener('input', search); field.addEventListener('change', search); }); form.addEventListener('submit', function (event) { event.preventDefault(); runSearch(form); }); }); }); })();