Mastering Tabs in Oracle APEX

Search for a command to run...

Thank you Jon!
Hi Jon, thank you for your blog post. Let's say I have a tab region with 4 tabs, and each tab has an Interactive Report with 10,000 records. When the page loads, I don't want all tabs to be fetching all the records. I want only the active tab to fetch the records for its IR. How can I do that? Thanks in advance.
Thank you Jon Dixon/ I don't see the Lazy Loading attribute for IR in version 20.2. It must be available for newer versions.
Muito bom.
Introduction One of the marquee features of APEX 26.1 was AI Interactive Reports. When I started testing this new feature, I was interested to see what was going on behind the scenes. In this post, I

Introduction One of the marquee features of APEX 26.1 is APEX AI Agents. APEX AI Agents allow you to use an LLM and your own PL/SQL and JS tools to perform actions on your data instead of just chattin

Introduction In my previous post, I looked at logging APEX AI Agent requests and responses with Request and Response handlers. Logging is the first step because it shows you what is actually moving th

Introduction Logging is one of the first things you need when building serious AI Agents. Without it, debugging quickly becomes guesswork. You can see the final answer, but not always why the model ch

Context management patterns from building agents in Oracle APEX

Tab regions in Oracle APEX help organize content by grouping related sections, reducing visual clutter, and improving user navigation. Used effectively, tabs can improve usability, performance, and user satisfaction.
This post will discuss some nuances about tab regions in APEX and the things I look out for.
Creating a tab container is straightforward: Create a region, assign the ‘Tabs Container’ template, and any regions placed beneath it become tabs.

There are four options you can tweak under Template Options:
Remember Active Tab - This one is key, if you check this, when a page is refreshed, APEX automatically shows the most recent tab after the refresh.
Layout, Tab Style, and Tabs Size - These options are all related to the visual appearance of tabs. Modify them to reflect the appearance you want for your tabs.
I recommend adding Static IDs to the Tab Container region and all Tab regions. This will allow you to reference them from JavaScript, which we will discuss later in the post.
If a tab region is based on a Classic Report, IR, IG, or Template Component, then I suggest enabling ‘Lazy Loading’ for infrequently used tab regions. This prevents the report in that region from running until the user clicks/activates the tab. This can significantly improve page load times for pages with multiple tabs.

Break the content of tabs into logical groups of fields. e.g., for a sales order page, place all customer information in a single tab.
Sequence tabs logically so that users can easily follow the flow as they move from tab to tab.
Try to keep the number of tabs to five or fewer. Any more than that becomes difficult for users to navigate.
I like to use the ‘Blank with Attributes’ region template for tab regions. This prevents the region title from showing up at the start of the tab, which overloads the UI (if you ask me).


You can add icons to tabs using the appropriate CSS classes in the region ‘Title’ as follows:

<span class="fa fa-search u-padding-right-sm" aria-hidden="true"></span>Search
Now that the APEX Universal Theme supports CSS variables, changing the color of tabs is easy. Adding the following CSS to the page level Inline CSS will change the active tab color to the primary color for the current Theme Style:
:root {
--ut-tabs-item-active-text-color: var(--ut-palette-primary-contrast);
--ut-tabs-item-active-background-color: var(--ut-palette-primary);
--ut-tabs-item-active-highlight-color: var(--ut-palette-primary);
}
Using the above CSS, I get this:

instead of this:

Sometimes it is helpful to perform an action when a tab is clicked (or activated).
atabsactivate, whenever a tab is clicked/activated. This allows developers to hook into tab actions programmatically.The below Dynamic Action shows a message with the static ID of the active Tab:

atabsactivate custom event is fired when a tab is clicked for the region called ‘Tab Container’. It is also fired on page load.
The JavaScript code first gets the currently active tab. I have assigned the static is cn-tabs-container to the Tab Region ‘Tab Container’.
It then strips out the href for the currently active tab which looks like this:
<a href="#SR_cn-search" class="t-Tabs-link" role="tab" aria-selected="true" aria-controls="SR_cn-search">
<span><span class="fa fa-search u-padding-right-sm" aria-hidden="true"></span>Search</span>
</a>
cn-search.Here is the complete code:
var active = apex.region("cn-tabs-container").widget().aTabs("getActive"),
href = active.href,
staticID = href.replace(/^#SR_/, "");
apex.message.showPageSuccess( "You clicked the " + staticID + " Tab");
atabsactivate event is also fired when the Tab Region is instantiated after a page load.When you click a tab, the Static ID of the tab region is displayed.


As of APEX 24.2, there is a bug in APEX that causes the apex.item( "TBD" ).setFocus() JavaScript API to not work if there is a tab region on the page. Details can be found in this APEX Forum Post. As you can see from the post, using the atabsactivate event allows us to set the focus on a specific field after the tab region has been activated.
We can modify our previous JavaScript to set the focus on a particular item when a tab is activated. In this case, we set the focus to the search field when the search tab is clicked; otherwise, we set the focus on the question field.
var active = apex.region("cn-tabs-container").widget().aTabs("getActive"),
href = active.href,
staticID = href.replace(/^#SR_/, "");
if (staticID === 'cn-search') {
apex.item( "P2_SEARCH" ).setFocus();
} else {
apex.item( "P2_QUESTION" ).setFocus();
}
Tab regions in Oracle APEX are a powerful tool for organizing complex UIs, but they require careful setup to deliver the best user experience. By thoughtfully configuring tab containers, leveraging lazy loading, using static IDs, and enhancing with CSS and JavaScript, you can create interfaces that are performant, intuitive, and visually consistent.