pulling the X coordinate for each item in a horizontal menu

Having problems with DHTML Menu? There is usually somebody here who knows the answer.
twesson
Advanced
Advanced
Posts: 14
Joined: Sun Feb 15, 2004 7:10 pm
Location: Chicago, IL

pulling the X coordinate for each item in a horizontal menu

Post by twesson »

Is there a way to access the X-coordinate of each item in a horizontal menu so I can line up my vertical menus appropriately?

Before you respond, please note that my horizontal menu is in one frame and my verticals are in another frame. Therefore, the nice automatic vertical menu adjustment we've all come to enjoy doesn't apply.

Also, I "have" manually aligned them but all that hard work goes out the window as soon as the menu is on a system that doesn't have the first font in my fontlist. Different font than my development system means all the vertical menus become unaligned again because the font widths all change.
User avatar
Maz
Milonic God
Milonic God
Posts: 1717
Joined: Fri Jun 06, 2003 11:39 pm
Location: San Francisco
Contact:

Post by Maz »

It sounds to me that your best option would be to use a % width so that it always fills the required size. menuwidth="50%";

Then itemwidth="100%"; to fill the required size.

This works best if you have a stretchable layout, a url might help to see, but I think this may be the best workaround.

Regards,
maz
User avatar
kevin3442
Milonic God
Milonic God
Posts: 2460
Joined: Sat Sep 07, 2002 12:09 am
Location: Lincoln, NE
Contact:

Post by kevin3442 »

I can't think of a way off the top of my head. I can get the coordinates of the menu itself, but not individual items within the menu (not to say that there isn't a way; just that I can't think of one right now). If your page layout could allow for fixed menu item widths, where you specify the width of each item, then you could extrapolate the location of any particular item from the origin of the menu containing it. Don't know if that would work for you, but give a holler if your're interested.

Another possibility would be to use images as your menu items. You could then get the x coordinate you're looking for by locating the position of the image on the page. I have played with that in the past with some success, although there may be some cross-browser issues.

Kevin
twesson
Advanced
Advanced
Posts: 14
Joined: Sun Feb 15, 2004 7:10 pm
Location: Chicago, IL

Post by twesson »

The only thing that makes me persist is this idea I have about how Milonic links horizontal and vertical menus internally so that they're always aligned with each other when used in a horz/vert configuration. It makes me think the data is somewhere just waiting to be accessed.
User avatar
kevin3442
Milonic God
Milonic God
Posts: 2460
Joined: Sat Sep 07, 2002 12:09 am
Location: Lincoln, NE
Contact:

Post by kevin3442 »

Good point. Now all that's left is to figure out where... worth poking around some. If I find anything, I'll let you know.

Kevin
User avatar
Andy
Milonic
Milonic
Posts: 3308
Joined: Sun May 19, 2002 8:23 pm
Location: Menu Developer
Contact:

Post by Andy »

Here are some internals that might be of use.

getMenuByName("menuname")
Will return the reference number for a menu.

gmobj("objname")
Will return a reference to an object, for example:

Code: Select all

myMenu = gmobj("menu"+getMenuByName("mainmenu"))
Will set myMenu variable as the mainmenus object. You can then use this to get and set properties.

To get the dimensions of a menu, use:

Code: Select all

myMenu = gmobj("menu"+getMenuByName("mainmenu"))
menuDimensions=gpos(myMenu)
This creates an array with the menu dimensions and positioning, like this:

menuDimensions[0] // Top
menuDimensions[1] // Left
menuDimensions[2] // Height
menuDimensions[3] // Width


To set the position of a menu, use spos(), like this:

Code: Select all

myMenu = gmobj("menu"+getMenuByName("mainmenu"))
spos(myMenu,10,10,200,200)
syntax: spos(myMenu,top,left,height,width)

The above aren't just for menus, they can be used for any HTML object.

Hope this helps
Andy
User avatar
Maz
Milonic God
Milonic God
Posts: 1717
Joined: Fri Jun 06, 2003 11:39 pm
Location: San Francisco
Contact:

Post by Maz »

This is some kind of foreign language :lol:

Kevin,

Could you put into a little script for those of us who don't get it?

Regards,
maz
User avatar
John
 Team
 Team
Posts: 5967
Joined: Sun May 19, 2002 8:23 pm
Location: Phoenix, AZ
Contact:

Post by John »

Javascript. I believe it's in the South Seas someplace (i.e., foreign...) :roll:
John
User avatar
kevin3442
Milonic God
Milonic God
Posts: 2460
Joined: Sat Sep 07, 2002 12:09 am
Location: Lincoln, NE
Contact:

Post by kevin3442 »

