• If you are citizen of an European Union member nation, you may not use this service unless you are at least 16 years old.

  • You already know Dokkio is an AI-powered assistant to organize & manage your digital files & messages. Very soon, Dokkio will support Outlook as well as One Drive. Check it out today!

View
 

Menubar

Page history last edited by Jörn Zaefferer 10 years, 9 months ago


type:
 widget

release: ?

status: in development on ice

documentation: n/a

demo: http://view.jqueryui.com/menubar/demos/menubar/default.html

 


TODOs:

  • Rename "menuElement" option to "menus" to match naming in Menu
  • Rename icons.menu to icons.dropdown 
  • Make the managed focus sticky: When focus returns to a menubar, the last focussed item gets focussed again.
    • See also keyboard/focus handling for tab/shift-tab below.  
  • Disable items/menus with class="ui-state-disabled"  
  • Add refresh method 
    • See method description below
  • Revert the menu modifications and remove the popup widget from the branch (or completely)  
  • Add a demo ala Wordpress admin menubar: http://bassistance.de/i/40afad.png 

 


 

1 - Description:

 

A horizontal menu with nested vertical flyout menus for each menu item. Wraps the menu widget (which has a lot more links to existing plugins and other references).

 

A relevant reference is the whatwg html spec on menus.

 

Accessible Mootools has a DropMenu that's an equivalent of the menubar.


 

2 - Visual Design:

 

See E2:

 

 

 


 

3 - Functional Specifications/Requirements:

 

Options:

  • items (Selector, default: "li" ) 
    • Which elements to use as top-level items inside the menubar
  • menus (Selector, default: "ul" ) 
    • Which elements to use as nested menus under the top-level items. Will also be forwarded to Menu's menus option.
  • icons (Object, default: { dropdown: "ui-icon-triangle-1-s" } ) 
    • Has a single property "dropdown". This class gets added to any top-level item that have a submenu.
    • Set the menu property to something else for custom icons, or set the icons option to null to disable icons.
  • position (Object, default: { my: "left top", at: "left bottom" } ) 
    • Where to position the dropdown menus. 

Methods:

  • refresh
    • Equivalent to Menu's and other widgets refresh method
    • When new elements are added to the menubar element, calling refresh will add the right classes and event handlers to those element. This also takes care of cleaning up when elements are removed, if necessary.

Events:

  • select
    • Same select event as the one in Menu.

 

Keyboard/focus handling:

  • Cursor left/right: If no menu is open, focus just moves from one top-level item to the next. If there's a menu open, cursor right might open the active's menu submenu, while cursor left would close it. If a menu is open and the next item has a menu, moving to that item opens the next item's menu. When the next item doesn't have a menu, the previous menu is closed. When then moving to another item with a menu, that menu opens.
  • Cursor up/down: If the active item has a menu, that menu is opened. If its already open, focus is moved within the menu.
  • Escape: Closes the active menu, if there is one.
  • Tab/Shift-Tab: Moves focus to the next or previous focusable element. Must be outside the menubar. To move focus within the menubar, use the other keys as described. When moving focus back to the menubar, the item that had the (managed) focus last will receive it again.

 

Not supported:

  • The menubar doesn't support a vertical display, since ARIA requires menubars to be horizontal. The equivalent of a vertical, hover-activated menubar can be achieved by just using an inline Menu.

 

 

4 - Markup & Style:

 

4.1 Initial markup examples 

     Any unordered list:

          <ul>

              <li><a href="/http://google.com">Google</a></li>

              <li><a href="/http://yahoo.com">Yahoo</a></li>

              <li><a href="/http://msn.com">MSN</a></li>

              <li><a href="/http://ask.com">Ask</a></li>

              <li><a href="/http://aol.com">AOL</a></li>

</ul>

 

     For nested menus, nested unordered lists:

          <ul>

              <li><a href="/http://google.com">Google</a></li>

              <li><a href="/http://yahoo.com">Yahoo</a></li>

              <li><a href="/http://msn.com">MSN</a>

                    <ul>

                         <li><a href="/htp://sub1.example.com">sub-level</a></li>

                        <li><a href="/http://sub2.example.com">sub-level</a></li>

                    </ul>

               </li>

              <li><a href="/http://ask.com">Ask</a></li>

              <li><a href="/http://aol.com">AOL</a></li>

</ul>

 

4.2 Recommended transformed HTML markup

TODO

 

4.3 Accessibility recommendations

 

