How to build a better Pop-up LOV in Oracle APEX — Without Losing Your Mind


Let’s be honest. The native pop-up LOV in Oracle APEX is neat. It pops up a searchable list, you pick an option, job done! But if you’ve ever tried to filter columns inside that pop-up or wanted it to behave a bit smarter, you know the pain.
In this blog, I’ll share a neat trick how to solve this after wrestling with Oracle APEX LOVs. It’s about mimicking the native pop-up LOV’s look and feel while unlocking Interactive Report capabilities.
Want to see it in action? Watch the demo
Why Native Pop-up LOVs Sometimes Fall Short
The native pop-up LOV renders a classic report based on your LOV’s SQL source, great for simple lists but lacking advanced interactivity. But what if you want to extend this to an Interactive Report, enabling column filtering, sorting, and better search experience?
My guess is that it’s not natively supported because you can’t easily predefine the columns without knowing the shape of the SQL in advance. Interactive Reports also depend on fixed column metadata defined at design time.
Your options basically boil down to:
🔎 Option 1: Use a Button to Open a Dialog Page
Just create a button next to your Page Item, link it to a dialog (inline), and map return items. APEX handles everything: dialog, checksum, security, return value. But it doesn’t look like a Pop-up LOV at all!
🚫 Option 2: Open a Modal Page Using JavaScript (client-side)
You can either use apex.util.makeApplicationUrl
to generate the URL, or hardcode one, and then open the inline dialog like this:
const url = apex.util.makeApplicationUrl({
pageId: 10,
itemNames: 'P10_MANAGER_ID',
itemValues: $v('P4_USER_ID'),
});
apex.navigation.dialog(url, {
title: 'Choose Something',
height: '600',
width: '800'
});
But this doesn’t include a checksum, unless you create a server-side process to return a secure URL via apex_util.prepare_url
. Otherwise this means it can be a security risk or break altogether if APEX’s deep linking protection is enabled.
🤕 Option 3: AJAX Callbacks and Dynamic Rendering
Sure, you can write an AJAX process to return a secure URL including a checksum and return values using apex.navigation.dialog().then()
. Opening the modal is fine, but chaining modals becomes tricky. You’re introducing new modal sessions, and returning values across multiple modals can get unstable:
apex.server.process('getDepartmentLOV', {
x01: $v('P4_DEPARTMENT_ID')
}, {
success: function(pData) {
if (pData?.url) {
apex.navigation.dialog(pData.url, {
title: 'Select Department',
height: '600',
width: '800'
}).then(function(returnData) {
if (returnData) {
apex.item('P4_DEPARTMENT_ID').setValue(
returnData.returnValue,
returnData.displayValue
);
}
});
}
}
});
💀 Option 4: SQL Hacking (Don’t Do This)
Some adventurous devs try to build HTML in their LOV SQL using apex_escape.html()
and then parse it client-side. Please don’t. You’ll lose all the benefits of APEX items, LOV handling, and security.
The Eureka Moment: Fake It Till You Make It
What if you could fake the native pop-up LOV, but with an (inline) modal and an interactive report?
Create a fake pop-up LOV that looks exactly like the native one.
Trigger an (inline) modal with an Interactive Report inside (so you get column filters and sorting).
Use a hidden input for the actual stored ID value, and a readonly text input for the display label.
Keep checksums and session state happy because no weird URLs or page redirects are involved.
👇 Here's how to build it step-by-step:
Step 1: Custom Template to Mimic the Pop-up LOV UI/UX
A container div with
t-Form-fieldContainer
andapex-item-wrapper--popup-lov
classes.<div class="t-Form-fieldContainer t-Form-fieldContainer--floatingLabel apex-item-wrapper apex-item-wrapper--has-initial-value apex-item-wrapper--popup-lov js-show-label #ITEM_CSS_CLASSES#" id="#CURRENT_ITEM_CONTAINER_ID#">
A hidden input named like
#CURRENT_ITEM_NAME#_HIDDENVALUE
for the real value.<div class="t-Form-inputContainer"> <div class="t-Form-itemWrapper"> <input type="hidden" name="#CURRENT_ITEM_NAME#" id="#CURRENT_ITEM_NAME#_HIDDENVALUE"> <div class="apex-item-group apex-item-group--popup-lov">#ITEM_PRE_TEXT#
A text input will be placed between before/after label and styled as a pop-up LOV for showing the label.
<div class="t-Form-labelContainer"> <label for="#CURRENT_ITEM_NAME#" id="#LABEL_ID#" class="t-Form-label">
The classic little pop-up LOV button.
<button type="button" class="a-Button a-Button--popupLOV" id="#CURRENT_ITEM_NAME#_BTN"> <span class="a-Icon icon-popup-lov"></span> </button> </div>#ITEM_POST_TEXT##HELP_TEMPLATE# </div>#INLINE_HELP_TEMPLATE##ERROR_TEMPLATE# </div>
You can follow the wizard in Application → Shared Components → Templates → Create → Item to create a custom template for one of you fields templates, e.g. Optional Floating and it will look similar to this:
👉 Always check your current theme’s Popup LOV template for changes before copying this example.
This way when you do apex.item('P4_DEPARTMENT_ID').setValue(id, label)
, APEX knows what to do, hidden value updates, label updates, all the good stuff!
Step 2: Create the Input Using a Custom Template
Now it’s time to add a simple text field in your screen and set the Page Item → Appearance to your custom template, connect a list of values to translate the selected ID into something readable for the user.
Step 3: Inline Modal Region with Interactive Report
Next, you add an Inline Modal Region on the same page with an Interactive Report:
Fully searchable.
Column filters included.
Sortable.
Looks clean inside the modal pop-up.
Opening the modal in a breeze (refer to the static ID of the Inline Modal Region) by creating a Dynamic Action on Click with a simple Execute JavaScript Code:
apex.theme.openRegion("p4_department_lov_dialog");
Or create a hidden button linking to a Dialog Page, set-up return values, trick the opening of the modal by creating a Dynamic Action on Click of your Pop-up LOV and button.
Step 4: Picking a Value in the Modal (Optional)
Inside the modal’s Interactive Report, you set a click handler #p4_department_lov_dialog tbody tr
on the table rows, don’t forget to only target the table body, otherwise your row click fires when filtering columns.
When using this approach, I’d recommend assigning static IDs on your column names, like p4_ir_c_department_id
, so you can easily target the values:
apex.item('P4_DEPARTMENT_ID').setValue(
this.triggeringElement.querySelector("td[headers='p4_ir_c_department_id']").textContent.trim(),
this.triggeringElement.querySelector("td[headers='p4_ir_c_department_name']").textContent.trim()
);
apex.theme.closeRegion('p4_department_lov_dialog');
Boom! Hidden input and display text update instantly, modal closes, user happy.
Conclusion
Turning a boring old pop-up LOV into a fully interactive, filterable mini-report, wrapped in native styling.
It’s a pattern worth keeping in your toolbox, especially when you want your LOVs to be smart, stylish, and user-friendly without building a dozen Dialog Pages or writing complex JavaScript hacks.
Subscribe to my newsletter
Read articles from Jordy Kiesebrink directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Jordy Kiesebrink
Jordy Kiesebrink
Jordy completed his degree in media technology in 2016. He started as a developer in the e-commerce industry, where he built omnichannel web shops, an affiliate/data-driven marketing platform and a distributed cloud-native SaaS platform for web shops. Jordy is loyal and ambitious. In addition to his full-time job, he took a 4-year college ICT course in the evenings and continued working for his first employer. Despite a busy schedule, Jordy enjoys making space to help friends with their websites. With a Bachelor of Software Engineering in his pocket, he has joined the SMART4Solutions family as an ICT developer/consultant.