placedb

Picker

Country, state and city fields in one line.

Add one script, then one tag inside your form. Your users pick a country, then a state or province, then type their city. Your form receives codes, names and coordinates as plain fields. No key, no account, no build step.

Try it

A real form

What the form sends

Choose a city and press Submit.

Add it

Two lines of HTML

<script src="https://placedb.org/picker/v1.js" defer></script>

<form method="post" action="/address">
  <placedb-picker required></placedb-picker>
  <button>Save</button>
</form>

The fields are ordinary inputs inside your form, so a normal submit, a FormData, PHP's $_POST or any framework reads them with no extra code.

Fields

What your form receives

country
ISO 3166-1 alpha-2 code
country_name
Country name
region
Division id, the key for /v1/cities/<CC>/<id>.json
region_name
Division name, empty for Other
region_iso
ISO 3166-2 code, when the division has one
city
Settlement id, empty for a typed name
city_name
Settlement name
lat, lon
Coordinates of the chosen settlement

Options

Attributes

country
ISO code to start on, such as IN. With region and city (ids), an edit form opens on a saved address.
countries
Limit the list, such as "IN,NP,BD". With one country, its field is preselected.
prefix
Put before every submitted field name: prefix="ship_" submits ship_country, ship_city and so on.
required
Every visible field must be filled before the form submits.
strict
The city must be chosen from the list. Without it, a typed name is submitted with an empty city id.
label-country, label-region, label-city
Field labels. Defaults: Country, State / province, City.
label-other
What to call places the dataset could not place in a division. Default: Other.
unstyled
Skip the built-in styles. Every rule uses :where(), so your own CSS wins either way.

In script

document.querySelector('placedb-picker')
  .addEventListener('placechange', (event) => {
    const { country, region, city } = event.detail;
    // city is { id, name, lat, lon } once one is chosen
  });

The element's value property returns the same object at any time.

Under it

Three static files

The picker reads countries.json, then the chosen country's divisions, then the full settlement list of the chosen division, and filters it as your user types. Half of all divisions list under 3 KB. The path /picker/v1.js never changes behaviour; a breaking change ships as v2.