• 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
 

Menu

Page history last edited by Scott González 11 years, 3 months ago

 

type: widget

release: 1.9

status: released

documentation: http://api.jqueryui.com/menu/

demo: http://jqueryui.com/menu/

 

 


 

1 - Description:

 

Transforms any set of nested elements into a themeable menu with mouse and keyboard interactions for navigation.

 

NOTE: numbers in brackets reference visual designs.

 

Flat, non-hierarchical list (default when there are no nested lists)

 

  • simple menu [D1] appears/acts like a customized dropdown list.
    This is covered by the Selectmenu widget. 
  • popup menu [D8] appears/acts like a native Mac OS select list, where the the selected option appears boxed to the left of the trigger button, and the user can click either the selected option or button to open the menu.  The menu is positioned so that the selected option always appears at the same place in the list; when the menu is open, if the selected option is third from the top, you'll see the first two options above the selection, and the rest below.
    This is covered by the Selectmenu widget.  

 

Hierarchical list:

 

  • fly-out [D2 and D3], if the option is explicitly set or, as a best practice, if number of sub-levels limited to 2 or 3 (when 3+ submenus are showing,  collision detection can become unwieldy depending on the available space in the viewport).  Behaves similarly to Apple's OS menus where the main menu appears on click and sub-menus on hover; the current sub-menu remains open as long as the user's mouse is over it, otherwise it (and any other sub-menus) closes after a short delay.  The user's path through the menu is marked with an "on" state.

      

  • ipod-style/drilldown [D6 and D7], if the number of sub-levels is larger or unknown or if the option has been explicitely set.  Mimics its namesake by showing a main menu, and as you choose options that navigate to deeper levels, the next menu slides to the left into view.  By default a "back" link appears at the bottom of the menu, and when clicked, the visible menu slides to the right out of view.  Options allow the user to:
    • show a full breadcrumb in place of the back link
    • change the location of the back link (above vs. below the menu)
    • change the default back text (from "Back" to something else)
    • set default breadcrumb text (i.e., "Choose an option:")
    • select wether the menu should be context loaded, drop down or statically rendered

       

  • menubar [E2], if the option is explicitly set (not automatic detection): the top-level menu options are arranged either horizontally or vertically in a row, and sub-menus appear either below or beside them, respectively.  Sub-menus can be formatted as flat, ipod-style, or flyout.  This menu could be used as standard global navigation, or as part of a toolbar.  (The toolbar is a separate widget that groups navigation and form controls.) -> This is covered by the Menubar widget.

 

 

Split buttons

Users should have the option to create split-buttons for any menu option, where the left button selects the node and the right button opens a sub-menu.  The original design only spec'd split buttons for ipod style menu, but this could be useful to show link affordance in fly-outs as well.

 

Check and radio options

  • a check or radio option is always a leaf node, never has a child menu
  • check options can be toggled on/off one at a time; multiple check options can be selected/on in a single menu
  • radio options are like their namesake in that you can choose one from a group.  Example: EXT toolbar, "button with menu:" http://extjs.com/deploy/dev/examples/menu/menus.html
  • radio options must be visually grouped together, either in a stand-alone menu or sub-menu, or set apart from other list items with a divider
  • when one or more options has an check, radio, or custom icon, the entire menu -- parent menu plus all sub-menus -- is indented left so that the icons are easily scannable in a left "column"

 

Custom icons [D5]

Users could also specify unique icons that appear next to particular menu options.

 

Dividers

  • dividers could be specified in the original (pre-menu widget) markup as:
    • an empty list item.  The menu widget could insert a horizontal rule for vertical menus, or a vertical rule for horizontal menus (menubars)
    • a list item containing text (not linked) could be converted to a horizontal rule followed by a text label
  • dividers/labels are not clickable

 

