Milonic provide full featured pull down web menus for some of the worlds largest companies
click here to see what it can do for you

Download Milonic DHTML Menu
Buy Milonic DHTML Menu

Back To Start Of Archive
Taken From The Forum: Help & Support for DHTML Menu Version 5+
Forum Topic: Click to view post
Last Updated: Saturday July 14 2012 - 06:07:57

openonclick troubles


Poster: aaronz
Dated: Tuesday January 18 2005 - 17:41:47 GMT

Alright, I'd say thus far my experience with the menuing system has been quite pleasant and I am impressed. However, I'm running into a bit of a problem that may prevent my employers from choosing Milonic as our menuing solution, which would be unfortunate as I am a fan already.

Anyway, our goal is as follows:

The top menu should function such that submenus do not open until an item is clicked. Once a click has occurred, that submenu should not close unless another item on the top menu is clicked, even if the mouse cursor travels away from the menu and returns.

In case one finds it difficult to visualize this scenario, let it be known that the top and submenus are both horizontally oriented, stacked on top of each other. Both menus appear left justified in the browser.

It would also be preferrable, although not necessary, to have a certain item on the top menu be selected by default upon page load, and thus the appropriate submenu should be visible as well.

The problem is simple, but has proven difficult to solve:

Setting openonclick=true on the top menu, and keepalive=true on the submenus produces the following results:

The submenus do not display until an item in the top menu has been clicked, which is good. However, once a submenu is displayed, mousing over any items in the top menu will close this submenu, which is not good.

I have tried writing customized javascript routines to accomplish this goal, but I have not had any success as of yet. Any guidance would be much appreciated. Thanks!


Poster: kevin3442
Dated: Tuesday January 18 2005 - 19:44:27 GMT

Hi,

It would be a great help if you could post a url to a test site that demonstrates your approach so far. Can you do that?

Kevin


Poster: aaronz
Dated: Tuesday January 18 2005 - 20:08:03 GMT

kevin3442 wrote:
Hi,

It would be a great help if you could post a url to a test site that demonstrates your approach so far. Can you do that?

Kevin


Hi Kevin,

Thanks for the response. You can see what I've done so far at the link below. Ignore the menu at the top right-- the part I'm referring to is at the bottom of the header. Thanks again.

http://www.input.com/_milonic/index.cfm

Aaron


Poster: evanadelman
Dated: Wednesday January 19 2005 - 22:35:49 GMT

hi - i have a very similar problem (and would like a similar fix!) I'm in a vertical orientation, but it shouldn't be too different of a fix.

here's my structure:

menuitem1
---submenu1item1
---submenu1item2
menuitem2
---submenu2item1
---submenu2item2

Now, if I click menuitem1, submenu1 comes out which is good. But, as soon as I mouse over menuitem2, submenu1 hides and submenu2 shows, which is not what I want. I want submenu1 to wait until I CLICK menuitem2. I'd like to stop submenu1 from hiding until either the whole menu closes (mouse out of the whole menu or click outside) or until I click another menuitem.

Thanks for any guidance.
Evan


Poster: Ruth
Dated: Thursday January 20 2005 - 3:22:56 GMT

evanadelman wrote:
hi - i have a very similar problem (and would like a similar fix!) I'm in a vertical orientation, but it shouldn't be too different of a fix.


Actually, your fix is much different and much easier. Since you are using a vertical layout, I suggest you use the treemenu which does exacty what you want. http://www.milonic.com/treemenu/ Ignore the part about the treemenu.js is at 1. something now, you would need to download the treemenu.js module plus download the other files.

AARONZ -- As for what you want, right now the menu has an automatic mouseover feature which closes submenus automatically if another item in the main menu is moused over. I've asked if it's possible to disable that and I've been told that a 'tabbed' style menu is in the works and on the way. Other than that, the only thing I can think of is some kind of function that would shut that off which I don't know is possible, furthermore, I do not know how to do functions. :(

Ruth


Poster: kevin3442
Dated: Thursday January 20 2005 - 6:20:36 GMT

Hi Aaron,

Here comes one of my really long posts... ;)

Sorry it took me so long to get back to you... been pretty busy. And thanks for posting a test url. That makes it much easier to see what's happening and to envision your description of what you want to happen.

Ruth is correct in that, even with openonclick and keepalive set, the menu automatically closes when you mouse over another main menu item. As far as I can recall, it didn't used to work that way, but it was many builds ago that I played with those properties. In any case, what you have is the current build and it's always best to work with the current build. Don't know if the "tabbed style" that Ruth mentioned will eventually help or not, but in the mean time...

aaronz wrote:
I have tried writing customized javascript routines to accomplish this goal, but I have not had any success as of yet. Any guidance would be much appreciated.

I've whipped up a little function that I think will help you. But before I get to that, I'd like to make a few general suggestions:

