Dynamic menuing - one solution...
Category Technical
Bookmark :
Awhile back I asked about dynamic menuing options for Domino. I got a couple of good suggestions, but I just couldn't find exactly what I wanted. Well, since then my client and I decided that we wanted to have all submenus be floating, out to the right. However, we still want the menus to be dynamic, and to allow the first level to be graphics or text.
I did a ton of research looking for a solution. I decided that I wanted the solution to be as simple and lightweight as possible, and that if possible I wanted it to "degrade" gracefully, such as when there isn't a CSS available. I wound up going with the solution found at CSSCreator, here. This solution uses <UL> and <LI> tags to build the menus, and then CSS and a teeny bit of Javascript to control the functionality and appearance of the menu. I took this example, and then "Domino-ized" it to make it data driven. The result is shown below:
Because I used the <UL> and <LI> tags, it degrades pretty well, looking like this:
I like the way this works, and the tags aren't complicated at all (review the CSSCreator link from earlier). Now, let's take a quick look at how I coded this in Domino, and let me tell you about a small problem I found - and how I got around it....
Design Overview
First, let me say that I used the Javascript from the CSSCreator site verbatim, except for one minor modification for a kludge (which is explained later). I also took the CSS as a basis for mine, and then modified it fairly heavily to get my menu to appear as I wanted.
Since I wanted this to be dynamic, I initially wanted to do this from a view; however the structure of the tags just doesn't lend itself to using a view. So, then I decided to use a couple of cached lookups, to make sure I add the third level of menus where appropriate. Since this is Domino 6.x, I have the luxury of using @For to make this job pretty simple. Now, I thought about posting the code here and going through it, but it is pretty specific to this solution (I may build a generic version for download later). Instead let me tell you in pseudocode what I did, and why.
First, I have a DBColumn that pulls in the first level of the menu. In those documents I have stored the image names used for this level, and the text title (which is used as the ALT tags for the images). I then have a @For loop that walks each first-level item, builds the tag code, and then does a DbLookup to check for second-level items.
Now, you are probably balking at the fact that I am doing recursive lookups - I did when I first thought of it too. But follow me on this train of thought: I really have two choices - do a DbColumn and then use something like Trim/Replace or something similar to get the right second-level items for each first-level item; or do a cached DbLookup when needed in the code. I decided to go with the DbLookups for a couple of reasons. First, the code itself is much easier to read because I don't have that extra processing. Second, I am returning much less data for each lookup, which keeps me from any lookup limits. Finally, because I am using cached lookups the "hit" for the lookup is greatly minimized - and from tests I did it didn't cost me any speed in this instance because we're not talking about huge data sets.
OK, so we are doing DbLookups to pull in the second level items. Then we walk them (just like we walk the first-level items), build the appropriate tag code, and then do a cached DbLookup for the third level items, performing the exact same work as the earlier levels.
The Compulsory Kludge
This solution is FAST. I am extremely pleased with the performance. But I did run into one small issue. just to the right of the menu is a combobox (or a SELECT field in HTML speak). Those of you who have to code for IE know that comboboxes/SELECT boxes completely ignore the z-index in IE, which means that they show "through" any layer that goes over them. This is a PITA, and can make an otherwise elegant solution really ugly in IE. But there's hope. I found a great workaround here at WebReference.com. Basically the workaround is this: in your Javascript code that makes the submenus appear you add a line of code that hides the combobox/SELECT field. That line of code looks like this:
if (document.getElementById("SomeFld")) {document.getElementById("SomeFld").style.visibility = "hidden"};
Notice that I used an if statement to make sure the field is there - I did this because my combobox may or may not be there, as it is also data-driven. You add this line to the part of the javascript code that makes the submenu appear; you also need to add the following line of code in the javascript that causes the submenu to hide:
if (document.getElementById("SomeFld")) {document.getElementById("SomeFld").style.visibility = "visible"};
There is one other trick to keep in mind when using a solution like this. It seems that <UL> elements are indented from the left margin quite a bit by default; so if you want your menu to line up on the left, you need to move it over in your CSS style using a negative value in the margin-left property - for me a value of -20px seemed to do the trick.
Conclusion
There just doesn't seem to be a completely clean, elegant, and totally dynamic way to do menus in Domino - but this solution is close enough to be satisfactory for my needs. Hopefully you can learn a thing or two from this to make menu building in your own applications easier as well.
As always, comments are welcome.
Rock
**ASCII stupid question, get a stupid ANSI.









Blog Roll










Comments
It often takes our most experienced people spending serious time and effort, to drag us all as an industry back to where we took the wrong turns. Nice work.
-Andrew
Posted by Andrew Pollack At 10:22:30 AM On 08/15/2004 | - Website - |
for a solution without JS you could take a look at this page: http://www.meyerweb.com/eric/css/edge/menus/demo.html
Unfortunately this doesn't work in IE
To remove the indentation from the ul-Tags you could also remove the padding
#ul {padding: 0;}
Posted by Thomas Voelk At 12:17:07 PM On 08/15/2004 | - Website - |
1. it is not or may not be clear where you are in the drop down scenario. I do not clearly know how you got to "Key Documents", which can be frustrating for the end user.
2. I would also suggest replacing the graphics at the top level with CSS formatted text. You could then use CSS for moueover, click and select events to keep the menu "breadcrumbs" clear to the user. This would also make the degradation cleaner (i.e. not having a bullet in front of an image).
Looks like you were having some fun with this one! And I bet I can guess where the client is based on spelling
Posted by Christopher Byrne At 08:23:33 PM On 08/15/2004 | - Website - |
I've been looking for the same functionality and your tips are a huge help. Perhaps you could donate the finished examples as a demo DB to Sandbox or OpenNTF.
You also bring up something that I encounter daily: there isn't any easy way to do some "standard" web features in Domino. I lose quite a few projects to the ColdFusion team at work because of this. In the case of dynamic menus they looked at the requirement and said "no problem, there's a custom CF tag for that". They had it done before I could start. Granted there are other times when Domino wins for the same reason.
Thanks for the pointers
-Ed
Posted by Ed Maloney At 08:25:06 AM On 08/15/2004 | - Website - |