Autocomplete-widget i ren JavaScript

Sæt et adressefelt med forslag ind på en hvilken som helst side med ét script-tag, og fyld vej, postnummer og by i separate felter.

6 min Niveau: Begynder ✓ Kode testet

Vi har to færdige scripts til et adressefelt. De kræver ingen build-værktøjer, ingen frameworks og ingen andre biblioteker. Denne guide viser, hvilket du skal vælge, hvordan du sætter det op, og hvordan du får den valgte adresse ud i separate formularfelter.

Begge scripts kalder /autocomplete direkte fra brugerens browser. Nøglen ligger derfor i sidens kildekode og skal være en domænelåst browsernøgle. Læs Browsernøgler og tilladte domæner, før du går i produktion.

På en webshop-checkout, hvor du ikke kan skrive JavaScript, bruger du i stedet scriptet https://api.danadresse.dk/js/danadresse-auto.min.js med data-key. Det finder selv adressefelterne og udfylder vej, postnummer og by. Se platformssiderne under /integrationer.

1. Vælg script

danadresse-autocomplete-1.0.0.jsdanadresse-widget.js
Adressehttps://danadresse.dk/static/js/danadresse-autocomplete-1.0.0.jshttps://danadresse.dk/static/js/danadresse-widget.js
VersioneretJa, filen ændres ikkeNej, opdateres på stedet
TilgængelighedARIA 1.2 combobox, live region, Home/EndARIA 1.2 combobox, live region
Drill-down (vej → husnummer → enhed)JaJa
onSelect fårEt fladt objekt med vej, husnummer, postnummer osv.Det rå forslag fra /autocomplete
Separate felterDu skriver dem selv i onSelect (trin 5)Indbygget: fields: { street, postnr, city }
FejlvisningViser en besked og lader feltet virke som tekstfeltEn besked pr. årsag (nøgle, domæne, for mange søgninger, netværk)
Sprogda, en, ukDansk tekst; kan overskrives med messages

Brug danadresse-autocomplete-1.0.0.js til nye sider. danadresse-widget.js findes stadig og holdes opdateret, fordi eksisterende sider bruger den. Brug ét af dem pr. side. danadresse-widget.js registrerer altid window.DanadresseWidget og tager kun window.DanadresseAutocomplete, når 1.0.0 ikke er på siden, så de to overskriver ikke længere hinanden.

2. Indsæt feltet og scriptet

Et felt med label, scriptet og ét kald til attach:

HTML#basic-embed
<label for="adr">Adresse</label>
<input id="adr" name="adresse" autocomplete="off">

<script src="https://danadresse.dk/static/js/danadresse-autocomplete-1.0.0.js"></script>
<script>
  const API_KEY = "dawa_live_din_browsernøgle"; // domænelåst nøgle

  DanadresseAutocomplete.attach("#adr", {
    apiKey: API_KEY,
    lang: "da",
    onSelect: function (a) {
      console.log(a.tekst, a.id);
    },
  });
</script>

Du kan også nøjes med attributter. Scriptet finder selv alle input-felter med data-danadresse-key, når siden er indlæst:

HTML#declarative-embed
<input id="adr" data-danadresse-key="dawa_live_din_browsernøgle" data-danadresse-lang="da">
<script src="https://danadresse.dk/static/js/danadresse-autocomplete-1.0.0.js"></script>

De attributter, scriptet læser, er data-danadresse-key, data-danadresse-lang, data-danadresse-type og data-danadresse-base. Vil du have en onSelect, skal du bruge attach eller lytte efter eventet danadresse:select (se trin 4).

3. Indstillinger