Sub-menu indicator arrows and icon alignment [D4]

  • for vertical menus:  Arrow icons which indicate sub-menus always appear in the right column.  It may be problematic to flip the location of the arrows to the left side of the menu; doing so would only work when there are no left column check/radio icons, otherwise it may be visually noisy.  Keeping the arrow icons on the right but flipping their direction to point left may also be confusing, as the arrow would be pointing back to the list item -- has anyone seen a menu behave this way?  Using the Mac OS default behavior as a guide, it may be a safer bet to never flip the location or direction of the arrows and have them always stay in the right column and point right, which is the default direction of the menu, and reserve the left column for icons.
  • for horizontal menus (top-level menubar buttons):  An option could be set whether to show a "down" arrow to indicate sub-menus.

 

As decribed in the first paragraph, the behaviour/mode of the menu can be set to the following (the option for this is called 'mode'):

 

  • dropdown,  makes the element the menu is bound to to act like a button, therefore drops down the menu to one side of the original element (default is below, configurable via option 'direction')
  • context, appears on right-click in a specified region by default, or the user can optionally make it appear on left click or a key + click combination [any suggestions for this option?]. The direction option can be used to set how it pops up, the default is "right below".
  • static (default), simply takes the list or JSON and renders the menu statically (always visible) into the original element. If you don't specify the items option, it will search for the first ul that is a child of the selected element and transforms it automatically (this is specific to the selected mode).

 

 

One thing to consider for the grid (and many other future UI plugins) is that HTML 5 provides detailed specs for these widgets that we should seriously consider using as a blueprint for our plugins. If we shared similiar naming and conventions, it will provide a cleaner interface in the future when we all have to support both the HTML 5 version (where available) and the JS-based UI plugin verison on the same site (i.e. use the native HTML 5 if availble, fall back to JS if not supported).  The other benefit is that these specs have been refined by a large group of people so they are fairly mature and there may be no need to reinvent the wheel. There is a menu spec here:

http://www.whatwg.org/specs/web-apps/current-work/multipage/interactive-elements.html#menus

 

Many, many jQuery menu plugins already exist that we may be able to mine for ideas, or use as the basis for the jQuery widget.  Several are listed below, but there may be others that look as/more promising (feel free to add to or edit this list):

 

Single or multi-level menus (dropdown, flyout, ipod-style)

 

Context menu

 

Enhance standard <select> into menu

http://www.givainc.com/labs/linkselect_jquery_plugin.htm

 

Filament flyout and iPod menus with ARIA and CSS framework support:

http://www.filamentgroup.com/lab/jquery_ipod_style_and_flyout_menus/

http://www.filamentgroup.com/examples/menus/index.html

http://filamentgroup.com/examples/menus/ipod.php

 

iOS-Style menu build on jQuery UI 1.9's menu widget:

http://jamesarosen.github.com/jquery-ui/demos/menu/ios-menu.html  

 

Themeroller-based drilldown menu: http://www.matthewfeerick.com/jquery_menu/

 

For a very detailed description of menu design best practices and behavior, please review the Apple's UI guidelines for menus or Microsoft's Vista UI guide for menus.

 

Menubar ARIA example implementation that includes inputs: http://oaa-accessibility.org/examplep/menubar1/

Dojo/Dijit Menu, Menubar, Contextmenu: http://archive.dojotoolkit.org/dojo-2011-07-12/dojotoolkit/dijit/tests/test_Menu.html

 

Complex navigation patterns for responsive design: http://bradfrostweb.com/blog/web/complex-navigation-patterns-for-responsive-design/


 

2 - Visual Design:

 

 

 


 

3 - Functional Specifications/Requirements:

 

Keyboard

  • ENTER/SPACE - Invoke the focused menu item's action, which may be opening a submenu.
  • UP - Move focus to the previous menu item.
  • DOWN - Move focus to the next menu item.
  • RIGHT - Open the submenu, if available.
  • LEFT - Close the current submenu and move focus to the parent menu item. If not in a submenu, do nothing.
  • ESCAPE - Close the current submenu and move focus to the parent menu item. If not in a submenu, do nothing.
  • Typing a letter moves focus to the first item whose title starts with that character. Repeating the same character cycles through matching items. Typing more characters within the one second timer matches those characters. 
  • Disabled items can receive keyboard focus, but do not allow any other interaction.

 

