Last updated: August 28, 2026.
Dependent dropdowns are useful for country and state, category and product, or customer and project. Send a stable identifier to the server and build options with textContent.
Load options for the current selection
const parent = document.querySelector('#country');
const child = document.querySelector('#state');
let controller;
parent.addEventListener('change', async () => {
controller?.abort(); controller = new AbortController();
child.replaceChildren(new Option('Loading...', '')); child.disabled = true;
try {
const response = await fetch('/api/states?country=' + encodeURIComponent(parent.value), { signal: controller.signal });
if (!response.ok) throw new Error('Request failed');
const rows = await response.json();
child.replaceChildren(new Option('Choose a state', ''));
for (const row of rows) child.add(new Option(row.name, row.id));
child.disabled = false;
} catch (error) { if (error.name !== 'AbortError') child.replaceChildren(new Option('Could not load options', '')); }
});Secure the API too
- Authorize the endpoint on the server.
- Validate the parent identifier.
- Return only the fields the list needs.
- Handle empty results and network failure.
Building database forms with dependent fields?
PHPRunner can generate linked dropdowns and data-driven web forms. Explore PHPRunner.
Reference: MDN Fetch API guide.