Skip to main content

Command Palette

Search for a command to run...

APEX Collapsable Region add-ons

Updated
APEX Collapsable Region add-ons

Oracle APEX collapsible regions are great because they save space by letting us hide regions we don't need. However, there are a few missing features that would make these regions much better if implemented.

  1. Expand and collapse all: I miss a dynamic action to collapse and expand all to make it easy to find a region on a page with multiple regions. We have the dynamic action to colapse tree but not regions.

  2. Save the collapsible state beyond the session: Currently, we can save the collapsible state, but unfortunately, it's only saved for the session. If I collapse a region that isn't important to me, logging off and logging in again resets my chosen state.

In the video below, I have a page with 4 collapsible regions and two buttons that can collapse and expand all regions at the same time. If only the 4th region is important to me, when I collapse all, I can easily open wihout scrooling. In the second part of the video, I log off and log in again, and instead of resetting, the state of the region is saved.

To add those features, I’ve created the JavaScript below where I use apex.storage to save the collapsible region state when users click to expand or collapse. When the page loads, this JS also restores the regions to the saved state.

// Function to collapse all collapsible regions
window.collapseAll = function() {
    if (!apex.storage.hasLocalStorageSupport()) return;

    const storage = apex.storage.getScopedLocalStorage({
        applicationId: apex.env.APP_ID,
        pageId: apex.env.PAGE_ID,
        usePageId: true
    });

    $('.a-Collapsible').each(function() {
        const regionId = $(this).attr('id');
        storage.setItem(regionId, 'C');
        $(this).collapsible('collapse');
    });
};

// Function to expand all collapsible regions
window.expandAll = function() {
    if (!apex.storage.hasLocalStorageSupport()) return;

    const storage = apex.storage.getScopedLocalStorage({
        applicationId: apex.env.APP_ID,
        pageId: apex.env.PAGE_ID,
        usePageId: true
    });

    $('.a-Collapsible').each(function() {
        const regionId = $(this).attr('id');
        storage.setItem(regionId, 'S');
        $(this).collapsible('expand');
    });
};

// Initialization with state restoration
$(function() {
    'use strict';

    // Configure scoped storage  
    const storage = apex.storage.getScopedLocalStorage({  
        applicationId: apex.env.APP_ID,  
        pageId: apex.env.PAGE_ID,  
        usePageId: true  
    }); 

    // Restore states on page load
    $(window).on('apexwindowload', function() {  
        $('.t-Region--hideShow').each(function() {  
            const $region = $(this);  
            const state = storage.get($region.attr('id'));  
            if (state === 'C') {  
                $region.collapsible('collapse', {duration: 0});  
            } else {  
                $region.collapsible('expand', {duration: 0});  
            }  
        });  
    }); 

    // Persist state changes
    $(document).on('apexaftertoggle', '.t-Region', function(e, data) {  
        const regionId = $(this).attr('id');  
        storage.set(regionId, data.collapsed ? 'C' : 'S');  
    });  

    // Button click handlers
    apex.jQuery(document).on("click", "#EXPAND_BTN", function() {
        expandAll();
    });

    apex.jQuery(document).on("click", "#COLLAPSE_BTN", function() {
        collapseAll();
    });
});

I recommend you create the JavaScript above as a static file and reference it at the app level if you use collapsible regions throughout the app.

For the buttons, create two buttons as the following

Label: Collapse All
Behavior: Redirect to URL
URL: javascript:void(0);
Static ID: COLLAPSE_BTN

Label: Expand All
Behavior: Redirect to URL
URL: javascript:void(0);
Static ID: EXPAND_BTN

Enjoy!

More from this blog

A

APEX Blog

33 posts