Enhancing the Menu Drawer – Using Preferences

In the previous post I explained my approach to a menu drawer for the desktop. Now lets talk about how to remember if the drawer was left open or closed by the user.

One approach would be to use Cookies. Here’s a good reference blog post by Jeff Eberhard for that. I want to cover how I would do it using APEX User Preferences.

APEX Preferences are a convenient way to store user specific, generic information that will outlast a user’s session. Think of preferences as you would browser cookies. However, instead of only being valid for the current browser and a specified length of time, preferences are stored in the database, associated to the current user and with no expiration date.

The Approach

Here’s the technique I’m going to use. If the MENU_DRAWER_STATUS preference is set to “closed” then we’ll inject extra CSS in the page that will make the menu drawer start out closed. If it’s set to “open” then we don’t add anything because the default behavior of the sidebar is to start open.

We’ll add an open or closed class to the menu drawer handle itself (#menuToggle).  It won’t have any CSS assigned to it (but we could) as it will only be used to keep track of our current state when the page is running. We had this class already in the previous post, but this time we’ll add it based on the value of the preference.  We’ll also use a hidden item to obtain the preference value and default the class value on the menu drawer handle. Last but not least, we’ll add an “Execute PL/SQL Code” true action to our Dynamic Action to save our new preference value back to the database.

The Changes

Here’s the completed demo. Page 1 was for the last post. Page 10 is the one for this post.

First, I add a P10_MENU hidden item to store our initial state when the page loads. It will also be used by the PL/SQL code that will save the preference back to the database.  Make sure to specify “Value Protected = No” because we’ll be using Javascript to change it’s value.

Then we add a Before Header Computation to obtain the initial state. The Type “PL/SQL Function Body”. The code:

return nvl(apex_util.get_preference('MENU_DRAWER_STATUS'), 'open');

The nvl is important because, the very first time this runs for a user, they won’t have a value stored in the preference.

P10_MENU-Computation

Next, we edit the region with the menu drawer handle and add the class to it with this code: class=”&P10_MENU.”

Edit-Region

Now at this point, the title of the region is getting pretty long.

Long-Region-Name I find it a little annoying so I like to place all that content into an Application Item (Shared Components -> Application Items).  I use an application item, because it’s HTML contents are not escaped.  I add a computation to set the value and set the region title to the substitution of the item.  The source for the application item will look like this:

return '<a class="' || :P10_MENU || ' id="menuToggle" title="Hide or Show Menu" onclick="return false;" href="#0">&#9776;</a> Employees';

So now order is restored.

Substitution-Region-Name

Next we add a new region to hold the CSS needed when the sidebar needs to start closed.  The template should be “No Template” and the source:

<style>
table#uPageCols td#uLeftCol {display: none;}
table#uPageCols td#uLeftCol,
table#uPageCols td#uLeftCol>aside {width: 0;}
</style>

CSS-Region-sourceAnd for the condition we make sure this is only added when our User Preference, MENU_DRAWER_STATUS, is closed. Perfect opportunity to use the built-in “User Preference” condition.

CSS-Region-Conditional-Display

Next, we’re ready to modify the Dynamic Action.  In the Javascript that handles the open and close, we’re going to save the new state back to our hidden item P10_MENU.  All we need to add is this single line of code:

$s("P10_MENU", tStatus);

Edit-Open-Close-DA

Finally, we add one more True Action in which will save the new preference back to the database:

apex_util.set_preference('MENU_DRAWER_STATUS', :P10_MENU);

We don’t want it to fire on Page Load, and very important, we pass P10_MENU by adding it to “Page Items to Submit”.

This becomes an AJAX call to save the new preference value
This becomes an AJAX call to save the new preference value

We’re done.  Test it all out here.

 

Hi, I'm Jorge Rimblas. Father, husband, photographer, Oraclenerd, Oracle APEX expert, Oracle ACE, coffee lover, car guy, gadget addict, etc... I'm an APEX Tech Lead DRW. I have worked with Oracle since 1995 and done eBusiness Suite implementations and customizations. Nowadays I specialize almost exclusively in Oracle APEX.

2 Comments on “Enhancing the Menu Drawer – Using Preferences

  1. Hi Jorge Thanks for this post worked perfectly.
    Just an idea came to my mind.
    Say If I dont want to use any mobile theme in my app and I want my pull down list(Primary Navigation) to change to menu drawer when resolution is tablet or mobile.
    Is it possible with this approach?

I love comments, write me a line