# Mastering Tabs in Oracle APEX

# Introduction

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 Tab Regions in APEX

Creating a tab container is straightforward: Create a region, assign the ‘Tabs Container’ template, and any regions placed beneath it become tabs.

![Setting up and APEX Tab Container](https://cdn.hashnode.com/res/hashnode/image/upload/v1748437375467/7f98ea01-63fa-487c-864d-49d93ce5f49a.png align="center")

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.
    

## Static IDs

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.

## Enable Lazy Loading

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.

![Oracle APEX Tabs Enable Lazy Loading](https://cdn.hashnode.com/res/hashnode/image/upload/v1748440232314/232fb85b-4d61-464e-b53b-c31d5726d4ba.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">🚀</div>
<div data-node-type="callout-text">For a page with four reports, Lazy Loading can significantly reduce the initial page load.</div>
</div>

## Tab Content and Ordering

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.

## Tab Ordering

Sequence tabs logically so that users can easily follow the flow as they move from tab to tab.

## Number of Tabs

Try to keep the number of tabs to five or fewer. Any more than that becomes difficult for users to navigate.

# Tab Appearance and Customization

## Template for Tab Regions

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).

![APEX Tab Region with Standard Template](https://cdn.hashnode.com/res/hashnode/image/upload/v1748439672645/cc56e4c7-ee95-4417-80b4-5e1d29bc7383.png align="center")

![APEX Tab Region with Blank with Attributes Template](https://cdn.hashnode.com/res/hashnode/image/upload/v1748439712307/7ac42249-c59b-4121-ab45-ed9044165936.png align="center")

## Adding Icons to Tabs

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

![Adding Icons to APEX Tab Regions](https://cdn.hashnode.com/res/hashnode/image/upload/v1748439798802/29ecdb41-1976-41fa-b11e-e09aa139eb84.png align="center")

```css
<span class="fa fa-search u-padding-right-sm" aria-hidden="true"></span>Search
```

## CSS - Changing Tab Color

Now that the APEX Universal Theme supports [CSS variables](https://apex.oracle.com/pls/apex/r/apex_pm/ut/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:

```css
: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:

![APEX Tab using CSS to highlight the selected tab](https://cdn.hashnode.com/res/hashnode/image/upload/v1748442189416/ce7d8345-9617-4bbf-9274-c30b5de26b27.png align="center")

instead of this:

![APEX Active Tab display using defaults](https://cdn.hashnode.com/res/hashnode/image/upload/v1748442215417/c71a7e1f-a19d-4daa-b5e5-79c80e47ac9a.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Using CSS variables and Universal Theme classes allows your Apps to automatically adjust when you switch to a different theme or to changes to the Universal Theme delivered by Oracle.</div>
</div>

# Perform Actions on Tab Click/Activate

Sometimes it is helpful to perform an action when a tab is clicked (or activated).

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">APEX emits a custom JavaScript event, <code>atabsactivate</code>, whenever a tab is clicked/activated. This allows developers to hook into tab actions programmatically.</div>
</div>

## Example

The below Dynamic Action shows a message with the static ID of the active Tab:

![Oracle APEX Custom Event on Tab Region](https://cdn.hashnode.com/res/hashnode/image/upload/v1748442604420/42b69790-a91a-45f6-9ad2-b06323b608be.png align="center")

* In this case, the `atabsactivate` custom event is fired when a tab is clicked for the region called ‘Tab Container’. It is also fired on page load.
    

![Oracle APEX Execute JavaScript](https://cdn.hashnode.com/res/hashnode/image/upload/v1748442742707/2453e6c7-9e9a-415b-b34b-21af2d6a50fc.png align="center")

### **JavaScript Explanation**

* 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:
    

```xml
<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>
```

* Finally it gets the static ID of the active tab from the href. In this case the static ID for the Search Tab Region is called `cn-search`.
    

Here is the complete code:

```javascript
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");
```

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">The <code>atabsactivate</code> event is also fired when the Tab Region is instantiated after a page load.</div>
</div>

### Result

When you click a tab, the Static ID of the tab region is displayed.

![Oracle APEX Tab Region - User Clicks Countries Tab](https://cdn.hashnode.com/res/hashnode/image/upload/v1748443218418/16d3010b-5b0e-4d03-908e-fa8a3c32df2b.png align="center")

![Oracle APEX Tab Region - User Clicks Search Tab](https://cdn.hashnode.com/res/hashnode/image/upload/v1748443241525/79096243-f7ad-492e-be45-4b6c7829541e.png align="center")

# Known Issues and Workarounds

As of APEX 24.2, there is a bug in APEX that causes the [`apex.item( "TBD" ).setFocus()`](https://docs.oracle.com/en/database/oracle/apex/24.2/aexjs/item.html#setFocus) JavaScript API to not work if there is a tab region on the page. Details can be found in this [APEX Forum Post](https://forums.oracle.com/ords/apexds/post/set-focus-not-working-for-page-item-in-a-tab-region-7668). 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.

```javascript
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();
}
```

# Conclusion

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.
