Dynamic Collapsible Regions in Oracle APEX

Photo by Jess Bailey on Unsplash

Dynamic Collapsible Regions in Oracle APEX

Introduction

Recently, I was asked to create a screen that displays the status of the entries in each collapsible region and makes sure users only work on one collapsible region at a time.

This article will demonstrate how to complete this task by following a few simple steps.

The theme used: Universal Theme.

Step 1

In this example, I have included 3 collapsible regions with respective static ids region1,region2 and region3 and 'Remember Collapsible State' checked for all.

In the 'Function and Global Variable Declaration' section

add below Javascript

function f_navigator(pVal) {
    if (document.getElementById(pVal).value == null) {
        document.getElementById(pVal).value = 1;
        $('#' + pVal + '.a-Collapsible.is-collapsed').removeClass('is-collapsed').addClass('is-expanded');
        $('#' + pVal + '.a-Collapsible .a-Collapsible-content').show();
        var myArrayselected = ["region1", "region2", "region3"];
        var aLengthselected = myArrayselected.length;
        for (var i = 0; i < aLengthselected; i++) {
            if (myArrayselected[i] !== pVal) {
                document.getElementById(myArrayselected[i]).value = null;
            }
        }
    } else {
        document.getElementById(pVal).value = null;
        $('#' + pVal + '.a-Collapsible.is-expanded').removeClass('is-expanded').addClass('is-collapsed');
        $('#' + pVal + '.a-Collapsible .a-Collapsible-content').hide();
        var myArrayunselected = ["region1", "region2", "region3"];
        var aLengthunselected = myArrayunselected.length;
        for (var i = 0; i < aLengthunselected; i++) {
            if (myArrayunselected[i] !== pVal) {
                document.getElementById(myArrayunselected[i]).value = null;
            }
        }
    }
    $('#' + pVal + '.t-Region--hideShow.js-useLocalStorage.t-Region--scrollBody.a-Collapsible.is-expanded').addClass('t-Region--accent1');
    $('#' + pVal + '.t-Region--hideShow.js-useLocalStorage.t-Region--scrollBody.a-Collapsible.is-collapsed').addClass('t-Region--accent1');
    var myStringArray = ["region1", "region2", "region3"];
    var arrayLength = myStringArray.length;
    for (var i = 0; i < arrayLength; i++) {
        console.log(myStringArray[i]);
        if (myStringArray[i] !== pVal) {
            $('#' + myStringArray[i] + '.a-Collapsible.is-expanded').removeClass('is-expanded').addClass('is-collapsed');
            $('#' + myStringArray[i] + '.a-Collapsible .a-Collapsible-content').hide();
            $('#' + myStringArray[i] + '.t-Region--hideShow.js-useLocalStorage.t-Region--accent1.t-Region--scrollBody.a-Collapsible.is-collapsed').removeClass('t-Region--accent1');
        }
    }
}

$("#region1 button.t-Button.t-Button--icon.t-Button--hideShow").click(function(){
f_navigator('region1')
});
$("#region2 button.t-Button.t-Button--icon.t-Button--hideShow").click(function(){
f_navigator('region2')
});
$("#region3 button.t-Button.t-Button--icon.t-Button--hideShow").click(function(){
f_navigator('region3')
});

Step 2

Add a page load dynamic action to ensure the regions are collapsed by default.

Add below javascript

  $('#region1.a-Collapsible.is-expanded').removeClass('is-expanded').addClass('is-collapsed');
    $('#region1.a-Collapsible .a-Collapsible-content').hide();
  $('#region2.a-Collapsible.is-expanded').removeClass('is-expanded').addClass('is-collapsed');
    $('#region2.a-Collapsible .a-Collapsible-content').hide();
  $('#region3.a-Collapsible.is-expanded').removeClass('is-expanded').addClass('is-collapsed');
    $('#region3.a-Collapsible .a-Collapsible-content').hide();

Step 3

Change the region titles to ensure each title text is clickable

<p style='cursor:pointer;' onclick="f_navigator('region1')">Region 1</p>
<p style='cursor:pointer;' onclick="f_navigator('region2')">Region 2</p>
<p style='cursor:pointer;' onclick="f_navigator('region3')">Region 3</p>

Step 4

In my example, I have included only two items and want to track their entry statuses. Add a dynamic action 'when item changed' and ensure 'Fire on initialization' is set to Yes.

Include the below Javascript codes and apply it accordingly to all 3 regions

if (apex.item('P8_TEXTFIELD1').getValue().length >= 1 && apex.item('P8_RADIOGROUP1').getValue().length >= 1) {
  $('#region1 div.t-Region-headerItems.t-Region-headerItems--buttons').html('<i class="fa fa-check-circle fa-2x" style="color:green">&nbsp;</i>');
} else if (apex.item('P8_TEXTFIELD1').getValue().length >= 1 || apex.item('P8_RADIOGROUP1').getValue().length >= 1 ) {
  $('#region1 div.t-Region-headerItems.t-Region-headerItems--buttons').html('<i class="fa fa-check-circle fa-2x" style="color:orange">&nbsp;</i>');
} else {
  $('#region1 div.t-Region-headerItems.t-Region-headerItems--buttons').html('');
}
if (apex.item('P8_TEXTFIELD2').getValue().length >= 1 && apex.item('P8_RADIOGROUP2').getValue().length >= 1) {
  $('#region2 div.t-Region-headerItems.t-Region-headerItems--buttons').html('<i class="fa fa-check-circle fa-2x" style="color:green">&nbsp;</i>');
} else if (apex.item('P8_TEXTFIELD2').getValue().length >= 1 || apex.item('P8_RADIOGROUP2').getValue().length >= 1 ) {
  $('#region2 div.t-Region-headerItems.t-Region-headerItems--buttons').html('<i class="fa fa-check-circle fa-2x" style="color:orange">&nbsp;</i>');
} else {
  $('#region2 div.t-Region-headerItems.t-Region-headerItems--buttons').html('');
}
if (apex.item('P8_TEXTFIELD3').getValue().length >= 1 && apex.item('P8_RADIOGROUP3').getValue().length >= 1) {
  $('#region3 div.t-Region-headerItems.t-Region-headerItems--buttons').html('<i class="fa fa-check-circle fa-2x" style="color:green">&nbsp;</i>');
} else if (apex.item('P8_TEXTFIELD3').getValue().length >= 1 || apex.item('P8_RADIOGROUP3').getValue().length >= 1 ) {
  $('#region3 div.t-Region-headerItems.t-Region-headerItems--buttons').html('<i class="fa fa-check-circle fa-2x" style="color:orange">&nbsp;</i>');
} else {
  $('#region3 div.t-Region-headerItems.t-Region-headerItems--buttons').html('');
}

Conclusion

This approach gives a better user experience and the implementation steps are easy, I hope you will find it useful.

https://apex.oracle.com/pls/apex/f?p=100471:8:103249608478489:::::