React on RDS PagChange
published onWith the RDS and the region template tab container, APEX offers two options for grouping regions in such a way that they can be stacked on top of each other to save space. The RDS also has the option of showing all contained regions at once. I like to make use of both options. In the article (here) I had already described how to react to the activation of the individual tabs. This article will now focus on how to react to the change of tabs in an RDS.
Unlike with tab containers, the titles of the respective tabs are always displayed in an RDS, or are always hidden. Sounds strange. What I mean is, if I decide to show the special tab ShowAll, I want the regions to show all their titles. But as soon as I click on a "normal" tab, I don't want the title to be displayed. Why? Well, from a UI point of view, the title of the region would now be displayed twice. Once on the tab and once as a region title. I think that's a bit of a duplicate and doesn't look good either.
If you look at the DOM and define hard in APEX that a region header should be hidden, you will find the class t-Region--hideHeader
in the div of the region. This means that whenever this class is present, the title is not visible. In addition, we find the ID of the first list element in the DOM. This is SHOW_ALL_tab
. Each time this is activated, the element has the class apex-rds-selected
.
We have to check whether the class apex-rds-selected
is present in the element #SHOW_ALL_tab
on the change event or not and use the class t-Region--hideHeader
to hide the titles of the regions. For this I use a bit of Knockout.js and jQuery
// this will hold the model
var viewModel = {};
// check if given element is using the class given
function hasClass(elemID, className) {
return (' ' + document.getElementById(elemID).className + ' ').indexOf(' ' + className+ ' ') > -1;
}
function initPage () {
// whenever the RDS is clicked, we check whether the region title should be visible
// this has the binding defined in the custom attributes: data-bind="class: hideRegionHeader”
apex.jQuery('.apex-rds').data('onRegionChange', function(mode, activeTab) {
viewModel.hideRegionHeader(hasClass("SHOW_ALL_tab", 'apex-rds-selected') ? "" : "t-Region--hideHeader");
});
// define the model
viewModel = {
hideRegionHeader: ko.observable(hasClass("SHOW_ALL_tab", 'apex-rds-selected') ? "" : "t-Region--hideHeader")
}
// activate binding with knockout
ko.applyBindings(viewModel, document.querySelector("html"));
}
We define a model and create the hideRegionHeader property. This contains the class name t-Region--hideHeader
or nothing. The property itself should always be calculated when the TabPage is changed. For this we use the event onRegionChange
and bind it via JQuery. Whenever the event is triggered, the function hasClass is used to check whether the class is contained in the specified selector and thus the value of the property is recalculated using knockoutjs.
To make this working, you have to reference knockoutjs #JET_BASE_DIRECTORY#js/libs/knockout/knockout-3.5.1.js
and call then initPage method on PageLoad.
We bind the property itself to all regions that are displayed by the RDS. data-bind="class: hideRegionHeader"
Done.
As usual, you can find a demo here: https://apex.oracle.com/pls/apex/r/die21/demos/rdspage