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:14

Add an item to a menu after drawMenus() has been called?


Poster: udi
Dated: Monday August 23 2004 - 20:22:29 BST

Has anyone looked into a nice way to add an item to the menu using the dom after it has been rendered?

I would like a user event to result in the addition of an item to a menu on the fly without refreshing the page. For example: The user clicks on a link titled "Click here to add 'Test Menu Item' to the main menu" and this calls a javascript function that adds such an item to the milonic menu.

Has anyone attempted such a thing before? Is it possible? Is there a function similar to aI() that works after drawMenus() has been executed?

If it is possible and hasn't been done yet I think this would be a fantastic feature to add to future versions of the menu.

Thanks,
Udi


Poster: Andy
Dated: Friday August 27 2004 - 13:53:44 BST

This was done sometime ago but not much call for it so a demo was never completed.

Anyway, I've now added a small demo on how to include and use the insertItem method.

There is a sample page, with download, at http://www.milonic.com/insertitem.htm

Hope this helps
Andy


Poster: udi
Dated: Friday August 27 2004 - 21:12:38 BST

Thanks for this. I can actually see a few nice uses for the insertItem method you've posted.

But, I'm not quite sure that it is doing what I had in mind in my original post. It looks like you're calling the insertItem method before drawMenus() is called, before the menus are "committed" to the page. It's more of a convenience function for people who want to build their menus in a different order. I would like a user event (i.e. mouse click) to result in the addition of an item to an existing, rendered menu. Similar to the way you can create a new option element to add to a <select> form item on the fly using javascript and the dom. Will the insertItem method work in such a situation? If not, is there another way to do this?

My thinking is that one can use the global functions to get the menu elements by name/id. If we can get a handle to the dom element for the menu we want, can we then add a row to the table of items in that menu? Know what I'm sayin? It would be great if someone has already implemented something like this, or if the studs at Milonic could whip something up.

Thanks again!


Poster: kevin3442
Dated: Saturday August 28 2004 - 0:06:41 BST

Hi Udi,
udi wrote:
...I would like a user event (i.e. mouse click) to result in the addition of an item to an existing, rendered menu. Similar to the way you can create a new option element to add to a <select> form item on the fly using javascript and the dom. Will the insertItem method work in such a situation?...

Yes, it'll work that way too. I think the key is assigning your menu definition to a unique object name. Notice, for example, that in the insertitem_menu_data.js file, the "Partners" menu is defined as
Code:
with(partners=new menuname("Partners")){

Note the partners= part. insertItem() is then a method of the "partners" object. You can now add to the "Partners" menu by calling partners.insertItem()... call it however you like, including from a user event. For example,
Code:
<a href='javascript:partners.insertItem("text=New Item;url=http://www.whatever.com/;",2)'>click to add "New Item" to "Partners" menu</a>

would make a link that, when clicked, would add an item called "New Item" to the "Partners" menu, in position 2.

Haven't played with it extensively enough to know for sure, but if the menu in question has already been displayed (or if it's an alwaysvisible "main" menu), you might have to apply BDMenu() after the call to insertItem() to sort of rebuild the affected menu.

Hope that helps,

Kevin


Poster: Steven_Rosburg
Dated: Saturday August 28 2004 - 1:55:13 BST

Kevin,

I've been playing with this and, as you surmise, once the menu is drawn the first time it does not appear to be altered with successive calls to insertItem(). I tried calling BDMenu() as you suggest, but I get errors. Can you give an example of that?

Thanks and regards,
Steve


Poster: kevin3442
Dated: Saturday August 28 2004 - 4:05:01 BST

Hi Steve,

I played with it some and found two possibilities: (1) You can wrap the insertItem() function in your own, and call BDMenu() inside of that. But that means that you'd have to independently identify the menu index for the affected menu to pass to BDMenu() (probably by first identiying the item index for the new item). To do this outside of insertItem() involves some additional manipulations, which seemed a little overkill given that the information is already available inside of insertItem(). So instead... (2) You can slightly modify the insertItem() function itself. I wouldn't normally want to mess around directly with Andy's code because... well, it isn't mine. But it seems much easier this way, so...

The insertitem.js file contains the insertItem() function. If you add the following line:
Code:
BDMenu(_mi[_inum][0]);

