Live-Demo

Probier das Widget direkt aus. Wähle oben zwischen der schlanken Spielwiese und der ausführlichen Variante mit sichtbarer API-Kommunikation.

Tipp einen Ortsnamen ein, klick einen Vorschlag an. Unten siehst du die Werte, die das Formular beim Absenden an einen Server schicken würde.

Pfeiltasten ↑/↓ zum Navigieren · Enter oder Klick zum Auswählen · Esc zum Schließen.

Was beim Form-Submit als $_POST ankäme

Noch nichts ausgewählt — Werte erscheinen hier nach der Auswahl.

Dieselbe Eingabe wie nebenan — aber zusätzlich machen wir transparent, was im Hintergrund passiert: welche URL wird abgefragt, was kommt vom Server zurück, und wie verwandelt sich das in $_POST-Werte für deinen PHP-Code.

Tippe etwas und beobachte die drei Panels unten.

1. Anfrage

URL erscheint hier, sobald du tippst.

2. Antwort (rohe JSON)

JSON-Antwort erscheint hier.

3. $_POST nach Auswahl

Werte erscheinen nach Auswahl.
Panel 1 zeigt jeden HTTP-Aufruf, den das Widget macht. Panel 2 die Server-Antwort. Panel 3 die Hidden-Felder, die das Widget nach deiner Auswahl füllt — diese würden bei einem Form-Submit als $_POST-Variablen am Server ankommen.
Was du gerade beobachtest: Bei jedem Tastendruck (mit 200 ms Pause als Bremse) ruft das Widget https://geoapi.world/api/search.php?q=… auf. Die Antwort ist eine JSON-Liste mit Treffern. Sobald du einen wählst, schreibt das Widget mehrere unsichtbare Hidden-Felder in dein Formular — und genau diese Werte liegen in $_POST für dein Server-PHP an.

Der komplette Quelltext der schlanken Demo

Genau dieser Code erzeugt den Widget-Tab oben. Du kannst ihn 1:1 als Vorlage nehmen.

<!DOCTYPE html>
<html lang="de">
<head><meta charset="utf-8"><title>Mein Eingabeformular</title></head>
<body>

  <form method="post" action="speichern.php">
    <label>Geburtsort:
      <input type="text" name="ort" data-geoapi-place
             placeholder="Ort eingeben">
    </label>
    <button type="submit">Absenden</button>
  </form>

  <script src="https://geoapi.world/dist/geoapi-widget.js"></script>

</body>
</html>

So zerlegt sich der Code

1Das Eingabefeld

<input type="text" name="ort" data-geoapi-place>

Ein normales HTML-Input. Das Attribut data-geoapi-place ist die Markierung, an der das Widget erkennt: „hier soll Autosuggest hin". name="ort" bestimmt, wie das Feld später im PHP heißt: $_POST["ort"].

2Die Skript-Zeile

<script src="https://geoapi.world/dist/geoapi-widget.js"></script>

Diese eine Zeile lädt das Widget aus unserem Server. Der Browser kümmert sich automatisch darum — du musst nichts installieren oder herunterladen.

3Die unsichtbaren Hidden-Felder

Sobald du einen Ort wählst, baut das Widget zusätzliche Felder ins Formular, die du nicht siehst, die aber mit abgesendet werden:

  • $_POST["ort_geonameid"] — eindeutige Kennung (z. B. 2867714 für München)
  • $_POST["ort_timezone"] — IANA-Zeitzone (Europe/Berlin)

Optional zusätzlich (siehe data-geoapi-lat, -lon, -country — wie im Detail-Tab oben aktiv): Koordinaten und Ländercode.

4Was dein Server-Skript damit macht

<?php
$ort       = trim($_POST["ort"]             ?? "");
$geonameid = (int) ($_POST["ort_geonameid"] ?? 0);
$timezone  = trim($_POST["ort_timezone"]    ?? "");

if ($geonameid === 0) {
    die("Bitte einen Vorschlag aus der Liste wählen.");
}

echo "Du hast gewählt: $ort";
echo " (geoNames-ID: $geonameid)";
echo " in der Zeitzone $timezone";

