Cascading LOVs in Oracle APEX - Country → State → City
Build a 3-level dependent dropdown with zero custom JavaScript - using Dynamic Actions, SQL LOVs, and APEX's native cascading feature.

✍️ Utkarsh Ranjan · Oracle APEX Certified Pro (1Z0-771) · ⏱ 8 min read · Beginner → Intermediate
Cascading dropdowns are one of the most common requirements in enterprise forms. When a user selects a Country, the State dropdown should update automatically. When they select a State, the City dropdown should update.
Most developers think this requires JavaScript. In Oracle APEX — it doesn't.
APEX has a built-in Cascading LOV feature that handles this automatically using:
SQL-based List of Values
Native "Cascading LOV Parent Item" setting
Zero JavaScript required
In this blog I'll show you how to build a complete Country → State → City cascading dropdown from scratch.
What We Are Building
┌─────────────────────────────────┐
│ Country [ India ▼ ] │
│ State [ Uttar Pradesh ▼ ] │
│ City [ Kanpur ▼ ] │
└─────────────────────────────────┘
When Country changes → State list refreshes automatically When State changes → City list refreshes automatically
No JavaScript. No Dynamic Actions. Just APEX configuration.
Step 1 - Create the Tables
First create the reference tables for our LOVs:
Step 2 - Insert Sample Data
Step 3 - Create the Page in APEX
App Builder → your app → Create Page
Select Blank Page
Name:
Location SelectorClick Create Page
Step 4 - Add a Form Region
Page Designer → right-click Body → Create Region
Title:
Select Your LocationType:
Static ContentClick Save 💾
Step 5 - Create the Country Dropdown
Right-click your region → Create Page Item
Fill in:
| Field | Value |
|---|---|
| Name | P2_COUNTRY |
| Type | Select List |
| Label | Country |
- Right panel → List of Values section:
| Field | Value |
|---|---|
| Type | SQL Query |
| SQL Query | see below |
| Display Extra Values | No |
| Null Display Value | -- Select Country -- |
SQL Query for Country LOV:
SELECT country_name AS display_value,
country_id AS return_value
FROM countries
ORDER BY country_name
- Click Save 💾
Step 6 - Create the State Dropdown
This is where the magic happens — the Cascading LOV Parent Item setting:
Right-click region → Create Page Item
Fill in:
| Field | Value |
|---|---|
| Name | P2_STATE |
| Type | Select List |
| Label | State |
- Right panel → List of Values section:
| Field | Value |
|---|---|
| Type | SQL Query |
| SQL Query | see below |
| Cascading LOV Parent Item(s) | P2_COUNTRY ← KEY SETTING |
| Null Display Value | -- Select State -- |
SQL Query for State LOV:
SELECT state_name AS display_value,
state_id AS return_value
FROM states
WHERE country_id = :P2_COUNTRY
ORDER BY state_name
💡 The
:P2_COUNTRYbind variable is what links State to Country. When Country changes, APEX automatically re-runs this query with the new Country value.
Click Save 💾

Step 7 - Create the City Dropdown
Same pattern - cascades from State:
Right-click region → Create Page Item
Fill in:
| Field | Value |
|---|---|
| Name | P2_CITY |
| Type | Select List |
| Label | City |
- Right panel → List of Values section:
| Field | Value |
|---|---|
| Type | SQL Query |
| SQL Query | see below |
| Cascading LOV Parent Item(s) | P2_STATE ← KEY SETTING |
| Null Display Value | -- Select City -- |
SQL Query for City LOV:
SELECT city_name AS display_value,
city_id AS return_value
FROM cities
WHERE state_id = :P2_STATE
ORDER BY city_name
- Click Save 💾
Step 8 - Run and Test
Click Save 💾
Click Run ▶️
Select India from Country dropdown
State dropdown automatically shows UP, Maharashtra, Delhi, Karnataka
Select Uttar Pradesh
City dropdown automatically shows Kanpur, Lucknow, Agra, Varanasi
No JavaScript. No Dynamic Actions. It just works! ✅
How It Works Behind the Scenes
When you set Cascading LOV Parent Item = P2_COUNTRY on the State item:
User selects Country = India (value = 1)
↓
APEX detects P2_COUNTRY changed
↓
APEX re-runs State LOV SQL with :P2_COUNTRY = 1
↓
SELECT state_name, state_id FROM states
WHERE country_id = 1 ← automatically substituted
↓
State dropdown refreshes with India's states ✅
APEX handles the AJAX call, the query execution, and the dropdown refresh all natively.
Bonus - Save Selected Values to Database
Add a Submit button and process to save the selection:
-- Create a table to store selections
CREATE TABLE user_locations (
location_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
country_id NUMBER,
state_id NUMBER,
city_id NUMBER,
created_by VARCHAR2(100),
created_on DATE DEFAULT SYSDATE
);
Page Process on Submit:
Bonus - Show Selected Values as Text
To display the selected names (not IDs) in a confirmation area:
Common Issues and Fixes
| Issue | Cause | Fix |
|---|---|---|
| State not refreshing | Wrong parent item name | Check spelling — must match exactly e.g. P2_COUNTRY |
| City not refreshing | Cascading parent not set | Set P2_STATE as parent for City item |
| Empty dropdown | Wrong bind variable | Use :P2_COUNTRY not &P2_COUNTRY. in SQL LOV |
| All states showing | Missing WHERE clause | Add WHERE country_id = :P2_COUNTRY |
| Null option missing | Display Extra Values = Yes | Set to No and add Null Display Value |
Also:
1. You can chain more than 3 levels Country → State → City → Area → Pincode — just keep adding Cascading LOV Parent Item at each level.
2. Use Shared Components for LOVs If the same Country/State/City dropdowns are used on multiple pages, create them as Shared LOVs in Shared Components → List of Values. Reuse them across pages.
3. Clear child items when parent changes By default APEX clears child items when parent changes. But if you want to explicitly control this, add a Dynamic Action on P2_COUNTRY Change → Set Value → P2_STATE = null, P2_CITY = null.
4. Pre-select a default value Set Default → Type → Static Value on the Country item to pre-select a country when the page loads:
Default Value: 1 (India's country_id)
5. Use APEX_ITEM for tabular cascading For cascading dropdowns inside an Interactive Grid or tabular form, use APEX_ITEM.SELECT_LIST_FROM_QUERY with the cascading parameter.
Wrapping Up
Cascading LOVs in Oracle APEX are one of those features that make you appreciate how well-designed the framework is. A feature that would take hours of JavaScript in other frameworks takes 5 minutes of configuration in APEX.
The key things to remember:
✅ Use
SQL Querytype for your LOVs✅ Always use bind variable
:PARENT_ITEMin WHERE clause✅ Set Cascading LOV Parent Item(s) on child items
✅ Set Null Display Value for better UX
✅ No JavaScript needed — ever
Follow me for more Oracle APEX, PL/SQL and Low-Code content.
OracleAPEX CascadingLOV SelectList LowCode OracleDatabase Tutorial PLSQL
Utkarsh Ranjan · Oracle APEX Certified Pro (1Z0-771) ·