Accessibility

  • Follow ARIA best practices for menu, with the following exceptions:
    • Starting a mouse interaction with a menu does not force keyboard focus to that menu. Therefore the recommendations concerning mixing of mouse and keyboard interactions are ignored, specifically "With focus on a menu item and a sub menu opened via mouse behavior, pressing down arrow moves focus to the first item in the sub menu." 
  • ARIA roles and states:
    • Set role="menu" on menu container (usually ul).
    • Set aria-activedescendant attribute with the value referring to the current active item's id-attribute, which, if not present, gets generated based on the menu's id.
    • Set role=presentation to surrounding elements like <li>
    • Set role=menuitem to focusable <a> items, and add aria-haspopup=true if an item has a submenu.
    • Set aria-disabled="true" for disabled menu items 
    • Set role=menu to submenus, aria-expanded=false and aria-hidden=true while its not expanded, toggle those booleans when expanding
    • When role option is set to "listbox", use "option" as role of menuitems

 

 

There is no API for binding data to each item that menu provides. Instead, jQuery's data API can be used to bind whatever necessary to each menu item and retrieve that within the select-event via ui.item. Autocomplete does exactly that.

 

Delaying opening and closing submenus

When hovering a menu item with a submenu, slightly (200-300ms) delay opening the submenu. Close open (sibling) submenus when opening another submenu.

Implementation-wise: Start a timeout on mouseover. Clear the timeout on mouseout. When it executes, close open submenu and open the new submenu.

 

Icons

Icons are supported by adding a class of ui-menu-icons to the menu element, which happens automatically when there is an element within the menu with the class ui-icon. The ui-menu-icons class adds some padding to the left to offset menu items (with or without icon). The icon generated for submenus isn't affected and will continue to be positioned on the right.

 


 

4 - Markup & Style:

 

(only used prior to implementation) 

 


 

5 - Latest version of plugin:

http://view.jqueryui.com/master/demos/menu/default.html

 


 

6 - Open issues being discussed 

 

API Challenges

 

While working on the iOS-style version of the menu, I found I needed to redefine several key methods:

  • #left - the default behavior simply hides the menu and focuses on the parent; I needed to slide the child out.
  • #_open - the default behavior shows and positions the child menu; I needed to position it, then slide it in.
  • #select - I added back links to the child lists and thus had to override #select to call #left instead of triggering a select event
  • #_startOpening - the default behavior is to show a submenu when hovering over (or focusing via keyboard navigation) its name; this doesn't work for the iOS-style menu, which relies on an active press (mouse or keyboard) to open a menu

 

In general, this can all be overcome by splitting out behavior into smaller helper methods that are configurable via options(). I rather like the SproutCore- and Cocoa style of willFoo() and didFoo() callbacks. For example, we could add a willMoveLeft(event, parent, child) and didMoveLeft(event, parent, child) callbacks. If willMoveLeft returns false, the move is cancelled. [James]

 

The jQuery UI pattern for naming cancelable and notification events (like this) is beforemoveleft and moveleft. For example, see Dialog's beforeclose and close. [Richard]

 

@James: Can you look into splitting out the internal functionality of the existing methods into smaller methods so you can just override the individual parts you care about? For example, you could move the position/show code into its own function and change that to do the positioning and sliding. You can also look at the custom tooltip animation demo (see the open event example) to see how the animations for menu might be possible even without refactoring the base menu. For the back button, can you add a header above the menu and put the back button up there? That would be more like the iOS implementation. [Scott]

 

Issue where mouseover of the menu to open submenus does not allow for keyboard navigation of the menu or submenus

  • Need a use case from the desktop to prove a need for this to be fixed.

 

 

Inputs Menu

 

All work for input menu has been moved to an extension here https://github.com/kborchers/jquery-ui-extensions/tree/master/menu with a demo here http://kborchers.github.com/jquery-ui-extensions/menu/inputmenu.html

 

Comments (0)

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