Hopp til hovedinnhold
Meny

lmfaole.party / designsystem / funksjoner / Koble datalist-søk

  • Forside
  • Turer
  • Økonomi
  • Slides
  • kobleDatalistSok – Koble datalist-søk / Wire datalist search

    Om funksjonen

    Formål

    Repoets regel om skjemafelt sier at autocomplete/forslag mot en kjent liste skal løses med et vanlig <input list="..."> koblet til en <datalist>, ikke en egen JS-drevet dropdown/søkekomponent. Når forslagene må hentes asynkront (f.eks. et geokodings- eller API-søk der datasettet ikke er avgrenset eller ferdig lastet), trengs likevel litt JS for å fylle datalisten etter hvert tastetrykk - denne funksjonen er den minimale, gjenbrukbare limingen for akkurat det: debounce, minste søkelengde, vern mot at et sent svar på et gammelt søk overskriver et nyere, og oppslag av det fulle valgte objektet (ikke bare den synlige teksten).

    Egner seg for

    • Fritekstsøk mot et åpent eller for stort datasett til å vises som faste <option>-er på forhånd (f.eks. geokoding mot Nominatim), der brukeren skal kunne velge et treff eller skrive fritekst.
    • Skjemaer som vil beholde et helt vanlig, native <input>/<datalist>-par i markupet, uten en egen combobox-komponent.

    Egner seg ikke for

    • Et avgrenset, kjent sett med valg som passer i en vanlig nedtrekksliste - bruk <lm-select-field> (eller en ren <datalist> helt uten JS, se guiden om skjemafelt) i stedet.
    • Multi-select eller tag-inntasting - funksjonen modellerer bare ett valgt forslag om gangen.

    Signatur(er)

    kobleDatalistSok(input: HTMLInputElement, datalist: HTMLDataListElement, valg: {search: (query: string) => Promise<Array<{value: string, label: string, [key: string]: unknown}>>, minLength?: number, debounce?: number, onSokStart?: () => void, onSokFerdig?: (treff: Array<object>) => void, onValg?: (item: object) => void}) => {hentValgt: () => object | null, nullstill: () => void}

    Parameter Type Beskrivelse
    inputHTMLInputElementTekstfeltet, koblet til datalisten via sitt list-attributt.
    datalistHTMLDataListElementDatalisten forslagene rendres inn i.
    valg{search: (query: string) => Promise<Array<{value: string, label: string, [key: string]: unknown}>>, minLength?: number, debounce?: number, onSokStart?: () => void, onSokFerdig?: (treff: Array<object>) => void, onValg?: (item: object) => void}search henter forslag for et søkeord - label vises/velges i datalisten, alle andre felt følger med til onValg. minLength (standard 2) og debounce (standard 300 ms) styrer når søk faktisk kjøres. onSokStart/onSokFerdig brukes til å vise egen søkestatus ("Søker…"/"Ingen treff"). onValg kalles med hele forslagsobjektet når brukerens tekst nøyaktig matcher et forslag.

    Returnerer: hentValgt() gir det valgte forslagsobjektet (eller null hvis feltets tekst ikke matcher et kjent forslag) - kalles typisk i et submit-steg. nullstill() tømmer feltet, datalisten og de huskede forslagene.

    import {kobleDatalistSok} from "/designsystem/funksjoner/dom/koble-datalist-sok/koble-datalist-sok.js";
    
    const input = document.getElementById("stopp-sok");
    const datalist = document.getElementById("stopp-forslag");
    const statusEl = document.getElementById("stopp-sok-status");
    
    const {hentValgt, nullstill} = kobleDatalistSok(input, datalist, {
        search: async (query) => {
            const treff = await searchPlace(query);
            return treff.map((t) => ({value: t.displayName, label: t.displayName, ...t}));
        },
        onSokStart: () => { statusEl.hidden = false; statusEl.textContent = "Søker…"; },
        onSokFerdig: (treff) => { statusEl.hidden = treff.length > 0; statusEl.textContent = "Ingen treff."; },
    });
    
    form.addEventListener("submit", (e) => {
        e.preventDefault();
        const sted = hentValgt();
        // ...
    });

    Tilgjengelighet

    Ingen egen tilgjengelighetslogikk - hele forslagspresentasjonen er nettleserens native <datalist>-oppførsel. Kallende kode må fortsatt gi input en synlig <label> som ellers i repoet.

    Referanser

    Se også:

    Brukes av:

    • turer/js/features/stops/stops.js - stedsøk mot Nominatim i "Legg til stopp".
    • turer/js/features/hotels/hotels.js - adressesøk mot Nominatim i "Legg til hotell".

    Avhengigheter: Ingen