Wie geht es weiter?

Vier Bausteine, mit denen du das Widget an deine Anwendung anpassen kannst — alle live ausprobierbar. Jede Box zeigt das Eingabefeld plus genau den HTML-Code, der diese Variante erzeugt.

AEigenes Format für Liste & Eingabefeld

Standardmäßig zeigt das Widget „Munich (DE)" mit Zeitzone und Einwohnerzahl als Untertitel. Mit den Attributen data-geoapi-format-list und data-geoapi-format-input bestimmst du selbst, was angezeigt wird. Platzhalter sind in geschweiften Klammern: {name}, {country_code}, {admin1_code}, {timezone}, {population}, {lat}, {lon}, {geonameid}, {feature_code}.

<input type="text" name="fmt" data-geoapi-place
       data-geoapi-format-list="{name}<small>{admin1_code} · {timezone}</small>"
       data-geoapi-format-input="{name}">

BDaten automatisch in andere Felder/Anzeigen schreiben

Setze data-geoapi-fill="key" auf jedem beliebigen HTML-Element — sobald der Nutzer auswählt, wird das Element befüllt. Bei <input>/<textarea> in den value, sonst als Textinhalt.

Land: Zeitzone: Einwohner: Koordinaten: , Notizfeld:
<input type="text" name="meinort" data-geoapi-place>

<p>Land:        <span data-geoapi-fill="country_code"></span></p>
<p>Zeitzone:    <span data-geoapi-fill="timezone"></span></p>
<p>Einwohner:   <span data-geoapi-fill="population"></span></p>
<p>Koordinaten: <span data-geoapi-fill="lat"></span>,
                <span data-geoapi-fill="lon"></span></p>

<input type="text" data-geoapi-fill="name">
Mehrere Eingabefelder auf einer Seite? Standardmäßig gehört jedes Fill-Element zum nächsten Place-Input, der im DOM davor steht — solange deine Anzeige-Felder unter ihrem Eingabefeld stehen, klappt das automatisch. Falls nicht, explizit binden mit data-geoapi-fill-from="inputname".

CDebug-Modus: alle Werte sichtbar

Im Entwicklungsbetrieb hilfreich: data-geoapi-debug zeigt unterhalb des Eingabefelds eine Box, in der alle gerade gesetzten Werte sichtbar sind — die Hidden-Felder, die sonst niemand sieht. Im Produktivbetrieb das Attribut weglassen.

<input type="text" name="dbgort" data-geoapi-place
       data-geoapi-lat="dbgort_lat"
       data-geoapi-lon="dbgort_lon"
       data-geoapi-country="dbgort_cc"
       data-geoapi-debug>

DLayout der Auswahlliste über CSS

Alles am Aussehen ist über CSS-Variablen anpassbar — und zur Not können auch die internen Klassen direkt überschrieben werden. Probier folgende Variante mit warmen Farben:

<style>
.stage-warm {
  --geoapi-bg:           #fef3c7;
  --geoapi-fg:           #1f2937;
  --geoapi-border:       #f59e0b;
  --geoapi-border-light: #fde68a;
  --geoapi-active-bg:    #fbbf24;
  --geoapi-radius:       8px;
  --geoapi-shadow:       0 6px 16px rgba(245,158,11,0.25);
  --geoapi-padding-x:    0.9rem;
  --geoapi-padding-y:    0.55rem;
}
</style>

<div class="stage-warm">
  <input type="text" name="stilort" data-geoapi-place>
</div>

Vollständige Variablen-Liste:

--geoapi-bg, --geoapi-fg, --geoapi-muted,
--geoapi-border, --geoapi-border-light,
--geoapi-active-bg, --geoapi-radius,
--geoapi-shadow, --geoapi-max-height,
--geoapi-padding-x, --geoapi-padding-y,
--geoapi-font-size, --geoapi-z-index

Reicht das nicht, übersteure direkt die Klassen .geoapi-suggest-list, .geoapi-suggest-list li, .geoapi-suggest-list li.geoapi-active und .geoapi-suggest-list small.

Wie geht es weiter?