maz wrote:This is some kind of foreign language :lol:

Kevin,

Could you put into a little script for those of us who don't get it?

Regards,
maz
:) Hmmm... it's already in a script, but maybe it's somewhat scriptic... uh cryptic ;) . These are functions that are defined in the menu scripts, but the function names are abbreviated for, well, brevity (shorter function names = faster download)! Please allow me to unabbreviate... in this case, gmobj() means "get menu object", gpos() means "get position" of said menu object, and spos() means "set position" of said menu object.

Using the internal gmobj() and gpos() funcitons was actually what I had in mind to get the coordinates of a menu. But I think tweeson wants the coordinates of menu items within a menu; and I still don't see how to get that, but then I haven't had much chance to poke around.

Kevin
User avatar
Ruth
 Team
 Team
Posts: 8763
Joined: Thu May 15, 2003 5:02 am
Location: Yucaipa, CA
Contact:

Post by Ruth »

oh my.... I actually understood what Andy wrote :o

Ruth
User avatar
kevin3442
Milonic God
Milonic God
Posts: 2460
Joined: Sat Sep 07, 2002 12:09 am
Location: Lincoln, NE
Contact:

Post by kevin3442 »

innkeeper9 wrote:oh my.... I actually understood what Andy wrote :o
Now you've let the cat out of the avatar! Time to start coding with javascript! ;)

Kevin
User avatar
Ruth
 Team
 Team
Posts: 8763
Joined: Thu May 15, 2003 5:02 am
Location: Yucaipa, CA
Contact:

Post by Ruth »

:lol: I can understand the words in a medical book on brain surgery, doesn't mean I can do it.

But, a question. You said
Using the internal gmobj() and gpos() funcitons was actually what I had in mind to get the coordinates of a menu. But I think tweeson wants the coordinates of menu items within a menu; and I still don't see how to get that, but then I haven't had much chance to poke around.
Now, wouldn't you be able to get any of the menus and set their position with that.? It seems if you got the 'main' menu, got it's dimensions, set it's position, then you should be able to get any of the others the same way, by their name, get their dimensions and set their position based on the info you have with regard to the 'main' menu dimensions and position?

Ruth
User avatar
kevin3442
Milonic God
Milonic God
Posts: 2460
Joined: Sat Sep 07, 2002 12:09 am
Location: Lincoln, NE
Contact:

Post by kevin3442 »

Hi Ruth,

You make a good point. But there's more to the equation I think. Part of it has to do with this question (which goes back to the original): How exactly does the menu system know, internally, where to open a submenu when it comes time to do so? If the position of a submenu is known beforehand -- before the user mouses over the calling menu item -- then you could figure out where to open a submenu by essentially getting the coordinates of where it's already destined to open. But I doubt that the menu works that way internally (I have yet to investigate). It's more likely that the menu system waits until the user mouses over an item, then at that point figures out where the submenu should open, then opens it there. If that's the case, then it'd be instructive to figure out how the menu does that.

The problem is that the position of a submenu isn't just relative to the position of the parent menu (i.e., the main menu). The position of a submenu is relative to both the position of the parent menu and the position of the calling item within the parent menu; both of which can change as the window size changes, depending on how the site positions its main menu. So, to figure out the coordinates where you should open a submenu, you essentially have to figure out the coordinates of the menu item that opens that submenu. There might be two ways to go about it. The first would be the direct approach... get the coordinates of the calling menu item, if such coordinates are available somewhere to be gotten. I don't think that's the case (although it could be and I just don't know it). The second approach would be to calculate the coordinates of a menu item by (a) getting the coordinates of the menu containing that item (no problem), (b) summing the widths (assuming a horizontal menu) of all items preceding the targeted item (problem), and (c) adding the two together to arrive at a location for the submenu (no problem). Then you would (d) set the position of the submenu (no problem), and (e) open the submenu (no problem). The problem is part (b). Now, (b) would be pretty easy if each menu item was the same width (i.e., one itemwidth for the whole menu). It's be a little more difficult, but still do-able, if each menu item had a specified itemwidth. But I have no idea how to do it if each item's width is not set, but rather is determined by the menu itself.... where does it have those widths??? They gotta be somewhere... and now I'm probably gonna be up til the wee hours pulling out my hair (where's that smiley?) trying to figure that out! Don't you just love a good puzzle? Admit it.... I know you do. That's why you hang out here! (Also one of the reasons why I do.)

Cheers,

Kevin

P.S. Sorry for the wordiness... I tend to do that more as I get tired.
User avatar
Maz
Milonic God
Milonic God
Posts: 1717
Joined: Fri Jun 06, 2003 11:39 pm
Location: San Francisco
Contact:

