There are plenty of options for this, including a number of jQuery plugins, but here is an example that uses only CSS
http://www.lwis.net/free-css-drop-down-menu/ultimate.horizontal.html
This makes it lightweight and fast.
It's easy to implement this as a list template in APEX, enabling you to source your menu from a SQL query (possibly on your page meta-data) or a static list.
You might have seen this in the past as a Sumneva presentation from Scott Spendolini, which somehow I found after encountering the LWIS site - but it did confirm a few gaps for me. It also provides a good review of Tabs vs jQuery vs CSS.
I personally had a few issues implementing this as described, but I think there are some minor bugs during the rendering if list templates.
The following example renders it fine.
Upload supporting files
Upload the following files to your workspace - downloadable here under MIT/GNU licence.default.css
default.ultimate.css
dropdown.css
Or place them in your fileserver - whichever is appropriate.
You'll also need these images (in this example, anyway)
grad1.png
grad2.png
nav-arrow-down.png
Note no JavaScript files required.
Create list template
Create new list template from scratch (don't be scared!)Name: CSS Horizontal Dropdown Menu
Class: Pull Down Menu or Custom n -- either would be worthwhile
Once created, edit the template and enter the following in the relevant locations, or download the template export from here and adjust the supporting file locations accordingly.
Before List Entry
"List template before rows"
Here you'll need to modify the CSS location as appropriate. In fact when loading things into the APEX workspace, default.css also needs to be included here and the @import command removed from default.ultimate.css
Likewise, the CSS needs to be modified so all the supporting images are referenced using something like
background-image: url(http://www.lwis.net/free-css-drop-down-menu/images/default/nav-arrow-down.png);
unless you come to other arrangements.
<link href="#WORKSPACE_IMAGES#default.css" media="screen" rel="stylesheet" type="text/css" />
<link href="#WORKSPACE_IMAGES#dropdown.css" media="screen" rel="stylesheet" type="text/css" />
<link href="#WORKSPACE_IMAGES#default.ultimate.css" media="screen" rel="stylesheet" type="text/css" />
<div id="navwrap">
<ul id="nav" class="dropdown dropdown-horizontal" style="margin-bottom:10px;">
<style>
ul {
list-style-type: none;
}
#navwrap {
float:left;
width:100%;
margin-bottom:4px;
background:#f6f6f6;
border-style:solid;
border-color:#d9d9d9 #d9d9d9 #d9d9d9;
border-width:1px 1px 1px 0;
}
</style>
This also includes an override for the user agent stylesheet for unordered lists, otherwise you see bullet points instead of images.
The navwrap ID settings pushes the menu across the width of the page.
Template Definition
"List template current"
<li><a href="#LINK#">#TEXT#</a></li>
"List template current with sublist items"
<li><a style="color:black;" class="dir">#TEXT#</a><ul>
"List template non current"
<li><a href="#LINK#">#TEXT#</a></li>
"List template noncurrent with sublist items"
<li><a style="color:black;" class="dir">#TEXT#</a><ul>
Before Sublist Entry
"Sublist template before rows"
<!-- I don't believe this renders with dynamic lists!
this is why the opening UL is in the definitions above -->
Sublist Entry
"Sublist template current"
<li><a href="#LINK#">#TEXT#</a></li>
"Sublist template current with sublist items"
<li><a href="#LINK#" class="dir">#TEXT#</a>
"Sublist template noncurrent"
<li><a href="#LINK#">#TEXT#</a></li>
"Sublist template noncurrent with sublist items"
<li><a href="#LINK#" class="dir">#TEXT#</a>
After Sublist Entry
"Sublist template after rows"
</ul></li>
After List Entry
"List template after rows"
</li></ul></div>
Prepare menu hierarchy
Before defining the region that renders the list, you need a list defined - this will be your hierarchical menu. This way it can either be a static list where you manually define the menu options, or it could be a query over your application's meta-data.
In this example I'll use a dynamic query - but before creating your list, we need to prepare the hierarchy.
I defined a few Page Groups to be my menu headings, and the allocated pages will live under the relevant drop down.
Application Builder -> Utilities -> Cross page utilities -> Page groups
Page group allocation |
Create List
Now we've prepared the meta-data, we can create a list based on a query that our list region will use.The query is structure in three parts -
- Home link - often identified by page alias of HOME, but you could get clever with this.
Once I embedded this into the template itself, allowing me to parameterise a logo as the home link via substitution strings
<li > <a href="f?p=&APP_ID.:HOME:&SESSION." style="padding:0 5px;"> <img src="&TEMPLATE_LOCATION.logo_&APP_ALIAS..png" style="max-height:26px;"/> </a></li>
- Top menus - by default this are links, but I've modified these to just facilitate opening the menu - particularly for mobile devices where your finger is used instead of a mouse hover.
- Drop down options - the destination pages for your menu
select -- Link to home page 1 lvl ,page_name label ,'f?p='||:APP_ID||':'||page_id||':'||:APP_SESSION||'::'||:DEBUG target ,null is_current_list_entry ,null image ,null image_attribute ,null image_alt_attribute ,page_alias order1 from apex_application_pages ap where application_id = :APP_ID and page_alias = 'HOME' -- identify however you like union all select -- Menu options, don't link anywhere to aid touch devices 1 lvl ,page_group_name label ,'#' target ,null is_current_list_entry ,null image ,null image_attribute ,null image_alt_attribute ,page_group_name order1 from apex_application_page_groups pg where application_id = :APP_ID union all select -- drop down menu options - pages belonging to groups 2 lvl ,page_title label ,'f?p='||:APP_ID||':'||page_id||':'||:APP_SESSION||'::'||:DEBUG target ,null is_current_list_entry ,null image ,null image_attribute ,null image_alt_attribute ,page_group order1 from apex_application_pages ap where application_id = :APP_ID and page_group is not null -- you may limit this to set groups, allowing further management of utility pages, popups etc order by order1, lvl,labelIf you find the menu not displaying in the hierarchy you expected, check the order by. It should group results as you might translate to the menu - all the relevant menus together, and the top menu is the first record of each group.
Create list region
Create your global page (page zero) if you haven't done so already. This is the perfect place for your menu's list region.Create a new list region in the global page, with the display point appropriate for your particular template. I chose region position 1. The region requires no template, but you use the List Template you just created.
You will also need to ensure the menu doesn't appear on pages that don't require it - logon, popups, etc. So make sure your region condition is appropriate. To start with it might be
:APP_PAGE_ID != 101
Remove tabs
Now that you have a CSS menu system in place, you can now remove the tab list that may have previously supported your pages. You might be able to make one change, depending on how you've managed your page templates. This could be modifying the Page template default in your current theme from "One Level Tabs" to "No Tabs". For the theme (2) I have been using in my sample application I also needed to remove the div that housed the tab set.
CSS menu system |
It's not quite as pretty as when implemented using one of the newer themes, but still looks neat and clean. I'll have to update this in future. You may also wish to replace the pixel style down arrows to something more contemporary, less retro.
This biggest bugbear I have with this solution is it doesn't seem touch-screen friendly, despite my interpretation of assurances in the LWIS FAQ. While it drop's down, it doesn't allow me to select "Employees" using Chrome on my Samsung Galaxy III. On a Windows Latitude using IE, the drop-downs don't even open. First level selections are ok.
Open my sample application and try out the lightweight, CSS only menu. Does it work on your handheld device? |
This biggest bugbear I have with this solution is it doesn't seem touch-screen friendly, despite my interpretation of assurances in the LWIS FAQ. While it drop's down, it doesn't allow me to select "Employees" using Chrome on my Samsung Galaxy III. On a Windows Latitude using IE, the drop-downs don't even open. First level selections are ok.
Scott
ps - a few weeks after I drafted this I noticed Dutch blogger Kees Vlek posting about the same framework.
ps - a few weeks after I drafted this I noticed Dutch blogger Kees Vlek posting about the same framework.
Hi,
ReplyDeletei appreciate your work and posts.
but i have a problem with drop down menu?
i get post till to before list creation but after that i do not get any thing can you help me
to fix it please?
regards:
shtanai.
Questions like this are best asked on the Oracle APEX community forum.
ReplyDeleteScott,
ReplyDeleteYour download is broken. I am very interested in your solution.
404. That’s an error.
The requested URL /files/free-css-drop-down-menu_v1.3.zip was not found on this server. That’s all we know.
Regards,
Scott
Hi Scott,
ReplyDeleteYou sound like a great guy, I'd love to help ;p
However, I'm not sure what link you're talking about. I can't find that url on my post, nor is lwis.net my site.
I've generally moved on from this menu solution, though I still use the SQL pattern - to source menu hierarchy from apex_application_pages.