ARIA markup:

Use the following roles:

  • role="menubar" for menubar <ul>
    • role="menu" for submenu <ul> elements
    • role="menuitem" for (sub)menu items *
      • role="menuitemradio" and role="menuitemcheckox" for checkable menu items
    • Role="presentation" for menuitem containers that are not needed in the exposed accessible menubar structure* 


Use the following states:

  • aria-expanded="true/false" for branch menu items
  • aria-hidden="true/false" for submenus
  • aria-activedescendant="<id of active menuitem>" to track focus
  • aria-labelledby="<id of parent menu item>"

 

* Support for ARIA menubars by screen readers such as JAWS is erratic at best, specifically in internet explorer. It seems support is more consistent when placing the role="menuitem" element adjacent to its submenu, as opposed to nesting the submenu inside the menuitem element (which is what regular nested html lists do). Because of this it's recommended to set role="presentation" on the <li> element and role="menuitem" on the <a> element inside of it.


To associate submenus with their parent menu(bar) items we need an aria-labelledby attribute on the submenu elements that point to the ID of the parent menu item. The downside is that you would have set ID values on those menu items, which would also conflict with the ID value bring added and removed by the menubar's  aria-activedescendant attribute. An easier solution would be to use the aria-label attribute, which just takes the submenu's accessible name as a string. The downside there is that IE does not support this attribute yet. The other option is to add the submenu's name as a title attribute, which works on all browsers and does not requires IDs. But of course the downside there is that you get unwanted tooltips as a side effect.


Keyboard navigation

In general the menubar needs to behave like in a desktop environment. It should be possible to use the left and right arrow keys to open the adjacent sub menu in the bar. It should also be possible to navigate the menubar items sideways without automatically expanding their sub menus (unless the current menubar item was already expanded).

 

Optionally, there could be a shortcut to move focus to the menu from any point in the web application. Selecting an item in the menubar should ten attempt to move focus back to where it was when the menubar shortcut was triggered

 

High contrast support

The sub menu indicators as well as checkable indicators must be visible in high contrast mode.

 

4.4 CSS & Theme

TODO

 

 


 

5 - Latest version of plugin:

 

http://view.jqueryui.com/menubar/demos/menubar/default.html

 


 

6 - Open issues being discussed

 

  •  n/a 

 

 

Comments (Show all 41)

JohnHadj said

at 9:08 am on Oct 11, 2011

In the second example, it seems that the submenu doesn't close when an item from the dropdown is selected. IE9. Is that by design?

Dalia said

at 7:14 pm on Nov 9, 2011

I know this plugin still in development however I can not wait I already used it, but can you please help me how to activate or make the click on the menu bar items (buttons) work, I mean the horizontal items not the sub menus. Also there is a bug, if the menubar item does not have sub menu and you hover, you get error "Uncaught TypeError: Cannot read property 'nodeType' of undefined". Also for the menuIcons I asked above, this should be easy to implement, IMHO when creating the sub menus, looping through the menubar elements and if the element/button has a children then add the icon otherwise no.

Dalia said

at 7:48 am on Nov 10, 2011

Not sure if this is correct or not, I tried this :

$('.ui-menubar-link').unbind("click");

and it solved the menubar items click issue. I still have the issue with the error "Uncaught TypeError: Cannot read property 'nodeType' of undefined" when you hover on
menubar items without submenus. Please help

Dalia said

at 12:48 am on Nov 11, 2011

One more issue, the menus links color are completely not shown or white on most ui themes, the menus of the menubar gets their colors from the ui-widget-header a of the menubar and therefore its colors not the same as the reset of menus, normally the header color is inverted so the header is dark and text is light. I think the sub menus should be wrapped with some container or should not inheret the bar header classes. Any suggestions.

Dalia said

at 1:43 am on Nov 11, 2011

Simple fix I did for the above error, I checked the menu length before opening after line about 98:
if (menu.length == 0){
return;
}
that._open( event, menu );

Eric H said

at 11:29 am on Dec 28, 2011

>Should menubar allow top-level regular links, without submenus?
Yes. They're needed to support icon bars as a variety of this widget.

Jovan Popovic said

at 10:55 am on Jan 27, 2012

Currently menu bar does not allow external links because event.preventDefault(); is called in the function that handles click event.
This can be avoided if in the event handler we check whether the input has href attribute other than "#" and in that case skip further processing - something like this:


input.bind("click.menubar focus.menubar mouseenter.menubar", function (event) {

...
//If user has clicked on the external link do not prevent default behaviour
if (event.type == "click" && $(this).attr("href") != "#")
return;

event.preventDefault();
...

Optionally can be checked whether the input.tagName is "A" or something else.
This works for me (I can put top navigation link with href="#" for internal, and other values for external links) but I'm not sure is there anything else that could be affected b this change.

hmua2012 said

at 5:54 am on Mar 20, 2012

Hello everybody:

I'm just using this menu for my applications, but I find two problems to work fine:
1. How can i delay the collapsing time? I think it is very quickly.
2. I have a long vertical menu, then i cant see whole menu because the navigator window is shorter (height) than the menu. How can i add a scroll vertical bar to let acces all menu?

Thank you very much.

Dalia said

at 6:54 pm on May 19, 2012

I come up with solution to remove the icons for buttons without submenus, I hope some one improve the code, :

// remove menubar icons from buttons without sub menus
$('.ui-menubar-link').each(function(){
if ($(this).next().length == 0){// if it has ul menu
$(this).children(".ui-icon-triangle-1-s").remove();//remove the icon span
}
});

Please post a better code to perform the same task until this feature is implemented in the menubar plugin.
Thanks

Dalia said

at 7:20 pm on May 19, 2012

I was too fast in posting, after you remove the icon, the space is still left and the button text not centered, to remove this space, this updated code is:

// remove menubar icons from buttons without sub menus
$('.ui-menubar-link').each(function(){
if ($(this).next().length == 0){// if it has ul menu
debug($(this));
$(this).children(".ui-icon-triangle-1-s").remove();//remove the icon span
$(this).removeClass('ui-button-text-icon-secondary').addClass("ui-button-text ui-button-text-only");
}
});

dave_25 said

at 2:52 pm on Sep 7, 2012

In a project I am working on and the demo for menubar, the sub-menus are not accessible on iPad or iPod (assuming also the case for iPhone). However, they are functional on droid devices.

When I try to select the submenu, I get the following in the log dialog box: Selected: Encoding Auto-detect UTF-8 UTF-16 Option 1 Option 2 Option 3 Option 4

Also note, the functionality works in the menu.ui with the horizontal menus, but not in menubar.

Charles P. Collins IV said

at 4:47 pm on Nov 13, 2012

What is the correct approach to take to enable top-level links? In my opinion this is necessary functionality, available to be incorporated into almost every horizontal menu since suckerfish.

Does anyone have a draft or work in progress to enable this?

Jörn Zaefferer said

at 7:10 am on Nov 14, 2012

In the demo above, the "About" item is a top-level link, pointing at "#about". Is that not what you're looking for?

Charles P. Collins IV said

at 7:15 pm on Nov 14, 2012

No. The use case would be using menubar for navigation in lieu of a suckerfish style menu.
Please see the fiddle here for an example: http://jsfiddle.net/PZa5G/3/

This is not the most robust way to handle this, but it details this use case and works as desired for desktops and iPad / iPhone users. The second example (with the autoExpand: true) emulates the behavior of a traditional navigation menu, and still has usability in iPad devices, but fails on my android device. It only fails in the second example in the above fiddle. When autoExpand is not true, the behavior is correct - - first touch on top-level link opens the menu, second changes the location to that link.

The desired behavior would be for desktop users to be able to open the menu on hover (autoExpand) and for touch users to have a similar experience with the second touch on the top-level link changing the location. Of course this would have to be extended in the icon use case for the user to be able to both change the location OR close the menu, depending on their choice.

Scott González said

at 8:24 pm on Nov 14, 2012

There's an unfortunate dichotomy between web and desktop style controls. For example, navigation menus are extremely common on the web, but don't really exist on the desktop. Unfortunately, web-style controls aren't always easy, or even possible, to expose to the accessibility APIs provided by the OS if they don't have an equivalent on the desktop. Do you have examples of desktop menubars that behave this way?

Charles P. Collins IV said

at 8:49 pm on Nov 14, 2012

Sorry, I meant "desktop" as in non-touch device users, standard Firefox, Chrome, IE, etc with a mouse. Poor language choice on my part.

Scott González said

at 7:54 am on Nov 15, 2012

No problem, I wasn't confused by your earlier comment. I'm pointing out that the type of menu you're referring to is web-specific and therefore doesn't have an ARIA equivalent. I'm asking if you know of *any* desktop menus that behave this way.

Charles P. Collins IV said

at 9:17 am on Nov 15, 2012

No good examples come to mind. The closest I can think of to this type of behavior would be with Mozilla Thunderbird, though that is more of a menu / icon-menu arrangement. The "Get Mail" button triggers an action, and the icon next to it drops the menu (which has "Get all messages", "Account 1", "Account 2"), the "Write" button triggers an action, the icon lists "Message", "Task", "Event" as more specific actions.

This "split button" type menu described above is pretty common, such as in firebug and greasemonkey (to enable / disable or drop the menu for options). I suppose it is really just a clever way of designing two different UI elements though.

My current use of this is web only.

NordLeuchte said

at 4:25 pm on Nov 26, 2012

I wonder if this component targets both desktop (mouse pointer, non-touch) and touch devices, because this is not mentioned in the specs or TODOs.
I experience a strange behavior using Chrome or Firefox on my Android tablet. It sometimes requires two taps to open a menu, the first one only causes a focus on the menu button.
Also, is it possible to open a sub-menu with a touch device? Using the demo, I can't manage to open the View/Encoding sub-menu. Instead, a select event occurs and the menu closes. Is there any configuration option/switch to change this behavior? (I tried removing the anchor and just leaving the text node, but that didn't work.)

Jörn Zaefferer said

at 10:54 am on Nov 27, 2012

So far only the interaction branch is getting tested with touch events, everything else isn't. Commitment to supporting all touch-based devices is a big deal. That said, you're welcome to track down the problem at hand here, or even send a PR against the menubar branch.

Ethan Gruber said

at 9:32 am on Jan 8, 2013

Is it possible to change the orientation of the menu to right-aligned for right-to-left languages such as Arabic?

nttaylor said

at 12:03 am on Feb 5, 2013

Is there a good way to disable top-level menu elements that also turns off/overrides their "mouseover" handlers? Just adding class="ui-state-disabled" fades out the element, but hovering over it still sprouts the submenu if one is defined.
For example, in the demo code if I add class="ui-state-disabled" to the <li> element that directly contains "<a href="#Edit">Edit</a>", hovering over "edit" still brings out the "copy"/"cut"/"paste" submenu. Is there something more I shold be doing?

Jörn Zaefferer said

at 4:17 am on Feb 5, 2013

Menu supports disabling items by adding class="ui-state-disabled" in the markup. We should extend Menubar to do the same.

sgharms@... said

at 3:21 pm on Apr 14, 2013

I believe bullets 1,2,4 can be deleted now.

Alastair said

at 12:23 pm on Jun 7, 2013

I honestly found the delay jarring and thought it was broken until I tested it again...but that futher supports configurability.

Currently it's hard-coded to on line 79 via `this.closeTimer`: http://view.jqueryui.com/menubar/ui/jquery.ui.menubar.js

Marv said

at 9:23 am on Jun 11, 2013

I am using menubar at http://www.innseason.com/isr with jQuery 1.10.1 and jQuery UI 1.10.3. I have added some javascript to auto click the menubar item with first mouseover and close the menus on mouseleave. IMHO, both of these options should be part of the plug-in. Moving the mouse off the submenus should automatically close them.

juan.lanus said

at 11:07 am on Jun 11, 2013

Usability view:
The first comment, and other within the set, ask for a delay in the collapsing of the menus.
What is really needed is a delay for the opening.
Consider the following use case:
1- The user has opened the Edit menu (in "Latest version of plugin" above). The mouse pointer is at the top of the "E" in "Edit".
2- Suddenly she decides to click something located where the word "here" is in the text below.
3- She calculates the optimal path (considering Fitt's law) and moves the pointer over a straight 45° line down and to the left.
4- The mouse pointer briefly hovers the "File" menu element.
5- The "File" menu opens.
6- The user ends up clicking "Save", breaking an important file, and gets fired.
This is solved with a 100ms delay of the menu expansion, as provided by the hoverIntent plugin.
The issue is more dramatic when the menus are expanded by the mere hover. Auto expansion is desirable, but then a user traveling ths mouse pointer from the page header to the content area, that briefly hovers the menu bar, might get surprising results.
Also, this happens to expert users, who look at a point in the screen and go for it without much thinking. Novice users (not computer-savvy) have to think each single step and have a chance to not click the wrong target, but they also get the chance to notice the sudden unexpected menu expansions and hate the UI and its authors up to and including their plugin providers.

SirFizX said

at 12:12 am on Jul 20, 2013

Have you implemented your own easing function for the opening and/or closing? If so, I'd be interested to see your code. I think animation/easing options should be declarable in the menubar constructor.

Justin said

at 12:56 pm on Jun 13, 2013

Slight bug found using different themes. The text colour is practically the same as the background in some states especially when using Cupertino. The text and highlight colours of the menus are not the same as the colours on the menu widget.

Justin said

at 5:54 am on Jun 14, 2013

BUG FIXES

LINE 212 : focus: function(){
CHANGE TO : focus: function(event){

LINE 217 : focusout: function(){
CHANGE TO : focusout: function(event){

Spartak Timchev said

at 6:05 am on Jun 14, 2013

Bug in the themes is because the background of the menu bar is with "ui-widget-header" class. The background should be put in separate element behind the others. Same "isolation" from ui-widget-header class should be made to the menu bar text, and to submenus.

The "button" and the "icon" options should not depend on each other also. Now we cannot have a menubar with icons and without buttons.

I have corrected version of the menubar without these bugs. Please tell me where to upload it for you, because it is a bit old.

Justin said

at 6:47 am on Jun 14, 2013

Anywhere or just email it to me (click my name and it will reveal my email address.

Thanks

Justin

Django said

at 8:39 am on Oct 1, 2013

Can you share your version ??

Spartak Timchev said

at 7:28 am on Jun 14, 2013

IMHO the default "smoothness" theme is not good for CSS debugging - it hides many bugs which can be seen in other themes. I always test with 5-6 themes when I do something.

Can anybody tell me where to upload corrected version for the corrections to be included in the next release? I am making these corrections for a third time already - every time a new version is released. :)

Richard D. Worth said

at 8:00 am on Jun 14, 2013

Spartak - To submit a change you'll need to fork the jQuery UI repo at https://github.com/jquery/jquery-ui/ and eventually create a pull request. There are a few other steps in-between, detailed at http://contribute.jquery.org/code/

LukeS said

at 4:47 pm on Jul 11, 2013

Why has he menubar been removed from all development road maps? http://wiki.jqueryui.com/w/page/12137947/FrontPage AND http://wiki.jqueryui.com/w/page/12138038/Roadmap ?

TJ VanToll said

at 7:33 am on Jul 12, 2013

@LukeS: We haven't abandoned it, we're just focusing on other things on the moment. We're looking for people to help out with its implementation if you're interested.

Django said

at 8:24 am on Oct 1, 2013

When used different theme than the default, Hover on menu items does not render ui-state-focus properly.
I have created a Fiddle , where you can compare original menu hover with menubar hover.
Can someone suggest a quick fix for this ?
http://jsfiddle.net/bababalcksheep/pKHTc/

Jörn Zaefferer said

at 6:56 am on Nov 15, 2013

From a review I did halve a year ago:

* having non-menu items is bad. Adds a lot of complexity.
* Does it really make sense? In the adminbar demo it does, but is that an "ARIA menubar"? Or just a fancy collection of links?
* Goes back to "websites vs webapps"?
* why do we need the closeTimer, e.g. inside focusin/out handlers? Why make closing async?
* Having anchors as top-level non-selectable items is bad
* Get rid of that when/while getting rid of anchors inside menu?
* top-level items should be able to consist of icons, or icons with text
* ala <span class="ui-icon ui-icon-document"></span>
* for touch devices, use a fastclick to open menus, the 300ms delay is bad
* implement the feature/bug ticket to open submenus when clicking their parent item, otherwise its impossible to open submenus with touch

juan.lanus said

at 9:45 am on Nov 20, 2013

Jörn, I loosely related some items in your comment with a usability problem this newspaper has:
http://www.lanacion.com.ar/
It is not possible to mouse from the heading (for example from "Ingresar" = log in) to a feature in the page body without opening a dropdown and if you pre-planned the click on something near the top you end up clicking a menu item you didn't even had a chance to see.
A delay is due there (as those of the hover intent plugin). IMO 300ms is too much, it only has to be enough time for the pointer to fly about 1cm, 40 or 50ms is enough.
Good if the menubar implements intelligence out of the box for not opening immediately.

Closing doesn't pose this same problem. But animating the closing is good for the user else it happens so fast that the user has the "hey, what happened!?" reaction, feels a loss of control.

You don't have permission to comment on this page.