diff --git a/_includes/search.html b/_includes/search.html index 9a033ce..79ae250 100644 --- a/_includes/search.html +++ b/_includes/search.html @@ -1,6 +1,6 @@ {%- assign param = include.param | default: 'search' -%} -
+
diff --git a/_packs/controllers/search_controller.js b/_packs/controllers/search_controller.js index a33b6ab..96a9ef0 100644 --- a/_packs/controllers/search_controller.js +++ b/_packs/controllers/search_controller.js @@ -8,25 +8,42 @@ require("lunr-languages/lunr.es")(lunr) export default class extends Controller { static targets = [ 'q' ] - connect () { - this.element.addEventListener('submit', async event => { - event.stopPropagation() - event.preventDefault() + get q () { + if (!this.hasQTarget) return + if (!this.qTarget.value.trim().length === 0) return - this.search() - }) - - const q = window.location.search.match(/^\?q=(?.*)&?/) - if (q) this.qTarget.value = decodeURI(q.groups.q) - - // There can only be one - if (!window.search_fetching) this.fetch() + return this.qTarget.value.trim() } - async search () { - const q = this.qTarget.value + connect () { + const q = window.location.search.match(/^\?q=(?.*)&?/) - if (!q || q === '') return + if (q) { + this.qTarget.value = decodeURI(q.groups.q) + this.search() + } + } + + async search (event) { + // Detiene el envío del formulario + if (event) { + event.preventDefault() + event.stopPropagation() + } + + this.formDisable = true + + // Obtiene el término de búsqueda + const q = this.q + // Si no hay término de búsqueda, no hay búsqueda + if (q) { + // Trae el índice de búsqueda + await this.fetch() + + // Hasta que no haya índice no buscamos nada, esto evita que se + // aprete enter dos veces y se fallen cosas. + if (!window.index) return + } const main = document.querySelector('main') const results = window.index.search(q).map(r => window.data.find(a => a.id == r.ref)) @@ -40,12 +57,17 @@ export default class extends Controller { document.title = title main.innerHTML = html + this.formDisable = false } async fetch () { - window.search_fetching = true + // Solo permite descargar uno a la vez + if (this.fetching) return + + this.fetching = true let response + // Si no existe el índice, lo descarga y procesa Lunr if (!window.data) { response = await fetch('data.json') window.data = await response.json() @@ -57,7 +79,12 @@ export default class extends Controller { window.index = lunr.Index.load(idx) } - if (this.qTarget.value !== '') this.search() + // Permitir volver a ejecutar + this.fetching = false + } + + set formDisable (disable) { + this.element.elements.forEach(x => x.disabled = disable) } /*