Post by Maz »

I look at it as having to calculate the size of font and family, those are variable so there is no dimension to work with unless you know all font sizes.

It would make more sense to make absolute menu item sizes and absolute submenu item sizes, only then you can match them up exactly.

Then you risk a different font or size, throwing it all off.

Sorry to spoil the fun,

maz
User avatar
Ruth
 Team
 Team
Posts: 8763
Joined: Thu May 15, 2003 5:02 am
Location: Yucaipa, CA
Contact:

Post by Ruth »

Yes, I do love a puzzle, well, what I really like doing is trying to find how to fix it, even if it only leads me to finding out what is contributing to the behavior. Unfortunately, I lack any knowledge of programming language of any kind to work on the ones like this. But, enjoy reading them and seeing the solutions reached. :)

Working on the smileys in between trying to find codes and stuff.

Ruth
twesson
Advanced
Advanced
Posts: 14
Joined: Sun Feb 15, 2004 7:10 pm
Location: Chicago, IL

Post by twesson »

Maybe the question to ask Andy is this:

"How does your menu know where to position the submenus on the X-axis in a horz/vert menu combination?"

It will be interesting to hear his response on this.

Granted, this is sort of an unsupported question in a way because you really only need this kind of knowledge if you're doing a frames-based menu -- but it would still be interesting to hear his answer.
User avatar
Andy
Milonic
Milonic
Posts: 3308
Joined: Sun May 19, 2002 8:23 pm
Location: Menu Developer
Contact:

Post by Andy »

This is based on the location of the menu item.

The location of menu items is gained by viewing the dimensions of "el#".

This is where is gets VERY complicated. Each menu item is numbered from zero to whatever and the variable name is el#. The problem is knowing which number is for which menu item.

However, this is not a problem if you are looking for the currently selected menu item because you can use the global variable _itemRef.

So try:

Code: Select all

itemPos=gpos(gmobj("el"+_itemRef))
Cheers
Andy
User avatar
kevin3442
Milonic God
Milonic God
Posts: 2460
Joined: Sat Sep 07, 2002 12:09 am
Location: Lincoln, NE
Contact:

Post by kevin3442 »

Hi tweeson,

That ought to do it... the left (x) coordinate of the currently selected item can be used to set the position of the targeted submenu in the content frame before it's opened. The "get" function in the nav frame could pass the coordinate(s) to a "set" function in the content frame before the call to popup(). If you're already doing frames, I'm sure that'll be easy for you.

You could manually set the top value in all of your fisrt-level submenus to 0 (or whatever their static location in the content frame is in your design... I assume top would be static). Height and width of the submenus would be taken care of automatically by the menu, so all you would need to set when opening a first-level submenu would be the left value. One nice thing about spos() is that if you pass a null in a parameter (other than the menu object), then that setting is ignored. So, for example:

Code: Select all

spos('products', null, 325, null, null);
would set the left coordinate of the menu named 'products' to 325, leaving its natural top, height, and width alone.

Kevin
Last edited by kevin3442 on Thu Feb 19, 2004 10:28 pm, edited 1 time in total.
twesson
Advanced
Advanced
Posts: 14
Joined: Sun Feb 15, 2004 7:10 pm
Location: Chicago, IL

Post by twesson »

I'm getting an error:

'_gs' is null or not an object

//distantMenu - opens up milonic menuName inside of mainmenu_body
function distantMenu( menuName )
{
top.hidden_storage.document.form.mainmenu_vert.value="1";

strItemPos = gpos(gmobj("el"+_itemRef));
parent.frames['mainmenu_body'].spos(menuName,null,strItemPos[1],null,null);
parent.frames['mainmenu_body'].popup(menuName);
}

The menu operates without error when I comment out the line with the spos() in it.
User avatar
kevin3442
Milonic God
Milonic God
Posts: 2460
Joined: Sat Sep 07, 2002 12:09 am
Location: Lincoln, NE
Contact:

Post by kevin3442 »

Hi David,

The problem is that you are passing a menu name rather than a menu object in the call to spos(). I may have contributed to this by referring to a menu name in my previous post (now edited). Just to clarify, the first parameter in your call to spos() should be a menu object, typically the return of gmobj(), as Andy had discussed in an earlier post.

Try changing your function to this:

Code: Select all

function distantMenu( menuName )
{
  top.hidden_storage.document.form.mainmenu_vert.value="1";

  strItemPos = gpos(gmobj("el"+_itemRef));
  parent.frames['mainmenu_body'].spos(gmobj("menu" + getMenuByName(menuName)),null,strItemPos[1],null,null);
  parent.frames['mainmenu_body'].popup(menuName);
}
Kevin
Post Reply