In one of my previous blog entries, I gave a brief explanation on how to create an accordion navigation menu. Someone commented on that article asking me how to open up multiple panels and remember the state (expanded or collapsed) of each panel. Since these two requirements are not related to the concept of an accordion navigation, I decided to write this separate article on how to create a vertical collapsible navigation menu. The end result can be seen here.
Step 1: create a custom list template
Navigate to the template section of your current theme and create a list template from scratch. Assign it a name and a custom theme class. Then, edit the list template and copy and paste the following code snippets in the appropriate sections.
- Before List Entry > List Template Before Rows (for example <table> <tr>)
<div id="vertical-collapsible-nav">
- Template Definition > List Template Current
<div class="is-lvl1-current"><span id="#A01#">#TEXT#</span> </div>
- Template Definition > List Template Current with Sub List Items
<div class="is-lvl1-current"><span id="#A01#">#TEXT#</span> <ul>
- Template Definition > List Template Noncurrent
<div><span id="#A01#">#TEXT#</span> </div>
- Template Definition > List Template Noncurrent with Sub List Items
<div><span id="#A01#">#TEXT#</span> <ul>
- Sublist Entry > Sub List Template Current
<li> <a href="#LINK#" alt="#TEXT#" class="is-lvl2-current"> <img src="#IMAGE#" #IMAGE_ATTR# /> #TEXT# </a> </li>
- Sublist Entry > Sub List Template Noncurrent
<li> <a href="#LINK#" alt="#TEXT#"> <img src="#IMAGE#" #IMAGE_ATTR# /> #TEXT# </a> </li>
- After Sublist Entry > Sublist Template After Rows
</ul></div>
- After List Entry > List Template After Rows (for example </tr> </table>)
</div>
Step 2: create and populate your navigation list
We now need to create a static list based on the list template we created in step 1. Include all navigation entries for your application in a parent-child hierarchy. The image below shows you the list entries that I used for the demo:
In the template definition in step 1, I make use of the #A01# substitution string to assign each first level list entry an id value. You can manage these values by navigating to the User Defined Attributes section at the bottom of the list entry detail page.
Please note that the list template we created in step 1 only supports a two-level hierarchy. List entries with a level number higher than two are simply being rendered as two-level entries. Also, pay attention to the Current List Entry section for each list entry. You might experience abnormal behaviour when you don’t take into account this setting.
Step 3: add the list to your pages
Page zero is ideal in this situation since you probably want to display the navigation menu on multiple pages. So just create a list region that uses the list we created in step 2.
Step 4: apply CSS to the list region
Here is how I styled mine in the demo:
/* first level menu */ div#vertical-collapsible-nav { width: 200px; background-color: #DDDDDD; border: 1px solid #9C9C9C; } div#vertical-collapsible-nav div span { display: block; padding: 4px 5px 4px 10px; font-weight: bold; color: #222222; } div#vertical-collapsible-nav div span:hover { background-color: #CCCCCC; cursor: pointer; } /* second level menu */ div#vertical-collapsible-nav div ul { list-style-type: none; margin: 0; } div#vertical-collapsible-nav div ul li { background-color: #F2F2F2; padding: 4px 5px 4px 18px; } div#vertical-collapsible-nav div ul li a { text-decoration: none; color: #222222; } div#vertical-collapsible-nav div ul li a.is-lvl2-current { font-weight: bold; } div#vertical-collapsible-nav div ul li a:hover { color: #3E9FFF; } div#vertical-collapsible-nav div ul li a img { vertical-align: middle; padding-right: 5px; }
Step 5: include jQuery cookie
This jQuery plugin simplifies cookie management. Download the JavaScript file here. Upload this file as a static file in shared components and include it in on your page(s) or page template.
Step 6: the jQuery code
- Function and Global Variable Declaration:
// return a unique array Array.prototype.getUnique = function(sort) { var u = {}, a = [], i, l = this.length; for (i = 0; i < l; ++i) { if (this[i] in u) { continue; } a.push(this[i]); u[this[i]] = 1; } return (sort) ? a.sort() : a; }
- Execute when Page Loads:
var cookie = $.cookie("panelState"), collapsed = cookie ? cookie.split("|").getUnique() : [], cookieExpires = 7; $.each(collapsed, function() { $('#' + this).siblings("ul").hide(); }); $("div#vertical-collapsible-nav div span").click(function() { var spanClicked = this; $(this).siblings("ul").slideToggle(300, function() { updateCookie(spanClicked); }); }); function updateCookie(el) { var tmp = collapsed.getUnique(); if ($('#' + el.id).siblings("ul").is(':hidden')) { tmp.push(el.id); } else { tmp.splice(tmp.indexOf(el.id), 1); } collapsed = tmp.getUnique(); $.cookie("panelState", collapsed.join('|'), { expires: cookieExpires } ); }
Source: http://stackoverflow.com/questions/3890524/jquery-menu-remembering-the-state-of-the-menu
There you go. Have a look at the demo.
Any problems or questions? Just post a comment.
I do everything as stated in this article, but the cookies are not saved. why this might be?
LikeLike
I added line:
LikeLike
I guess your code snippet got eaten by the comment system. I’d go to the article again and scan for possible errors. A few tips:
– Are you sure you assigned an id to each first level entry?
– Check for JavaScript errors while running the page.
– Put some alert messages in the JavaScript code. For example, use “alert(“cookie content: ” + expanded.join(‘,’));” to display the content of your cookie.
Good luck!
LikeLike
in file ” jquery.cookie.js ” should anything change?
LikeLike
could you make a user demo, so I can go to your circuit and see how it all dispensations?
LikeLike
The file “jquery.cookie.js” should not be changed.
I’m not going to make a user demo for this. The article contains all the steps required to accomplish your goal.
LikeLike
Reblogged this on Sutoprise Avenue, A SutoCom Source.
LikeLike
Thank you very much!!!!!!! I figured out the problem. In fact, everything is very easy to!!!!!!!!!!!!!!!!!
LikeLike
in page 0 shows this menu. how to fix this error?
LikeLike
How do I increase the width of the menu container?
LikeLike
You’ll have to modify the CSS. Locate the following part:
div#vertical-collapsible-nav {
width: 200px;
background-color: #DDD;
border: 1px solid #9C9C9C;
}
The width of the menu container is now 200px. Make it bigger by increasing the amount of pixels.
LikeLike
Thanks. Will give it a shot
LikeLike
Is it possible to create more than two levels of menu items?
LikeLike
It is possible, but this tutorial does not include and thus not support an unlimited amount of menu level items. You might have a look at Google for a suitable solution.
LikeLike
hi just now i have seen this example can u please tell me how to use this on page zero becoz for script java script and Function and Global Variable Declaration and Execute when Page Loads can u please tell me where to put this code becoz in page 0 we dnt have this section please guide me
LikeLike
Hello Shadab,
There is a JavaScript section on page template level, if you’re using APEX 4.2 or higher. You can put the code right there. If you’re not on APEX 4.2, you can still include the JavaScript somewhere in the Definition section.
LikeLike
thanks nick sorry i have not updated my comment i got success can but can we make this example as accordion menu
LikeLike
Hello Nick Buytaert,
I wanted to ask you. How can you make a 3 level menu? What exactly is to be done? What should be changed? Thanks in advance!
Best regards, Alexander.
LikeLike
Hey Alexander,
That is certainly possible. It requires, however, quite some changes to the code. I’ll create an example on apex.oracle.com and make it available to download. I’ll keep you posted.
I don’t understand your second question…
LikeLike
I wanted to ask you. Is it possible to apply this Javascript to the report(classic, IR, Tabular form), but not for dynamic list ???
LikeLike
Thanks for your answer.
How can add checkboxes to dynamic list? it’s possible?
LikeLike
Alexander, I published a new article in which I explain how you can create a multi level navigation menu:
Adding checkboxes to a dynamic list is not possible, I think.
LikeLike
I tried to create a collapsible menu but it only collapse at first load, when i click a link to go to the next page, it does not remember the state of the menu and also does not collapse when i click a first menu item….
where do i go wrong??
LikeLike
Difficult to say what went wrong. Do you get any JavaScript errors in the console of your browser?
LikeLike
I haven’t seen javascript errors (or not noticed)
Could I provide you with credentials for my apex.oracle.com application so you can have a look ? (by mail?)
LikeLike
I’ll have a look. You can send me your login credentials via mail: nbuytaert1@gmail.com.
LikeLike
Hi Nick again.I would like to ask you. Can this way to create a menu to work for Apex 4.2?
Thanks in advance!
Best Regards, Alexander Korotkov
LikeLike
Hey Alexander. It is still possible to create this kind of menu in APEX 4.2.
LikeLike
Yes. I create. But when I click on a menu item, it does not expand. At version 4.1, it works well
LikeLike
I think the above tutorial should work in APEX 4.2. I guess something went wrong on your side. Can you reproduce your problem on apex.oracle.com and send me the workspace login credentials? This way I can have a look at your code.
LikeLike
Thank you very much. please sent me your e-mail.
LikeLike
My e-mail address is apexplained@gmail.com.
LikeLike
Hi Nick, Firstly, thanks for this and the other examples… Great to use… One questions/problem.
Im using the collapsible nav menu.. (Im not actually, collapsing it with any code, I just like the style.. All works OK, except Im trying to modify the style to reflect the rest of my application. Mainly, to narrow it down a little as it seems to ‘bump’ into my reports region, and also to round the corners of the border..
However, when I change the CSS, nothing happens… If I remove the css, then the menu goes back to a bullet list, so its clearly referencing it, but if I change anything in the css, nothing happens…
Any ideas?
Many Thanks
Richard
LikeLike
Hey Richard,
Sounds like a caching issue to me. Have you tried hard refreshing your page after modifying the CSS file? That’s how you tell the browser to bypass the cache and reload the file from the server (or database in case you’re using files in shared components). The key combination to hard refresh the page in your browser is OS dependent:
– Windows: ctrl + F5
– Mac: cmd + R
– Linux: F5
Hope that helps,
Nick
LikeLike
Hey Nick. Worked a treat thanks.. One (hopefully final) question… Either 1) where did you get your icons, as I’d like to get some that look similar but relate more to the menus.. (its a finanical app, with payments, budget etc..) or2) alternatively, can I remove the icons.. (and I’ve tried removing the reference to the images in the list, but it comes up with a broken image icon in the menu)..
Many Thanks
Richard
LikeLike
Richard,
1. Here’s the icon set: http://tutsii.deviantart.com/art/49-hand-drawing-icons-set-123691516
2. You’ll have to modify the list template for that. Remove the img tag from the sublist entries.
<img src="#IMAGE#" #IMAGE_ATTR# />
Cheers,
Nick
LikeLike
Hi Nick, thanks for the info.. very Useful… I have one further question. Im really struggling with the style sheet and matching the menu to the theme Im using.. Ive tried to get the right information from the theme, then update the CSS with the right info, but Im struggling.. (and Im pretty new to CSS etc.. Is there any way to inherit the theme classes in the CSS for the collapsible menu? (I’m using Theme 17.. (Sapphire) and I cannot seem to make the menu look like it..
Many thanks..
Richard
LikeLike
Richard,
The best way to match the theme style is by applying the theme colours on the collapsible menu. That shouldn’t be too difficult, although it depends on your experience with CSS of course. I don’t think it’s a good idea to inherit the theme classes in the custom CSS.
Are you willing to set up a copy of your application on apex.oracle.com? That way I can have a look and provide you the changes to the CSS as I would make them.
Kind regards,
Nick
LikeLike
Hi! Thank you for the excellent article…
I’m following your guidelines in apex 4.2.0, and my menu isn’t “shrinking” or “growing”. I see in firebug that it doesn’t load the javascript code (i don’ t see the .click() function after div#vertical-collapsible-nav), although i’ve put it in page Javascript and template javascript.
Any suggestions?
Thank you for your time and effords,
Nik
LikeLike
Hi Nik,
The reason your JavaScript code isn’t loaded might be caused by missing substitution strings in your page template. Make sure you included #PAGE_JAVASCRIPT# somewhere in your template.
Can you reproduce this issue on apex.oracle.com? Just provide me your workspace login credentials, so I can have a look at this myself.
Kind regards,
Nick
LikeLike
hi nick i am very thankfull to sharing all idea, i want to ask you how can i make this same list but it should load from table data, in same manner ,reply me
fida7733@gmail.com
LikeLike
Hey Fida,
Instead of creating a static list, you should create a dynamic list based on a database table that stores a record per navigation item. Example queries can be examined when going through the “Create List” wizard. Here is an example:
Some helpful articles:
http://vincentdeelen.blogspot.be/2013/10/dynamic-navigation-lists.html
http://www.grassroots-oracle.com/2013/05/css-pull-down-menu-using-apex-list.html
Hope that helps,
Nick
LikeLike
Thanks Nick! This is awesome. Can we use application item to store the values instead of cookies ? If yes, how this can be implemented ?
Regards,
Archana
LikeLike
Hey Archana,
In theory, it is possible to use an application item to store the state of the navigation panes. It is not the most optimal solution though. These days, it is better to use HTML5 local storage. This technique allows you to store data locally within the user’s browser. More info on local storage: http://www.w3schools.com/html/html5_webstorage.asp
Nick
LikeLike
hello! very nice article. but i have on question: how i made first level list entry clickable.to redirect in other page?
thank you in advance.
Dimitris
LikeLike
The first level entries cannot redirect to another page in this example. Their task is to expand/collapse parts of the navigation menu.
You might be interested in another sort of navigation menu:
LikeLike