Skip to main content

Dynamic Collapsible Regions in Oracle APEX

 

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.

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')
});

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();

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>

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

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

Comments

Popular posts from this blog

Select/Unselect All Checkboxes in a Classic Report in Oracle APEX

Below are simple steps to select/unselect all checkboxes in a classic report: 1. Create a page with a classic report based on a sample query      select apex_item.checkbox(1, EMPLOYEE_ID) selectemp,        EMPLOYEE_ID,        FIRST_NAME,        LAST_NAME,        EMAIL,        PHONE_NUMBER,        HIRE_DATE   from EMPLOYEES 2. Add static ID : emp on the classic report region 3. Add below Javascript on the page function handleClick(cb) {     if  (cb.checked === true) {   $('#emp input[type=checkbox][name=f01]').prop('checked',true);       } else {   $('#emp input[type=checkbox][name=f01]').prop('checked',false); } } 4. Change the heading on the SELECTEMP column of the report to below              5. Ensure you set 'Escape Spe...

How to upload and embed a pdf document within a page in an Oracle APEX Application

Some Oracle APEX customers prefer to view embedded PDF documents directly within a page in their application rather than having to download. My current case study allows users to upload a .pdf document, save directly to a file location (rather than a DB Column) and view same embedded on the current page as shown above. Steps taken: 1. Identify the physical location of the #IMAGE_PREFIX# (/i/), in my case it is/u01/userhome/oracle/apex/images 2. Create a folder called 'docs' in the directory logged in as user SYS $ cd /u01/userhome/oracle/apex/images $ mkdir docs 3. Create a database directory called MY_DOCS create or replace directory MY_DOCS as '/u01/userhome/oracle/apex/images/docs'; Directory MY_DOCS created. grant read,write on directory MY_DOCS to {WORKSPACE_SCHEMA}; Grant succeeded. 4. Create a page within your application with following create page items PXX_FIRST_NAME (Textfield), PXX_LAST_NAME (Textfield), PXX_UPLOAD_DOC (File Browse), PXX...