OptionStandardBetydning
apiKeyingenDin browsernøgle. Uden nøgle svarer API'et 401, og feltet viser fejlbeskeden
lang<html lang>, ellers dada, en eller uk. Styrer pladsholder, tom-besked, fejlbesked og skærmlæsertekst
typeadresseadresse (med etage/dør), adgangsadresse (stopper ved husnummer) eller vejnavn
limit8Antal forslag (per_side). API'et tillader højst 100
minLength2Antal tegn, før der søges
debounce150Ventetid i millisekunder efter sidste tastetryk
baseUrlhttps://api.danadresse.dkSkift kun, hvis du kører kaldene gennem din egen proxy
credittruefalse fjerner linjen "Adresser fra danadresse.dk"
fuzzytruefalse sender fuzzy=false og slår tolerance for stavefejl fra. Standard: stavefejl rettes
onSelect(a)ingenKaldes, når brugeren har valgt en endelig adresse
onError(err)ingenKaldes ved netværksfejl eller HTTP-fejl. err.status er statuskoden

attach returnerer et objekt med close(), search(q) og destroy(). Kalder du attach to gange på samme felt, får du det samme objekt tilbage, så der ikke kommer dobbelte lister.

4. Læs den valgte adresse

Med type: "adresse" sker valget i op til tre trin. Vælger brugeren et vejnavn, sætter scriptet vejnavnet ind, placerer markøren efter det og søger igen. Det samme sker for en opgang med flere lejligheder. onSelect kaldes først, når der er valgt en adresse af den type, du bad om.

onSelect får et fladt objekt:

JSON#onselect-payload
{
  "type": "adresse",
  "tekst": "Rådhuspladsen 1, 3300 Frederiksværk",
  "id": "762a9a1f-a5fb-4e47-b1b2-9fa94026bc80",
  "adgangsadresseid": "0a3f507f-0959-32b8-e044-0003ba298018",
  "vejnavn": "Rådhuspladsen",
  "adresseringsvejnavn": "Rådhuspladsen",
  "vejkode": "1214",
  "kommunekode": "0260",
  "husnr": "1",
  "husnummer": "1",
  "husbogstav": null,
  "etage": null,
  "dør": null,
  "supplerendebynavn": null,
  "postnr": "3300",
  "postnrnavn": "Frederiksværk",
  "lat": 55.97657023,
  "lon": 12.01612365,
  "raw": { "type": "adresse", "tekst": "…", "data": { "…": "…" } }
}

husnr er husnummeret som én streng (12A). husnummer og husbogstav er det samme delt op (12 og A), hvilket mange ERP- og fragtsystemer kræver. raw er det oprindelige forslag fra /autocomplete, hvis du skal bruge et felt, der ikke er i det flade objekt.

Feltet dør har et ø i navnet. Læs det med a["dør"] i JavaScript.

5. Udfyld separate felter

Mange formularer har vej, postnummer og by i hver sit felt. Lad brugeren søge i ét felt og skriv resultatet ud i de andre. Gem altid id: så kan du slå adressen op igen senere uden at parse tekst.

HTML#separate-fields
<form id="levering">
  <label for="soeg">Find adresse</label>
  <input id="soeg">

  <label for="vej">Vej og nummer</label>
  <input id="vej" name="vej">
  <label for="etage">Etage og dør</label>
  <input id="etage" name="etage">
  <label for="postnr">Postnummer</label>
  <input id="postnr" name="postnr" inputmode="numeric">
  <label for="by">By</label>
  <input id="by" name="by">

  <input type="hidden" id="adresse_id" name="adresse_id">
</form>

<script src="https://danadresse.dk/static/js/danadresse-autocomplete-1.0.0.js"></script>
<script>
  const API_KEY = "dawa_live_din_browsernøgle";
  const f = document.getElementById("levering");

  DanadresseAutocomplete.attach("#soeg", {
    apiKey: API_KEY,
    onSelect: function (a) {
      f.vej.value = a.vejnavn + " " + a.husnr;
      f.etage.value = [a.etage ? a.etage + "." : "", a["dør"] || ""].join(" ").trim();
      f.postnr.value = a.postnr;
      f.by.value = a.postnrnavn;
      f.adresse_id.value = a.id;
    },
  });

  // Brugeren retter i felterne bagefter: id'et passer ikke længere.
  ["vej", "etage", "postnr", "by"].forEach(function (navn) {
    f[navn].addEventListener("input", function () { f.adresse_id.value = ""; });
  });