as the last line in the inserItem() function definition (i.e., before the closing } curly brace), that should do it.

This will work if you only intend to use insertItem() after the initial menus are rendered with drawMenus()... as is your intent I believe. If you try to use the mod before drawMenus(), as in Andy's sample, then you'll get errors and your menus probably won't appear at all. This could be solved with a third parameter passed to insertItem()... a boolean that would only call BDMenu() if true. But that entails more meddling with Andy's code, so I'll leave it for now. Maybe Andy will have some better insights after he reads the rest of this thread. (Sorry for tampering with your very cool code Andy.)

Hope that helps,

Kevin


Poster: udi
Dated: Saturday August 28 2004 - 18:41:16 BST

Kevin+Andy,

It works! This is great. Thanks a lot guys...

I'm happier about my decision to buy this menu every day.

Udi


Poster: Steven_Rosburg
Dated: Saturday August 28 2004 - 21:47:06 BST

Kevin,

Works for me too... many thanks!

If you remember my original example, the ui.jsp page is processed and rendered in the browser first, and then the Search.jsp page is processed afterward, updating the contents of the ui page via DHTML.

Because my application is stateful, I need to rebuild the menu every time Search.jsp loads, because the URL submitted by a menu item needs to reflect the current search state. This requires me to be able to dynamically remove all menu items and add new ones.

For example:
1. ui.jsp is loaded and rendered -- empty "Main Menu" created and drawMenus() called.
2. Search.jsp is loaded and updates contents of ui page via DHTML. Menu items and submenus are created dynamically and added to main menu.
3. User performs search, thus activating Search.jsp to update the ui page via DHTML to reflect the new search state.

Obviously, you've already demonstrated how to add a menu item after drawMenus() has been called using the insertItem() method. Can you also add submenus and items to the submenus?

For example: suppose the ui.jsp page constructs an empty main menu, then calls drawMenus(). When Search.jsp loads, I need to draw the following menu:

Main Menu
----Epson
--------Stylus C66
--------Stylus C84
--------Stylus C86
----HP
--------Inkjet cp1700
--------Inkjet 2300
--------Inkject 9600

Then, suppose the user selects "Stylus C66". At this point Search.jsp is activated, and a new menu needs to be presented:

Main Menu
----Ink
--------Can the printer still print if an ink cartridge is empty or not installed?
--------I installed new ink cartridges and the printer is now doing continuous cleaning cycles. Is this normal?
----Paper and Other Media
--------How can I stop the printer from feeding multiple pages at the same time?
--------The printer won’t feed paper. What should I do?
----Print Quality and Appearance
--------My printouts are missing color and/or black print. What should I do?
--------The quality of my printed output is unacceptable. What can I do to improve it?
----Software

However, since the ui.jsp page is not reloaded, I need to be able to remove all menu items and submenus from "Main Menu", and then add the new menu items and submenus.

Does what I'm suggesting sound possible? If so, that would make this the perfect menuing system and I would be truly in yours and Andy's debt.

Thanks and regards,
Steve


Poster: udi
Dated: Sunday August 29 2004 - 22:19:55 BST

I'm with Steven on this one. If there was also a way to delete a menu item, that would be quite helpful as well.

Thanks again,
Udi


Poster: kevin3442
Dated: Friday September 3 2004 - 1:19:35 BST

Hi udi and Steve,

The following quote is from a different thread, copied here for completeness.
In a different thread, udi wrote:
...The other piece to this puzzle is of course the ability to remove a menu item dynamically as well.

I'm looking for a menuName.deleteItem(index) and a menuName.deleteAll() function would be nice to have as well (or at least help me find out how to get the number of items in a menu so I can loop through them).

Is something like this possible? Judging by the insertItem() code, I dont' think it should be too difficult. If I had a copy of the unobfuscated javascript menu code I could probably figure it out on my own, but it's one big jumble of text at the moment...


