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 |
|---|---|---|
input | HTMLInputElement | Tekstfeltet, koblet til datalisten via sitt list-attributt. |
datalist | HTMLDataListElement | Datalisten 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å:
../../../komponenter/skjema/select-field/index.html - Riktig valg når datasettet er avgrenset og kan vises som faste alternativer, i stedet for et asynkront søk.../../../guider/skjemafelt/index.html - Forklarer valget mellom en ren<datalist>, denne funksjonen og en<select>for ulike typer valg/forslag.
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