</script>

Hvis du ikke vil skrive en onSelect, kan du lytte efter eventet. Det bobler op gennem DOM'en med samme objekt i detail:

JavaScript#select-event
document.addEventListener("danadresse:select", (e) => {
  const a = e.detail;
  console.log("Valgt:", a.tekst, a.postnr, a.postnrnavn);
});

6. Når API'et ikke svarer

Ved netværksfejl, 401, 403, 429 eller 5xx viser scriptet beskeden "Adresseopslag er utilgængeligt — skriv adressen manuelt", og feltet virker videre som et almindeligt tekstfelt. Din formular skal derfor kunne tage imod en adresse uden id. Vask den på serveren med /datavask/adresser, hvis du skal bruge koder.

Brug onError til at logge årsagen. err.status er undefined ved netværksfejl:

JavaScript#on-error
const API_KEY = "dawa_live_din_browsernøgle";

DanadresseAutocomplete.attach("#adr", {
  apiKey: API_KEY,
  onError(err) {
    if (err.status === 403) console.warn("Tjek nøglens tilladte domæner");
    else if (err.status === 429) console.warn("For mange kald lige nu");
    else console.warn("Adresseopslag fejlede", err);
  },
});

Fejlsvar har CORS-headere, så browseren ser den rigtige statuskode og ikke bare en netværksfejl. En browsernøgle har en grænse pr. besøgende på 120 søgninger i minuttet. Over den svarer API'et 429 rate_limit_per_visitor med Retry-After, og feltet viser fejlbeskeden, indtil brugeren skriver igen.

danadresse-widget.js viser en dansk besked pr. årsag: manglende eller ugyldig nøgle (401), domænet er ikke tilladt (403), for mange søgninger (429) og netværksfejl. Dens onError får { kind } med unauthorized, forbidden, rate, network eller error.

7. Se kaldet, som scriptet laver

Scriptet sender kun den indtastede tekst, markørens position, type, antal og fuzzy. Nøglen ligger i headeren X-Api-Key, og der sendes ingen cookies (credentials: "omit"). Du kan gentage kaldet fra terminalen:

Shell#widget-request
curl -s "https://api.danadresse.dk/autocomplete?q=Strandvejen%20100%2C%202900&type=adresse&per_side=8&fuzzy=" \
  -H "X-Api-Key: $DANADRESSE_API_KEY"

Svarer kaldet her, men ikke i browseren, er det næsten altid nøglens domæneliste. Se Browsernøgler og tilladte domæner.

8. Udseende, SRI og selv-hosting

Listen følger prefers-color-scheme. Farverne er CSS-variabler, som du kan overskrive:

CSS#theme-vars
.dda2 {
  --dda2-bg: #ffffff;
  --dda2-fg: #1a1a1a;
  --dda2-active: #fff4d6;
  --dda2-link: #8a4b00;
}

Filen danadresse-autocomplete-1.0.0.js ændres aldrig, så du kan bruge Subresource Integrity. Beregn hashen for præcis den fil, du indlejrer, og sæt den i integrity sammen med crossorigin="anonymous":

Shell#sri-hash
curl -s https://danadresse.dk/static/js/danadresse-autocomplete-1.0.0.js \
  | openssl dgst -sha384 -binary | openssl base64 -A

Du må også kopiere filen ind i din egen statiske mappe. Den er MIT-licenseret. Behold versionsnummeret i filnavnet, så du kan se, hvilken version du kører. Brug ikke SRI på danadresse-widget.js eller på aliaset danadresse-autocomplete.js: de er ikke versionerede, og hashen holder op med at passe, når filen opdateres.

Næste skridt

Relaterede guides

Markdown-kilde Fejl i guiden? Skriv til os API-reference (Swagger)

Prøv det med en gratis nøgle

2 000 kald/måned på gratisplanen. Intet kreditkort.

Opret konto →