buscador funcional

This commit is contained in:
f 2021-03-26 13:11:29 -03:00
parent d65faed9e6
commit 43a38b5d6c
2 changed files with 45 additions and 18 deletions

View file

@ -1,6 +1,6 @@
{%- assign param = include.param | default: 'search' -%} {%- assign param = include.param | default: 'search' -%}
<form method="get" action="" class="form-inline" data-controller="search"> <form method="get" action="" class="form-inline" data-controller="search" data-action="search#search">
<div class="form-group"> <div class="form-group">
<label for="{{ param }}_q" class="sr-only">{{ site.i18n.search.label }}</label> <label for="{{ param }}_q" class="sr-only">{{ site.i18n.search.label }}</label>

View file

@ -8,25 +8,42 @@ require("lunr-languages/lunr.es")(lunr)
export default class extends Controller { export default class extends Controller {
static targets = [ 'q' ] static targets = [ 'q' ]
connect () { get q () {
this.element.addEventListener('submit', async event => { if (!this.hasQTarget) return
event.stopPropagation() if (!this.qTarget.value.trim().length === 0) return
event.preventDefault()
this.search() return this.qTarget.value.trim()
})
const q = window.location.search.match(/^\?q=(?<q>.*)&?/)
if (q) this.qTarget.value = decodeURI(q.groups.q)
// There can only be one
if (!window.search_fetching) this.fetch()
} }
async search () { connect () {
const q = this.qTarget.value const q = window.location.search.match(/^\?q=(?<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 main = document.querySelector('main')
const results = window.index.search(q).map(r => window.data.find(a => a.id == r.ref)) 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 document.title = title
main.innerHTML = html main.innerHTML = html
this.formDisable = false
} }
async fetch () { async fetch () {
window.search_fetching = true // Solo permite descargar uno a la vez
if (this.fetching) return
this.fetching = true
let response let response
// Si no existe el índice, lo descarga y procesa Lunr
if (!window.data) { if (!window.data) {
response = await fetch('data.json') response = await fetch('data.json')
window.data = await response.json() window.data = await response.json()
@ -57,7 +79,12 @@ export default class extends Controller {
window.index = lunr.Index.load(idx) 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)
} }
/* /*