# Adresse-autocomplete og validering i Contact Form 7

> Giv Contact Form 7-felterne id'er, kobl adresse-widget'en på, og afvis adresser, der ikke kan findes, når formularen sendes.
>
> https://danadresse.dk/guides/contact-form-7 · verified 2026-11-02
Contact Form 7 laver almindelige input-felter ud fra form-tags, og du kan give hvert felt et id direkte i tagget. Det er alt, widget'en behøver. Fordi CF7 sender formularen til din egen server, kan du også tjekke adressen dér, før mailen bliver sendt.

## Den hurtige vej: pluginnet Lynbro Danadresse

Det gratis plugin [Lynbro Danadresse](https://wordpress.org/plugins/lynbro-danadresse/) fra wordpress.org giver adresse-autocomplete i WooCommerce, Contact Form 7, Gravity Forms, WPForms, Fluent Forms, Elementor, GiveWP, Forminator og flere. Det kalder API'et via din egen server, så nøglen aldrig når browseren.

1. Gå til **Plugins → Tilføj nyt** i WordPress, søg efter "Lynbro Danadresse", klik **Installér** og **Aktivér**.
2. Opret en nøgle under [Nøgler](/dashboard/keys). Brug en almindelig *live*-nøgle **uden** tilladte domæner: pluginnet kalder API'et fra din egen server, og dér afvises en domænelåst nøgle, fordi et serverkald ikke har en `Origin`.
3. Sæt nøglen ind under **Lynbro → Danadresse → Settings**. Fanen **Status** laver et testopslag med nøglen.
4. Contact Form 7 har ingen egen adressefelttype, så pluginnet finder adressefeltet med auto-detect, eller du angiver feltets CSS-selektor under **Integrations** (fx `#dk-adresse` fra trin 2 nedenfor).

Pluginnet udfylder kun postnr. og by i separate felter for formular-plugins med eget adressefelt (WooCommerce, Gravity Forms, WPForms m.fl.), og det tjekker kun adresser i WooCommerce-checkout'en. Skal din CF7-formular udfylde postnr. og by eller afvise adresser, der ikke findes, så brug din egen kode som nedenfor.

## 1. Opret nøgler

Du skal bruge to nøgler fra [Nøgler](/dashboard/keys):

- en *live*-browsernøgle låst til sitets domæner under **Tilladte domæner** (se [Browsernøgler og tilladte domæner](/guides/browser-noegler-domaener))
- en server-nøgle uden domænelås til valideringen i trin 4. Læg den i miljøvariablen `DANADRESSE_API_KEY` på serveren

## 2. Felterne i formularen

Ret formularen i **Kontakt → Kontaktformularer**:

```text id=cf7-tags run=no
<label>Adresse [text* adresse id:dk-adresse]</label>
<label>Postnummer [text* postnr id:dk-postnr]</label>
<label>By [text* by id:dk-by]</label>
```

## 3. Widget'en som mu-plugin

Gem filen som `wp-content/mu-plugins/danadresse.php`:

```php id=mu-plugin run=syntax
<?php
/**
 * Plugin Name: Danadresse autocomplete (Contact Form 7)
 */
if (!defined('ABSPATH')) {
    exit;
}

add_action('wp_enqueue_scripts', function () {
    wp_enqueue_script(
        'danadresse-autocomplete',
        'https://danadresse.dk/static/js/danadresse-autocomplete-1.0.0.js',
        [],
        null,
        true
    );
    wp_add_inline_script('danadresse-autocomplete', <<<'JS'
const API_KEY = "DIN_BROWSER_NØGLE";

function streetLine(a) {
  let line = a.vejnavn + " " + a.husnr;
  if (a.etage) line += ", " + a.etage + ".";
  if (a["dør"]) line += " " + a["dør"];
  return line;
}

const input = document.getElementById("dk-adresse");
if (input) {
  DanadresseAutocomplete.attach(input, {
    apiKey: API_KEY,
    onSelect(a) {
      input.value = streetLine(a);
      document.getElementById("dk-postnr").value = a.postnr || "";
      document.getElementById("dk-by").value = a.postnrnavn || "";
    },
  });
}
JS
    );
});
```

CF7 læser felterne direkte, når formularen sendes, så her er det nok at sætte `value`.

## 4. Afvis adresser, der ikke findes

Tilføj dette nederst i samme fil (uden en ny `<?php`-linje). Det tjekker vej, husnr. og postnr. mod `/datavask/adgangsadresser` og viser en fejl ved feltet, hvis resultatet er kategori C.

```php id=cf7-validate run=syntax
<?php
add_filter('wpcf7_validate_text*', function ($result, $tag) {
    if ($tag->name !== 'adresse') {
        return $result;
    }
    $adresse = sanitize_text_field(wp_unslash($_POST['adresse'] ?? ''));
    $postnr = sanitize_text_field(wp_unslash($_POST['postnr'] ?? ''));
    $street = trim((string) strtok($adresse, ','));

    $res = wp_remote_get(
        'https://api.danadresse.dk/datavask/adgangsadresser?'
            . http_build_query(['betegnelse' => $street . ', ' . $postnr]),
        ['headers' => ['X-Api-Key' => getenv('DANADRESSE_API_KEY')], 'timeout' => 5]
    );
    if (is_wp_error($res) || wp_remote_retrieve_response_code($res) !== 200) {
        return $result; // API'et svarer ikke: lad formularen gå igennem
    }
    $vask = json_decode(wp_remote_retrieve_body($res), true);
    if (($vask['kategori'] ?? '') === 'C') {
        $result->invalidate($tag, 'Vi kunne ikke finde adressen. Vælg den fra listen.');
    }
    return $result;
}, 20, 2);
```

Etage og dør bliver ikke tjekket, kun bygningen. Hvad A, B og C betyder, står i [Datavask i checkout](/guides/datavask-i-checkout).

## 5. Test

Send formularen to gange: én gang med en adresse fra listen (skal gå igennem) og én gang med en opdigtet adresse som "Findesikkevej 999, 9999" (skal give fejlen). `403 origin_not_allowed` i konsollen betyder, at domænet mangler på browsernøglen.

## Næste skridt

- [CF7-opskriften](/integrationer/contact-form-7). Den bruger den ældre `danadresse-widget.js`, som går fra vej til husnummer til enhed og kan udfylde separate felter med sin `fields`-indstilling.
- [Gravity Forms](/guides/gravity-forms) og [WPForms](/guides/wpforms)
- Pluginnet på wordpress.org: [Lynbro Danadresse](https://wordpress.org/plugins/lynbro-danadresse/)