(1) I see that all of your js menu code is embedded in the page. That's understandable if you're generating the menus at run time from a database (I see that you're using .cfm). But if the menus are static, you might want to consider moving the code for your menu styles and your submenus into a .js file (leaving your "Top Menu" and "Main Menu" embedded in the table cells). Whether you move the code into a .js file or leave it all embedded, there are a couple of other things you should do:

(2) You don't need a call to drawMenus() after the menu style definitions.

(3) All of your submenus are embedded in a table cell. Some browsers will probably object to that (screwy positioning mainly). You don't really need those submenu definitions in a table cell, since that will not affect their positioning. You'd be better off moving the submenu definitions out of the table cell and into either (a) the embedded script block that currently contains your menu style definitions (in which case you will need a call to drawMenus() at the end), or (b) a menu_data.js file.

OK... now on to the function stuff. Here's some js code that should let you do what you want to do. I normally put such functions at the top of my menu_data code, where the menu's global variables are set.
Code:
var menuNumToClose = -1;

function adjustSubmenus()
{
  var menuNumToOpen = getMenuByName(_mi[_itemRef][3]);
  _m[menuNumToOpen][7] = 1;
  if (menuNumToClose > -1 && menuNumToClose != menuNumToOpen) menuDisplay(menuNumToClose, 0);
  menuNumToClose = menuNumToOpen
}

You would call this function with the clickfunction property of the aI() string, for any "Main Menu" item that opens a submenu. For instance, the first "Main Menu" item in your example (the "Federal" item) would be defined as follows:
Code:
aI("text=  Federal  ;showmenu=Federal;clickfunction=adjustSubmenus()");

Here's what happens: The global variable, menuNumToClose, keeps track of the currently open submenu (if any). The actual opening of the submenu is still handled by the menu system. That way, we can still take advantage of the openonclick property and _menuOpenDelay, and we don't have to worry about submenu positioning. But each time you click a "Main Menu" item, the adjustSubmenus() function is called. First, the function figures out which submenu is supposed to be opened from the item that was clicked. Then the function sets that submenu's alwaysvisible property to 1 (true would also work). That way, the submenu will remain open (alwaysvisible) until the function closes it. Next, if a submenu is already open, and if the click is supposed to open a different submenu (i.e., you clicked a different Main Menu item), then the function will close the currently open submenu.

A few things to note:

(1) When the function determines that it should close a submenu, then the submenu will close, even though we set its alwaysvisible property to 1 (a nice feature of the menuDisplay() method).

(2) This approach essentially replaces the keepalive property, so you should probably remove the keepalive property from all of your menu_data code.

(3) Since we're using the alwaysvisible property to keep a submenu open, submenus will no longer close when you click anywhere outside of the open menus (as they normally do).

(4) Because the submenu is converted to an alwaysvisible menu when it opens, the only way that it'll close is if you click on a Main Menu item other than the one that opened it.

I tested this function (using your test page locally) with IE6 and NS7.1 in WinXP and it worked the way you want your menus to work (or at least the way I think you want them to work... it's late). You may want to test in other browsers that you want to target.

Jeez... I can sure ramble on when it's getting late. I suppose I could've just posted the code and said "do this and this". But since you seem to be interested in custom code for a particular effect, I figured I'd explain the logic behind it. I hope it made sense.

aaronz wrote:
It would also be preferrable, although not necessary, to have a certain item on the top menu be selected by default upon page load, and thus the appropriate submenu should be visible as well.

Hmmm... My fingers are getting tired! How about you give the above a try. If that works for you, then we can tackle this issue next (if you still want to).

Hope that helps,

Kevin


Poster: aaronz
Dated: Thursday January 20 2005 - 14:59:41 GMT

kevin3442 wrote:
Sorry it took me so long to get back to you... been pretty busy. And thanks for posting a test url. That makes it much easier to see what's happening and to envision your description of what you want to happen.
No worries, thank you for your response. The help is much appreciated.

kevin3442 wrote:
(1) I see that all of your js menu code is embedded in the page. That's understandable if you're generating the menus at run time from a database (I see that you're using .cfm). But if the menus are static, you might want to consider moving the code for your menu styles and your submenus into a .js file (leaving your "Top Menu" and "Main Menu" embedded in the table cells).
The menus are indeed dynamic, unfortunately. Not in the version you viewed, but the subsequent ones that have the actual menu structure in them are generated based on XML-structured data.

kevin3442 wrote:
(3) All of your submenus are embedded in a table cell. Some browsers will probably object to that (screwy positioning mainly). You don't really need those submenu definitions in a table cell, since that will not affect their positioning. You'd be better off moving the submenu definitions out of the table cell and into either (a) the embedded script block that currently contains your menu style definitions (in which case you will need a call to drawMenus() at the end), or (b) a menu_data.js file.
Well, since the menus are indeed to be generated dynamically using a recursive algorithm, it presents the circumstances that it is much easier to generate all of the menus at once, including the main one. If I want the main menu to be positioned relative to a certain table, but the rest of the menus are simply relative to the main menu, is there a way to generate them all at once in an embedded script above the html at the bottom and then reposition the main menu such that it is "relative" to that specific table?

kevin3442 wrote:
Here's what happens: The global variable, menuNumToClose, keeps track of the currently open submenu (if any). The actual opening of the submenu is still handled by the menu system. That way, we can still take advantage of the openonclick property and _menuOpenDelay, and we don't have to worry about submenu positioning.
I actually wrote something rather similar to this, although not quite. It caused the menu to flicker a lot, so I'm hoping your code will not. I will give it a shot and see how it works.

kevin3442 wrote:
Jeez... I can sure ramble on when it's getting late. I suppose I could've just posted the code and said "do this and this". But since you seem to be interested in custom code for a particular effect, I figured I'd explain the logic behind it. I hope it made sense.
It most certainly did. Thank you for your thorough explanation!

kevin3442 wrote:
Hmmm... My fingers are getting tired! How about you give the above a try. If that works for you, then we can tackle this issue next (if you still want to).
Sounds good... thanks again! I'll respond shortly once I give this a shot.


Poster: aaronz
Dated: Thursday January 20 2005 - 19:18:02 GMT

Alright, well that certainly helped a lot... it definitely made the menus work as intended. However, we also wanted the items in the main menu to remain selected after they are clicked, which proved quite daunting, although through some seriously convoluted techniques, I managed to pull it off. I'm going to include my modified version of your adjustSubmenus() routine below which I have commented thoroughly to explain why I'm doing such bizzare things. If you can think of an easier or less roundabout way of accomplishing this, let me know, because I've only tested this in IE6 thus far, and I'm sure it won't work in everything.

Code:
      // next submenu to close
         var menuNumToClose = -1;
      // last clicked menu item
         var lastClickedItem = -1;
      
      function adjustSubmenus() {
         // For clicked item, replace offclass attribute with 'clicked' style to make it appear to stay selected.
            _mi[_itemRef][54] = 'MAIN_CLICK';
         // Identify submenu to be opened.
            var menuNumToOpen = getMenuByName(_mi[_itemRef][3]);
         // Set alwaysvisible parameter to true on submenu.
            _m[menuNumToOpen][7] = 1;
         // If necessary, close currently open submenu.
            if (menuNumToClose > -1 && menuNumToClose != menuNumToOpen) menuDisplay(menuNumToClose, 0);
         // Turn 'off' previously selected menu item.
            if (lastClickedItem > -1 && lastClickedItem != _itemRef) {
               /* itemOff() does not seem to perpetuate manual changes to onclass
                  and offclass attributes.  However, itemOn() does. Consequently,
                  the following convoluted routine must take place: */
                  
               // For reasons cited above, set onclass to 'off' style.
                  _mi[lastClickedItem][53] = 'MAIN_OFF';                  
               // Set offclass back to 'off' style.   
                  _mi[lastClickedItem][54] = 'MAIN_OFF';         
               // Use itemOn() function to 'turn off' the previously clicked item.
                  itemOn(lastClickedItem);
               // Set onclass back to 'on' style.
                  _mi[lastClickedItem][53] = 'MAIN_ON';
               // Use itemOff() function to ensure Milonic regards lastClicked item as being off.
                  itemOff(lastClickedItem);
               // Use itemOn() function to ensure Milonic regards clicked item as being on.
                  itemOn(_itemRef);            
            }
         // Set lastClickedItem to clicked Item.
            lastClickedItem = _itemRef;
         // Set next submenu to close to the submenu opened above.
            menuNumToClose = menuNumToOpen;
      }   


I will post the most recent changes to the following test url so you can see the progress. This one is including dynamically generated menus, as well.

http://www.input.com/_milonic

Thanks again!


Poster: aaronz
Dated: Monday January 24 2005 - 14:33:20 GMT

Just wondering if anyone has any further information regarding this subject.. thanks :)


Poster: Andy
Dated: Monday January 24 2005 - 14:58:49 GMT

Hi,

Can you please try the Pre Release version of the menu at http://www.milonic.com/menuvinfo.php

There are some changes to the way onclick and keepalive work.

Cheers
Andy


Poster: aaronz
Dated: Tuesday January 25 2005 - 20:42:07 GMT

Quote:
Can you please try the Pre Release version of the menu at http://www.milonic.com/menuvinfo.php

There are some changes to the way onclick and keepalive work.


Unfortunately, I did not find that the changes made a difference with respect to the problems that I was trying to correct with the large subroutine in the above message. However, I've found that the subroutine does work properly in Firefox, Netscape 7.x, and IE 5.5+, so that's good enough for now, I believe. I think what I really need is a tabbed-style menu. Thanks.

Aaron