This article demonstrates how easy it is to create your own custom jQuery Accordion-like navigation menu. Have a look at the final result in case you’re not sure what this is all about. In the end, it’s nothing more than a two-level navigation list with the same behaviour of jQuery’s UI Accordion.
Now, I’m not going to give a detailed explanation of the code I used (although the title of this blog is called apexplained). I’ll just describe the steps required and provide all the code necessary to build your own accordion navigation menu. You need a basic understanding of HTML, CSS and jQuery.
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="accordion-nav">
- Template Definition > List Template Current
<div class="is-lvl1-current"><span>#TEXT#</span> </div>
- Template Definition > List Template Current with Sub List Items
<div class="is-lvl1-current"><span>#TEXT#</span> <ul>
- Template Definition > List Template Noncurrent
<div><span>#TEXT#</span> </div>
- Template Definition > List Template Noncurrent with Sub List Items
<div><span>#TEXT#</span> <ul style="display:none;">
- 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> <script type="text/javascript"> $("div#accordion-nav div span").click(function() { $(this).parent().siblings().children("ul").slideUp(300); $(this).siblings("ul").slideToggle(300); }); </script>
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:
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 */ div#accordion-nav { width: 200px; background-color: #DDDDDD; border: 1px solid #9C9C9C; } div#accordion-nav div span { display: block; padding: 4px 5px 4px 10px; font-weight: bold; color: #222222; } div#accordion-nav div span:hover { background-color: #CCCCCC; cursor: pointer; } /* second level */ div#accordion-nav div ul { list-style-type: none; margin: 0; } div#accordion-nav div ul li { background-color: #F2F2F2; padding: 4px 5px 4px 18px; } div#accordion-nav div ul li a { text-decoration: none; color: #222222; } div#accordion-nav div ul li a.is-lvl2-current { font-weight: bold; } div#accordion-nav div ul li a:hover { color: #3E9FFF; } div#accordion-nav div ul li a img { vertical-align: middle; padding-right: 5px; }
That should do it. Give me a shout if you experience any issues.
The most important part here is the list template in step 1. It allows full control over the HTML that is being generated by APEX. The little piece of jQuery code in the template is responsible for the accordion effect.
To be honest, I only scraped the surface of what could be written on this topic. There are endless possibilities when building your own list template since you are in charge of how it’s build (HTML), how it behaves (JavaScript/jQuery), and how it should look like (CSS).
Update on 14-08-2012: modified the list template definition so that it’s possible to work with childless first-level entries.
Reblogged this on Sutoprise Avenue, A SutoCom Source.
LikeLike
Very good article! I liked! There was one question. Where to put this CSS code?
LikeLike
where to put the CSS code..?
LikeLike
Hey Karthick,
1. access the page attributes by double-clicking your page name
2. locate the “Header and Footer” section (APEX 4.2 has a separate CSS section)
3. put the CSS code in the “Header Text” text area, surrounded by style tags
In a production environment, you ideally put your CSS code in files: http://docs.oracle.com/cd/E23903_01/doc/doc.41/e21674/ui_custom_css.htm
LikeLike
Thank you very much again! I understand. Tell me whether it is possible to do so, you can open a few points?
LikeLike
Hello Alexander,
Yes, it is possible. And it is extremely easy to accomplish.
Go to the list template you created and locate the “After List Entry > List Template After Rows” region. That text area contains the jQuery code to achieve the accordion effect. You can prevent the panes from collapsing by getting rid of the next line:
$(this).parent().siblings().children(“ul”).slideUp(300);
That’s all you have to do :-)
LikeLike
ok. Thanks))) though I did it yesterday..
LikeLike
One more question, if you allow it. How to make the transition to another page open apex memorized items?
LikeLike
That’s a little more challenging. You’ll need cookies or another similar technique to remember what panes were opened. The following article on stackoverflow.com should give you a head start:
http://stackoverflow.com/questions/3890524/jquery-menu-remembering-the-state-of-the-menu
Could be a nice extra for this blog post to be honest. Thank you for the tip! ^^
Regards,
Nick
LikeLike
to be honest, I do not understand where i need to insert this text to apex. Can you help me? Thank you.
LikeLike
Alexander,
I just wrote a new tutorial in which I create a vertical collapsible navigation menu, with a cookie to remember the state of the panels.
Good luck with it,
Nick
LikeLike
I have this working but I would like to display an image aswell as text (like in your demo).
I tried putting menu/pt_all_20.png in the image attribute in the list, but no image displays.
LikeLike
Hi Angus,
try /i/menu/pt_all_20.png
Nick
LikeLike
Great blog and solutions,
Can you please make your demo app available for us to download.
I mean something similar to Roels Blog:
http://apex.oracle.com/pls/apex/f?p=22115:16:0::NO:::
LikeLike
Hey Fateh,
Good tip. I took an export of my application and made it available to download. You can download it here: http://apex.oracle.com/pls/apex/f?p=19914:1
LikeLike
in page 0 shows this menu. how to fix this error?
LikeLike
– Create a new page of type “Page Zero”
– On page zero, create a list region based on the list you defined in shared components
LikeLike
So i did.. But when i logout, on page 101(login), show this menu.. How fix this error?
LikeLike
Put a condition of type “Current Page is NOT in Expression 1 (comma delimited list of pages)” on the navigation region on page zero. Then fill in 101 in the “expression 1” text area. That’s it.
LikeLike
To be honest, I do not quite understand what you mean .. Could you explain more on
Thank you
LikeLike
Thank you. I’m mean how to do it.
LikeLike
And another question … Can I make a menu based on a database?
LikeLike
Tell me is it possible to build a menu with a table from the database? And how is it done?
LikeLike
That is possible by using a dynamic list. The minimum APEX version for this feature is 4.1. Here is a link to the official documentation: http://docs.oracle.com/cd/E23903_01/doc/doc.41/e21674/nav_list.htm#CACHABBF
LikeLike
Sorry, I’m new to the apex. and so to the end of everything else I do not understand. Could you explain to me how all the same to create a table (which headers it necessary), so that worked template “vertical-collapsible-nav” ?
LikeLike
please explain how the table should look like, and how to build a query. I will be very grateful.
LikeLike
I did it)) thank you very much Nick Buytaert!!!!!!!
LikeLike
now does not save cookies. as it is now to save them if the page “user defined attributes” is not?
LikeLike
You still need the user defined attribute of course. Just add an extra column to your table that contains the value for user defined attribute 1. Then select this column in your query and alias it “attribute1”. That should do it.
LikeLike
ok. Thank you very much.. I did it))
LikeLike
I have implemented your accordian like navigation menu. I would like to link a menu item to a report but still keep the menu items on the left sidebar. Please help.
LikeLike
So you want to display the navigation menu on every page of your application? Follow these steps:
– Create a new page of type “Page Zero”
– On page zero, create a list region based on the list you defined in shared components
– Put a condition of type “Current Page is NOT in Expression 1 (comma delimited list of pages)” on the region and include all page IDs that do not need to contain the navigation menu
LikeLike
Thank you Nick. Working as expected.
LikeLike
hi
i m using ur menu plugin can u please help me i have created the menu on page 0 the problem i m getting is the menu is collapsing after redirecting please can u guide me on this
LikeLike
Hi, is it possible to achieve the accordian effect sliding right (meaning opening the sub-menu items in a box on the right, rather than below the main menu item)? Also, I would like to automatically open the first sub-options. Essentially, I would like to have two connecting menu boxes (one for the main, and the second one to the right of it for the sub-menu) and then when you click on a different option in the main menu, the second menu changes to the corresponding child items.
LikeLike
Hey Bridgitte,
That is certainly possible. It requires, however, quite some changes to the JavaScript and CSS. I’ll create an example on apex.oracle.com and make it available to download. I’ll keep you posted.
LikeLike
Bridgitte, I published a new article in which I explain how you can create a navigation menu according to your requirements. It is not completely the same, but I hope you find it useful.
LikeLike
This was really helpfull!! Thanks!
LikeLike
Hello, I am not able to download from the above link which you had mentioned, could you please help ?
redirecting to https://www.dropbox.com/s/eclhszhduab6sxx/apexplained.sql, but it says that SSL connection error.
LikeLike
Hey there,
That’s weird. I tried downloading the file with five different browsers and didn’t experience a single problem. What browser (and version) are you using? Have a try with another browser.
LikeLike
can you help me do this in apex4.0??
LikeLike
I don’t think you need something extra in APEX 4.0 to complete this tutorial.
LikeLike
i did like above instruction but it didn’t work out.I’m new at apex so i’m having some trouble..
LikeLike
Do you have an account on apex.oracle.com? If so, upload your application there and I’ll have a look at your problem.
LikeLike
hi nick,
i really appriciate you work.
i just email you my logins for apex.oracle.com
could you kindly check it there and tell me where is the porblem?
Thank you so much nick.
LikeLike
Hello Muhammad,
I had a look at your problem on apex.oracle.com. The code itself is perfectly fine, but you forgot to define sub list entries in your accordion-nav list. This means that all your list entries are parent entries that do not have any child entries. That’s why you accordion didn’t work as expected.
Have a look at the accordion-nav list and you’ll see I created two sub list entries. The parent entry of these two sub list entries is the ‘General’ entry. Now run your application, click on the ‘General’ entry, and you’ll see appear the two sub list entries.
LikeLike
okay,
now it is working but the image icon beside the child entry is not showing.
instead a red cross is there.
i try to change another image item for it, but not working.
there is a list item from the image chooser place displaying STANDARD IMAGES.
the same list includes two more options WORKSPACE IMAGE,APPLICATION IMAGES.
when i try to select one of the last two options, then there is no image there.
do i need to copy images into WORKSPACE IMAGE,APPLICATION IMAGES?
how?
Thank you nick.
LikeLike
sorry,
but the navigition region is vast , mean it cover the whole page.
how to set it as yours, your nivigation region is small, only covering the area required for the items to be displayes in.
Regards.
LikeLike
Simply upload your images in shared components and reference them like this: #WORKSPACE_IMAGES#my_image.png
The region itself is covering the whole page. Just set “No template” in the region template select list.
LikeLike
Hi,
This is a great article and ‘how to’ but I found out that Theme 25 (responsive theme) does not support any sub lists so I have seen postings on OTN where users were even trying to implement Jquery plugin for drop down type menus and it would not work. As I understand it, you have to start with a template that supports sub lists. I have also heard that you can ‘import’ a template and use that to support this type of Jquery accordian menu. Can anyone explain how I could do that? My application was built to take advantage of responsive so I don’t want to have to switch to a totally different theme, but the import of a template sounds like a great way to do this. Unfortunately the OTN thread on this did not go ‘all the way’ and provide how to do it!
Thanks,
Pat
LikeLike
Hi, UPDATE on my posting:
I actually got this to work despite the fact I am using responsive theme 25!! Really appreciate this blog!
There is just 1 item I need help with. I am on Apex 4.2.2 and on Page 0 — I do not see where to apply the CSS. You say that in 4.2 there is a separate CSS section. I cannot seem to find it.
Thanks again! Let me know about CSS.
Pat
LikeLike
Hi,
I downloaded your demo and I see how you apply the CSS to the page, and when I apply CSS like in the demo to Page 1, it formats correctly, but if the menu list is installed on Page 0, how do you apply the CSS there for all the pages where you want the menu to show?
Pat
LikeLike
Hey Pat,
Edit the list region on page zero and put the CSS in the region header or region footer section. Use the following syntax:
Best regards,
Nick
LikeLike
Nick,
Thanks a lot! This was the best Blog I have yet seen on Apex!! I have been trying for weeks to get a drop down to work!
LikeLike
Nick,
One final question. One of my Top level menu items has no ‘sub menu’ and in the List it has a target page, since I want it to open that page. It seems the Jquery is making all the top level menus ‘inactive’. How do I change that or do I need to define a sub-menu for that even though there is no ‘real’ sublist.
Thanks,
Pat
LikeLike
Patrick,
The top level menu entries simply ignore their target page URL. That’s just the way an accordion menu works. As you suggest, you’ll have to create an extra sub list entry that links to the target page.
In case your navigation menu contains a lot of these entries, it might be better to use another type of menu. For example this one here: http://apex.oracle.com/pls/apex/f?p=19914:70
Best regards,
Nick
LikeLike
Thanks for the suggestion. I just have 1 of those so this should work for me. I’ll look at the other option as well.
Pat
LikeLike
Nick,
Can this type of menu list be placed horizontally — so top level list acts like horizontal tabs and the sub lists drop down? I tried doing this when placing it in a region and selecting a horizontal template but that does not work. Any hints to get this working would be appreciated.
Pat
LikeLike
I’m afraid that’s not possible. It’s not a good idea to turn an accordion menu into a horizontal drop down menu. Both menu types are two distinct GUI elements.
Have you seen Dan McGhan’s horizontal Navbar plugin? I think it might fit your needs: http://www.danielmcghan.us/2013/04/enkitec-navbar-now-available-without.html
LikeLike
I just ran into another issue. I added a second region with another accordian menu list and it is working very well just like the original one I created using your instructions. However, now the first accordian menu list is collapsing right after I click on the parent instead of showing the dropdown sub list menus such that I can’t even select a sub-menu item. The 2nd region accordian menu works fine. Would appreciate any help resolving this. The regions are in the same row, the 2nd region to the right of the first.
Thanks,
Pat
LikeLike
Pat,
Mhm, haven’t really thought about having two accordion menus on the same page. The problem is that the template includes a div element with an id attribute. Two menus mean two HTML elements with the same id. As you probably know, an id in HTML is supposed to be unique.
I’m afraid you’ll have to edit the HTML, CSS and JavaScript code to fix this. Replace the id attribute of the very first div in the template with a class attribute. You’ll notice a lot of references to the div element with id accordion-nav (div#accordion-nav) in the CSS and JavaScript code. Just replace “div#accordion-nav” with “div.accordion-nav”.
That should fix your problem. Give me a shout in case you experience further issues.
Best regards,
Nick
LikeLike
Nick,
Thanks. I will look into Dan’s horizontal menu and also look at working with your last suggestion.
Pat
LikeLike
Hi nick,
Great Work !
But what about three-level hierarchy ? Any possibility for this
Thanks
LikeLike
For example Inbox has sub menu too so it will be displayed below
Your efforts will be highly appreciated.
Thanks
LikeLike
Hey Shayan,
A multi-level hierarchy is not possible for this example. Refer to the following article which explains you how to create a multi-level navigation menu: https://apexplained.wordpress.com/2013/03/10/creating-a-multi-level-navigation-menu/
Kind regards,
Nick
LikeLike
I have tried to implement this menu, but when I click on a header, the accordion opens, but then straight away, it closes again.
LikeLike
I think the is a problem using it with the UILayout plugin, as it works on pages without this plugin
LikeLike
Probably some sort of collision between the UILayout plugin and the little piece of JavaScript code I wrote for the menu. You might want to play around with the JavaScript code to prevent this from happening.
LikeLike
Nick,
I had used your accordion menu described above on an application in Apex 4.2.1 and it worked great. Just text menus under the main menu items. Now after the upgrade to 4.2.4 which includes twitter bootstrap, there seems to be a ‘broken image’ icon in front of every sub-menu item–which then causes issues with the lists not being . Can you give me an idea as to where to look to remove those since I did not intend to have any ‘image’ with the sub menu items, just text menu items.
LikeLike
Hey Patrick,
Just remove the img elements in your list template. Both the Sub List Template Current and Sub List Template Noncurrent contain an img element. Simply remove the below from the sub list templates:
That should do it.
Kind regards,
Nick
LikeLike
Thanks much!
Pat
LikeLike
Nick,
Your tutorial on creating an accordion menu is great. Thanks for your time from all of us newbies. I am new to APEX/CSSS/HTML so forgive my lack of knowledge. Is there a way to reduce the opacity of the image when it is not current or hovered over? I know CSS3 has the opacity property for an img, but since the image is referenced inside a hyperlink tag in the HTML, I wasn’t sure if it could be altered by the CSS. Any help would be appreciated.
Thanks!
Rodney
LikeLike
Hey Rodney,
Reducing the opacity of the images is certainly possible, even when the image is between a hyperlink tag. Use the opacity property with a value lower than 1:
More information on the opacity property: http://www.w3schools.com/css/css_image_transparency.asp
Hope that helps,
Nick
LikeLike
Hi Nick, now moved on from the Collapsible menu to the Accordion menu.. I have a couple of issues, which Id be grateful if you could help me with???
2) I’ve got the menu on page zero.. can’t get it to stay open when I change pages.. I had this working fine with the collapsible menu..
Ive gone into the javascript code (also created on page zero as a dynamic page load action) and changed the functions from
$(“div#vertical-collapsible-nav div span”).click(function()
to
$(“div#accordion-nav div span”).click(function()
However, when I change pages, the menus collapse and I cannot open them again.. Any clues? As stated, it all works fine for the collapsible menu.. and If I don’t invoke the Javascript, then it works fine for the first page…
My other issue is a ‘look and feel’.. Ive modified the look of the menu using CSS to match the BlueJay theme.. The problem I have is that the first item of the sub menu, has no top padding, and the last sub menu item has no bottom padding… Its making the first and last menu look a bit squashed against the main menu items.. (its eactually the same on your demo).. Ive struggled for ages to change the style to add some top padding to the top and bottom padding to the bottom submenu item???? What am I doing wrong..
For ref, my style sheet looks like the following: (I also had an issue with stretching my image to fill the main menu item background by the way, which is why its set 300%…). It all looks OK except for the squashed top and bottom menu item..
Many Thanks
Richard
/* first level menu */
div#accordion-nav {
width: 192px;
border: 1px solid #888888 ;
border-radius:4px;
display: block;
overflow: hidden;
}
div#accordion-nav div span {
height: 26px;
width: 100%;
color: #444;
font: bold 13px/23px Arial,sans-serif;
padding: 5px 0px 0px 9px;
text-shadow: 0px 1px 0px #FFF;
text-shadow: 0px 1px 0px #FFF;
background-color: transparent;
background-image:url(#WORKSPACE_IMAGES#sregion5.png);
background-repeat:no-repeat;
background-size:300% 300%;
background-attachment: scroll;
background-position: 0px 0px;
background-clip: border-box;
background-origin: padding-box;
float:left;
overflow: hidden;
}
div#accordion-nav div span:hover {
background-color: #CCCCCC;
cursor: pointer;
}
/* second level menu */
div#accordion-nav div ul {
list-style-type: none;
margin: 0;
}
div#accordion-nav div ul li {
background-color: transparent;
padding: 4px 30px 4px 18px;
}
div#accordion-nav div ul li a {
text-decoration: none;
color: #222222;
}
div#accordion-nav div ul li a.is-lvl2-current {
font-weight: bold;
}
div#accordion-nav div ul li a:hover {
color: #3E9FFF;
}
div#accordion-nav div ul li a img {
vertical-align: middle;
padding-right: 5px;
}
LikeLike
Hey Richard,
It’s hard for me to help you out on this without seeing the actual code and details. Can you import your application on apex.oracle.com and grant me access? That would be the easiest way for me to help you out.
Nick
LikeLike
Hi Nick,
exellent work.But i have a problem with the images. They are show like crashed.Can you tell me a solution?
Thanks,
Adven
LikeLike
Hey Adven,
Have you uploaded the images in the Files section under Shared Components? You can reference these files by using a substitution string. Use #APP_IMAGES# for application files and #WORKSPACE_IMAGES# for workspace files.
Every child list entry has the ability to include an image. Simply enter a value for the Image setting (e.g. #WORKSPACE_IMAGES#configuration.png).
Hope that helps,
Nick
LikeLike