Suggest states after choosing a country

Connect a country dropdown to editable state, province, or region suggestions in an HTML form.

JavaScript (browser)Last tested Download and run ↓
On this page

Working example

HTML + form.js

Run the example

Download HTML

country-state-dropdown.html

Replace YOUR_PUBLIC_API_KEY in the downloaded file with your public key. Add localhost to that key's allowed domains. In a terminal in the download folder, run:

Terminal · Python 3
python3 -m http.server 8000

Open localhost:8000/country-state-dropdown.html. When publishing, add your website's hostname to the key. Keep secret keys on your server.

Need a key? Set up this example

Connect country and region

Connect a country dropdown to a state or province field without hardcoding a subdivision list. Include form.js, mark the country selector, and bind the region input's native datalist to the returned states.

HTML
<script src="https://cdn.parseapi.com/v1/form.js" data-key="YOUR_PUBLIC_API_KEY" data-parse-version="2.0.0" defer></script>
<div class="field">
  <label for="country">Country</label>
  <select id="country" name="country" data-parse="country" autocomplete="country">
    <option value="">Choose a country</option>
    <option value="US">United States</option>
    <option value="CA">Canada</option>
    <option value="GB">United Kingdom</option>
    <option value="AU">Australia</option>
  </select>
</div>
<div class="field">
  <label for="state">State, province, or region</label>
  <input id="state" name="state" list="states" autocomplete="address-level1" placeholder="Choose or type a region">
  <datalist id="states" data-parse-from="country" data-parse-fill="states"></datalist>
</div>

The four country choices are examples. Replace them with the countries your form accepts, keeping their two-letter codes as option values.

Select a country

Choosing a country loads its subdivisions. The region field offers their names and codes using the browser's native suggestions. Selecting one enters its subdivision code. Someone can also type a region directly, including when the lookup is unavailable.

Changing countries clears the previous suggestions and a region selected from them. Manually typed regions remain editable. A late lookup for the previous country cannot replace the current list, and typing during a request keeps that manual entry.

The list can contain states, provinces, territories, or other subdivisions. Choose the geographic level your application needs.

Submit the country alongside the region: country=US and state=CA identify California together. The download's field names are country and state; adapt them to your server's input. Accept typed values according to your application's rules and validate the submitted pair on your server.

Build directly with the Country API when you need custom dropdown behavior or country details.

Complete example

One HTML file with your fields, styles, and the form.js include. Replace YOUR_PUBLIC_API_KEY with your public key, then run it on a domain you have added to that key.

View and copy the complete source
country-state-dropdown.html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Suggest states after choosing a country</title>
  <style>
    :root { color-scheme: light dark; --bg: #fff; --ink: #152029; --muted: #5e6b75; --line: #d9e2e7; --field: #f6f9fa; --accent: #007c91; --error: #b42335; }
    @media (prefers-color-scheme: dark) {
      :root:not([data-theme="light"]) { --bg: #0b1015; --ink: #eff7fa; --muted: #94a6b2; --line: #2c3942; --field: #121b23; --accent: #67e8f9; --error: #fda4af; }
    }
    :root[data-theme="dark"] { color-scheme: dark; --bg: #0b1015; --ink: #eff7fa; --muted: #94a6b2; --line: #2c3942; --field: #121b23; --accent: #67e8f9; --error: #fda4af; }
    :root[data-theme="light"] { color-scheme: light; }
    * { box-sizing: border-box; }
    [hidden] { display: none !important; }
    body { margin: 0; padding: 24px; background: var(--bg); color: var(--ink); font: 15px/1.5 system-ui, sans-serif; }
    main { max-width: 540px; margin: 0 auto; }
    label { display: block; margin-bottom: 8px; font-size: 14px; font-weight: 600; }
    input, select { display: block; width: 100%; min-width: 0; padding: 13px 14px; border: 1px solid var(--line); border-radius: 8px; background: var(--field); color: var(--ink); font: inherit; }
    input::placeholder { color: var(--muted); }
    /* Keep native selection; size the closed control consistently in Safari. */
    select:not([multiple]):where(:not([size]), [size="0"], [size="1"]) {
      -webkit-appearance: none;
      appearance: none;
      padding-right: 40px;
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='m4 6 4 4 4-4' fill='none' stroke='%2371717a' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
      background-repeat: no-repeat;
      background-position: right 12px center;
      background-size: 16px;
    }
    :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
    .field + .field { margin-top: 18px; }
    /* Your form owns these styles. form.js adds semantic markup and states. */
    input[data-parse-status="invalid"], input[data-parse-status="disposable"] { border-color: var(--error); }
    .parse-hint { margin: 6px 0 0; color: var(--muted); font-size: .875em; line-height: 1.4; overflow-wrap: anywhere; }
    .parse-hint[data-parse-status="invalid"], .parse-hint[data-parse-status="disposable"] { color: var(--error); }
    @media (max-width: 380px) { body { padding: 18px; } }
  </style>
</head>
<body>
  <main>
    <!-- example:form -->
    <script src="https://cdn.parseapi.com/v1/form.js" data-key="YOUR_PUBLIC_API_KEY" data-parse-version="2.0.0" defer></script>
    <div class="field">
      <label for="country">Country</label>
      <select id="country" name="country" data-parse="country" autocomplete="country">
        <option value="">Choose a country</option>
        <option value="US">United States</option>
        <option value="CA">Canada</option>
        <option value="GB">United Kingdom</option>
        <option value="AU">Australia</option>
      </select>
    </div>
    <div class="field">
      <label for="state">State, province, or region</label>
      <input id="state" name="state" list="states" autocomplete="address-level1" placeholder="Choose or type a region">
      <datalist id="states" data-parse-from="country" data-parse-fill="states"></datalist>
    </div>
    <!-- /example:form -->
  </main>
</body>
</html>

Need a key? Set up this browser example. For every field and parameter, see Country API reference.

Build something else

All tutorials →