There's a lot to consider in these requests. I do have a function that I made to remove individual menu items programatically, but I did it quite a while ago, just fooling around, when I was trying to understand the menu system's internal structure. I have never really used the function for any practical purpose. Having said that, here's the function:
Code:
function mm_removeItem(menuName, itemName)
{
  menuName = menuName.toLowerCase();
  for (var i=0; i<_mi.length; i++)
    if (_mi[i][1].replace(/\&nbsp\;/ig,' ') == itemName && _m[_mi[i][0]][1] == menuName) break;
  if (i == _mi.length) return;

  var idx = 0;
  newItemArr = new Array();
  for (var j=0; j<_m[_mi[i][0]][0].length; j++)
    if (_m[_mi[i][0]][0][j] != i)
      newItemArr[idx++] = _m[_mi[i][0]][0][j];
  _m[_mi[i][0]][0] = newItemArr;

  BDMenu(_mi[i][0]);
}

There are two parameters:

(1) - menuName is the name of the menu you want to remove the item from (not the name of the menu object, but the name of the menu, as usually given in quotes in the first line of the menu definition). This is not case sensitive.

(2) - itemName is the name if the item you wish to remove, as given in the text= property used in the aI() string when you defined the item. This is case sensitive.

Now, this function works very differently from the insertItem() function Andy provided. His function completely rebuilds the menu item array. My approach was simply to "mask" the item within the named menu. In other words, the item is still in the menu item array, but it is no longer recognized by the menu. I strongly suspect that the two approaches will not be compatible for repeatedly removing and inserting menu items. For that, similar approaches should probably be taken for both inserting and removing (and Andy's approach would be best if you intend to do alot of inserting and removing, or mass inserts and removals). That said, feel fre to play around with this function and see if it works for your particualr needs.

I would suspect that the approach Andy took in his insertItem() function could fairly easily be modified for removing an item. But I don't have much more time today to have a look at it... maybe tomorrow. If we're lucky, Andy will have already thought of it and may chme in with a handy removal function that he's already made!

Another thought I have on this is that I don't know if this insert/remove an item one at a time would be a very efficient approach to completely rebuilding a menu. Seems to me that sort of thing would be better accomplished by dynamically building the menu from a database through server-side scripting. Is that something that you can do Steve? (I should probably re-read your posts to reacquaint myself with your particular goals.)

Final comment: I have no idea about dynamically removing and/or creating entirely new menus. I would think t could be done, but have never messed around with it. Could be an interesting puzzle for later if I can find the time.

Hope some of this helps,

Kevin

Status


Poster: udi
Dated: Thursday December 9 2004 - 13:13:03 GMT

Hi Guys,

I thought I'd bump this topic back up to see if any progress has been made on this request. I suspect that a number of people could benefit from add/remove functionsi that work dynamically. It would open up a large number of possible uses for the menus.

So, if there is any news on this, please let us know.

Thanks!
Udi

It's been a while...


Poster: Steven_Rosburg
Dated: Tuesday February 8 2005 - 8:26:58 GMT

Kevin,

I put the project I was working on the shelf for a while, but the need is still here, as Udi states. No, I cannot use an approach which only hides an item, because my menu will just continue to grow every time I rebuild it.

I cannot use a data-based approach to rebuild the menus in this case. I'm quite proficient with JSP, so rebuilding the menu every time the page is loaded is no big thing, since you start with a clean slate. However, I'm working with an MVC paradigm where the controller updates the view completely via DHTML. Therefore, the page is never unloaded, it's contents are simply modified via DHTML based on the action performed. This approach may sound crazy, but it is used to provide a skinned appearance which doesn't have the UI flicker normally present when submitting a form.

So, as Udi so aptly mentioned, something along the lines of deleteItem(item) and deleteAllItems(void) would be very helpful.

Thanks,
Steve


Poster: kevin3442
Dated: Tuesday March 8 2005 - 6:16:30 GMT

Hi Steve,

Don't know if you're still interested in this thread, but I just came across it again while doing something unrelated. Sorry I sort of forgot about it before. Since our original discussion, Andy created a file called mm_menueditapi.js which will probably do what you wanted (insert and delete items dynamically). You'll find a brief discussion here, along with a link to download the file. Look at the comments at the top of the file for instructions on using the functions.

Hope you can use it,

Kevin


Poster: Steven_Rosburg
Dated: Tuesday March 8 2005 - 6:20:52 GMT

Kevin,

Thanks for the update, this is very helpful information.

Regards,
Steve


Poster: kevin3442
Dated: Tuesday March 8 2005 - 6:25:23 GMT

WOW! That was fast!

;)

Kevin