This post is the third in a series of tutorials exploring the steps necessary to build custom navigation menus in Oracle APEX. The first tutorial I wrote explains how you can create a jQuery accordion-like menu. In the second tutorial, I created a vertical collapsible menu in combination with a cookie mechanism to remember the state of each panel. These two menu types suffer from one serious restriction: the menu depth level is limited to a two-level hierarchy. The navigation menu in this article, however, supports an infinite depth level. This is how the end result looks like: demo.
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>)
<ul class="multiLevelMenu">
- Template Definition > List Template Current
<li> <a href="#LINK#"> #TEXT# </a> </li>
- Template Definition > List Template Current with Sublist Items
<li class="hasSubMenu"> <a href="#LINK#"> #TEXT# <div class="right-arrow"></div> </a> </li>
- Template Definition > List Template Noncurrent
<li> <a href="#LINK#"> #TEXT# </a> </li>
- Template Definition > List Template Noncurrent with Sublist Items
<li class="hasSubMenu"> <a href="#LINK#"> #TEXT# <div class="right-arrow"></div> </a> </li>
- Before Sublist Entry > Sublist Template Before Rows
<ul class="multiLevelMenu subMenu">
- Sublist Entry > Sublist Template Current
<li> <a href="#LINK#"> #TEXT# </a> </li>
- Sublist Entry > Sublist Template Current with Sublist Items
<li class="hasSubMenu"> <a href="#LINK#"> #TEXT# <div class="right-arrow"></div> </a> </li>
- Sublist Entry > Sublist Template Noncurrent
<li> <a href="#LINK#"> #TEXT# </a> </li>
- Sublist Entry > Sublist Template Noncurrent with Sublist Items
<li class="hasSubMenu"> <a href="#LINK#"> #TEXT# <div class="right-arrow"></div> </a> </li>
- After Sublist Entry > Sublist Template After Rows
</ul>
- After List Entry > List Template After Rows (for example)
</ul>
Step 2: create and populate your navigation list
Create a list based on the list template we created in step 1 and include all navigation entries specific to your application. Remember that there is no limit whatsoever on the depth level.
The image below shows you a part of the list entries that I used for the demo:
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: the CSS
Here’s how I styled my navigation menu in the demo:
/* first level menu */ ul.multiLevelMenu { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 13px; line-height: 24px; list-style: none; background-color: #FFFFFF; width: 180px; border: 1px solid #444444; padding: 3px 0; -webkit-box-shadow: 0 5px 8px rgba(0,0,0,0.5); -moz-box-shadow: 0 5px 8px rgba(0,0,0,0.5); box-shadow: 0 5px 8px rgba(0,0,0,0.5); } div.right-arrow { display: inline-block; position: absolute; top: 50%; right: 8px; border-top: 3px solid transparent; border-bottom: 3px solid transparent; border-left: 3px solid #444444; margin-top: -3px; } ul.multiLevelMenu li { position: relative; } ul.multiLevelMenu li:hover { background-color: #3892FD; } ul.multiLevelMenu li a { display: block; padding-left: 6px; color: #444444; text-decoration: underline; cursor: pointer; border-top: 1px solid transparent; border-bottom: 1px solid transparent; } ul.multiLevelMenu li a[href=""] { text-decoration: none; } ul.multiLevelMenu li a[href=""]:hover { cursor: default; } ul.multiLevelMenu li:hover > a { color: #FFFFFF; text-decoration: underline; border-top: 1px solid #2A6DBD; border-bottom: 1px solid #2A6DBD; } ul.multiLevelMenu li:hover > a[href=""] { text-decoration: none; } ul.multiLevelMenu li:hover > a div.right-arrow { border-left: 3px solid #FFFFFF; } /* sub level menus */ ul.subMenu { display: none; } .showSubMenu { position: absolute; top: -4px; left: 180px; }
Step 5: include the hoverIntent jQuery plugin
The hoverIntent jQuery plugin is used to improve the usability of the navigation menu by introducing a short delay whenever the user unintentionally unhovers from a sub menu. Download the plugin here. Upload the jquery.hoverIntent.minified.js file as a static file in shared components and include it on your page(s) or page template.
#WORKSPACE_IMAGES#jquery.hoverIntent.minified.js
Step 6: the jQuery code
// global variables var subMenuHoverConfig = { over : showSubMenu, timeout : 150, out : hideSubMenu, sensitivity : 15, interval : 150 }; // functions function showSubMenu() { var subMenu = $(this).children("ul.subMenu"); subMenu.show(); subMenu.addClass("showSubMenu"); } function hideSubMenu() { var subMenu = $(this).children("ul.subMenu"); subMenu.hide(); subMenu.removeClass("showSubMenu"); } // page load $(function() { $("ul.multiLevelMenu li.hasSubMenu").hoverIntent(subMenuHoverConfig); $("ul.multiLevelMenu a[href=\"\"]").click(function(event) { event.preventDefault(); }); });
Put the above code in a file and upload it as a static file. Include it on your pages, just as you did for the hoverIntent jQuery plugin.
#WORKSPACE_IMAGES#multi-level-nav.js
Reblogged this on Christoph's 2 Oracle Cents.
LikeLike
I have followed this great post but when I hover over my menu, I do not see the sublist items.
I have loaded the jquery, css and js files into my workspace and refer to them in my page template
LikeLike
Hard to say what went wrong. Do you see JavaScript errors in the console of your browser?
LikeLike
I believe the problem is with the step 6. I saved the code to a file and called it mulit_level_nav.js and uploaded to the shared components.
Firebug show 2 errors, ReferenceError: jQuery is not defined, ReferenceError: $ is not defined.
Also if I click on the file mulit_level_nav.js, I get Microsoft JScript rumtime error line 24
LikeLike
It looks like the jQuery variable is undefined at the moment you reference the hoverIntent plugin. You have to use apex.jQuery instead of the regular jQuery variable.
Edit the jquery.hoverIntent.minified.js file and replace jQuery with apex.jQuery in the last line of code. That should fix your problem.
LikeLike
Changed the code in the jquery.hoverIntent.minified.js file, but still not working.
Now I am getting javascript errors:
ReferenceError: apex is not defined
ReferenceError: $ is not defined
LikeLike
Ahh, crap… It looks like the execution order of your JavaScript code is messed up. Are you using a custom theme or have you modified your theme page templates? Is it possible to import your application on apex.oracle.com? This way I can have a look at your code.
LikeLike
Workspace: GUSCRIGHTON
Username: ANGUS.CRIGHTON@HAVILOG.COM
Password: terminator
Application: 40867
Page: 81
Thanks
LikeLike
Fixed. The problem was you included the above JavaScript code, which uses jQuery, before the jQuery variable ($) was defined. That explains your JavaScript errors. Have a look at your page template.
LikeLike
Thank you very much for all your help.
I have a couple more questions.
1. How do I change the colour to red, when you hover over the menu.
2. How to display the menu across the top of the page, instead of down the page
Thanks
LikeLike
Worked great for me, thanks
LikeLike
How would I modify this to get the items to display in the similar fashion of the article “Creating a vertical collapsible navigation menu”? I cannot use the hover feature due to handicaps. I have the requirement for users to be able to click.
LikeLike
I have included an extra navigation menu in my demo application that works with click events instead of hovering. Check out the following page: https://apex.oracle.com/pls/apex/f?p=19914:75
Download the demo application under the “Downloads” tab and have a look at page 75. All implementation details can be found there. https://apex.oracle.com/pls/apex/f?p=19914:1
LikeLike
Hi!
Great Work.
Just a little thing when the page gets loads I want my sub list should come in collapsed form.
What can be done for this?
Thank you in advance!
LikeLike
Hello,
I’m afraid I don’t understand your question. The sub list items in the navigation menu are always collapsed after page load. You have to hover over a menu item to display its sub menu items.
Nick
LikeLike