Element: <oj-menu>

Oracle® JavaScript Extension Toolkit (JET)
16.0.0

F83701-01

Since:
  • 0.6.0
Module:
  • ojmenu

QuickNav

Attributes


Description: Themeable, WAI-ARIA-compliant popup menu with touch, mouse and keyboard interactions for navigation.

A JET Menu is created using an ( <oj-menu> ) tag with an ( <oj-option> ) tag representing each menu item:

<oj-menu id="menu" style="display:none" aria-label="Order Edit">
  <oj-option value="item1">Item 1</oj-option>
  <oj-option value="item2">Item 2</oj-option>
  <oj-option>Item 3
    <oj-menu id="submenu">
      <oj-option value="item3-1">Item 3-1</oj-option>
      <oj-option value="item3-2">Item 3-2</oj-option>
      <oj-option value="item3-3">Item 3-3</oj-option>
      <oj-option value="item3-4">Item 3-4</oj-option>
      <oj-option value="item3-5">Item 3-5</oj-option>
    </oj-menu>
  </oj-option>
  <oj-option>Item 4</oj-option>
  <oj-option>Item 5</oj-option>
</oj-menu>

JET Menu is a popup component, for use with context menu, menu button, or similar functionality. It is not intended to sit inline on the page. See also the JET NavigationList component.

For this reason, the component is automatically hidden until it is opened. However, this styling is not applied until the component is initialized.

Submenus can be created by specifying nested oj-menu elements under the desired oj-option elements.

When a submenu is present, a default submenu icon will be automatically added to the parent menu item (see Menu Item Icons).

Sheet menus are not appropriate when submenus are present. Therefore, submenus and there parent menus are always displayed as a drop down regardless of the open-options.display attribute's value.

Dividers

Divider elements can be created by including menu items that contain only spaces and/or dashes, or nothing at all:

<oj-menu id="menu" style="display:none" aria-label="Order Edit">
  <oj-option value="item1">Item 1</oj-option>
  <oj-option>---</oj-option>
  <oj-option value="item2">Item 2</oj-option>
</oj-menu>

For WAI-ARIA compliance, JET automatically adds role="separator" to the divider element.

Menu Item Icons

Menu items currently support the rendering of start and end icons. Submenu icons are inserted automatically. To replace the default submenu icon with a custom icon, the endIcon slot should be specified. To render additional start or end icons for a menu item, the startIcon or endIcon slot of the oj-option should be specified. Icon only menus are not supported, providing menu item label using oj-option is required. See the oj-option doc for details about accepted children and slots.

Scrolling

JET Menus is scrollable when the menu is long. However, scrolling isn't supported on below scenarios:

  • Scrolling is not supported on Submenus.
  • Scrolling is not supported on phone due to some themes supporting downward swipe dismissal on Sheet Menus.

Touch End User Information

Target Gesture Action
Menu Item Tap Invoke the menu item's action.
Menu Swipe Down Dismiss the menu, if "swipe to dismiss" is enabled by the application.
JET Component or HTML Element having a JET Context Menu Press & Hold Open the context menu.
Outside of Menu Touch Close the menu.

Disabled items do not allow any touch interaction.

Keyboard End User Information

Target Key Action
Menu Item Enter or Space Invoke the focused menu item's action.
UpArrow Move focus to the previous menu item, wrapping around at the top.
DownArrow Move focus to the next menu item, wrapping around at the bottom.
Home Move focus to the first menu item.
End Move focus to the last menu item.
Menu Item in Top-level Menu Esc Close the menu and move focus to the launcher.
JET Component or HTML Element having a JET Context Menu Shift + F10 Open the context menu.

* RTL refers to pages written in a right-to-left language such as Arabic.

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.

Note that the "Search for text when I start typing" feature in Firefox can interfere with web content that accepts keystrokes, such as this "type a letter" feature of JET Menu.

Disabled items can receive keyboard focus, but do not allow any other interaction.

Accessibility

The app should supply either an aria-label or aria-labelledby attribute on the menu's root element, except possibly for menu buttons as discussed below. These attributes should not be supplied for submenus, which are labeled automatically.

If a menu is shared by different launchers, and should have a different label for each launcher, then a ojBeforeOpen listener can be used to set a different label per launch.

For a menu launched exclusively by one or more menu buttons, these attributes are optional. When the menu is opened via the menu button UI, if neither attribute is present after all ojBeforeOpen listeners have been called, then aria-labelledby will be set on the menu, referencing the menu button, and will be removed when the menu is closed. This approach provides a useful default label, while allowing the app to supply a different label if desired, and while allowing the menu to be shared by several menu buttons and/or other launchers.

Disabled content: JET supports an accessible luminosity contrast ratio, as specified in WCAG 2.0 - Section 1.4.3 "Contrast", in the themes that are accessible. (See the "Theming" chapter of the JET Developer Guide for more information on which themes are accessible.) Note that Section 1.4.3 says that text or images of text that are part of an inactive user interface component have no contrast requirement. Because disabled content may not meet the minimum contrast ratio required of enabled content, it cannot be used to convey meaningful information.

Reparenting

When a menu is opened, it will be reparented in the document and reparented back when closed. The goal of this design is to maintain as much of the page author's document structure as possible, while avoiding most of the clipping and positioning issues of a completely inline design.

If opened from another popup, the menu will be reparented to the nearest parent popup. Otherwise, the menu will be reparented to a container in the document body.

The context of opening is defined by the resolved openOptions.launcher value, which can be set via the attribute, via the argument to the open() method, or via a ojBeforeOpen listener.

All menus are assigned the same z-index values. The layering between peer popups reflects the opening order. In addition, the page author has control over z-index weights by way of the menu's layer. The menu's layer defines the "stacking context" and assignd the "oj-menu-layer" style.

Some notable consequences of this design:

  • Events raised within the menu will not bubble up to the menu's original ancestors. Instead, listeners for menu events should be applied to either the menu's root element, or the document.
  • Likewise, developers should not use CSS descendant selectors, or similar logic, that assumes that the menu will remain a child of its original parent.

Performance

If a menu launcher (such as a menu button or item with a context menu) is stamped inside a table, dataGrid, or other container, the resulting set of launchers should share a single menu defined outside the container.

Reading direction

The only supported way to set the reading direction (LTR or RTL) is to set the "dir" attribute on the <html> element of the page. As with any JET component, in the unusual case that the reading direction is changed post-init, the menu must be refresh()ed, or the page must be reloaded.

Declarative Binding

For components like Menu and Buttonset that contain a number of like items, applications may wish to use an oj-bind-for-each Knockout binding to stamp out the contents as follows:

<oj-menu id="menu" style="display:none" aria-label="Order Edit">
    <oj-bind-for-each data="[[menuItems]]">
        <template>
            <oj-option value="[[$current.data.label]]" :id="[[$current.data.id]]" :disabled="[[$current.data.disabled]]">
                <span>
                    <oj-bind-text value="[[$current.data.label]]"></oj-bind-text>
                </span>
            </oj-option>
        </template>
    </oj-bind-for-each>
</oj-menu>


Usage

Signature:

interface MenuElement

Typescript Import Format
//To typecheck the element APIs, import as below.
import { MenuElement } from "ojs/ojmenu";

//For the transpiled javascript to load the element's module, import as below
import "ojs/ojmenu";

For additional information visit:

Note: Application logic should not interact with the component's properties or invoke its methods until the BusyContext indicates that the component is ready for interaction.


Styling

CSS Variables

See JET CSS Variables for additional details.
Name Type Description
--oj-menu-icon-size <length> Menu icon size
--oj-menu-icon-to-edge-padding <length> Padding between icon and menu edge
--oj-menu-text-to-start-icon-padding <length> Padding between text and start icon
--oj-menu-text-to-end-icon-padding <length> Padding between text and end icon
--oj-menu-text-to-edge-padding <length> Padding between text and menu edge
--oj-menu-divider-margin <length> Menu divider margin
--oj-menu-sheet-margin-horizontal <length> Menu horizontal margin when displayed as a sheet
--oj-menu-item-text-color <color> Menu item text color
--oj-menu-icon-color <color> Menu icon color

Slots

JET components that allow child content support slots. Please see the slots section of the JET component overview doc for more information on allowed slot content and slot types.

Default

The <oj-menu> element accepts oj-option and oj-menu-select-many as child elements. See the oj-option documentation for details about accepted children and slots.

Attributes

disabled :boolean

Disables the menu if set to true.
Default Value:
  • false
Names
Item Name
Property disabled
Property change event disabledChanged
Property change listener attribute (must be of type function, see Events and Listeners for additional information.) on-disabled-changed

open-options :oj.ojMenu.OpenOptions

A collection of settings impacting the launch of a menu. These openOptions may be accessed and overridden individually or collectively, as seen in the examples.

The values set here can be overridden on a per-launch basis by passing the corresponding params into the open method. Those per-launch values can be further customized by a ojBeforeOpen listener.

The built-in menu button and context menu functionality overrides some of the Menu's openOptions, for WAI-ARIA compliance and other reasons. Thus, if the app really wants to customize those values, it must do so in a ojBeforeOpen listener. If the built-in menu button or context menu functionality is modified in this way, it is the app's responsibility to ensure that the result is both correct and accessible.

Names
Item Name
Property openOptions
Property change event openOptionsChanged
Property change listener attribute (must be of type function, see Events and Listeners for additional information.) on-open-options-changed

open-options.display :"auto"|"dropDown"|"sheet"

Determines whether the menu is displayed as a drop down menu or a sheet menu.

The default value is "auto", in which case the behavior depends on the type of device, as determined by the Config.getDeviceRenderMode method. If the application is running on a phone device, the menu will display as a sheet. Otherwise, the menu will display as a drop down.

Sheet menus are not appropriate when submenus are present. Thus, menus having submenus are always displayed as a drop down, regardless of the values of this option.

Supported Values:
Value Description
auto Displays the menu as a sheet or drop down, depending on the screen width.
dropDown Displays the menu as a drop down.
sheet Displays the menu as a sheet.
Default Value:
  • "auto"
Since:
  • 2.1.0
Names
Item Name
Property openOptions.display

open-options.initial-focus :"none"|"menu"|"firstItem"

Determines focus behavior when the menu is initially opened.
Supported Values:
Value Description
firstItem Focuses the first menu item (e.g. MenuButton DownArrow behavior).
menu Focuses the menu itself, with no menu item focused (e.g. typical Context Menu behavior).
none Leaves focus where it is, e.g. on the launching component. The application must verify that the result is accessible.
Default Value:
  • "menu"
Names
Item Name
Property openOptions.initialFocus

open-options.launcher :string|Element

The DOM node (which may or may not be a JET element) that launches this menu. This node must be focusable, as focus is returned to it upon menu dismissal.

The launcher must either be specified in this component option, or on each menu launch -- see open() and ojBeforeOpen.

Default Value:
  • null
Names
Item Name
Property openOptions.launcher

open-options.position :Object

Determines the position of a drop down menu when launched via the open() method or via menu button or context menu functionality. Ignored for sheet menus.

The "my" and "at" properties define alignment points relative to the menu and other element. The "my" property represents the menu's alignment where the "at" property represents the other element that can be identified by "of" or defauts to the launcher when the menu opens. The values of these properties describe horizontal and vertical alignments.

  • JET supports start and end values wherever left and right are supported. The start value means "left in LTR; right in RTL", while the end value means "right in LTR; left in RTL."

Menu also supports the following extended syntax for the of field:

  • The "event" keyword means "position the menu relative to the UI event that opened the menu."
  • The "launcher" keyword means "position the menu relative to the launcher element."

By default, when the of field is not set, the menu is positioned relative to the launcher.

The default position value varies between menus and submenus as follows:

  • Top level menu default: { my: { horizontal: "start", vertical: "top" }, at: { horizontal: "start", vertical: "bottom" }, offset: { x: 0, y: 0 }, collision: "flipfit" }
  • Submenu default: { my: { horizontal: "start", vertical: "top" }, at: { horizontal: "end", vertical: "top" }, offset: { x: 0, y: 0 }, collision: "flipfit" }
Deprecated v5.0.0 jQuery UI position syntax; Use of a percent unit with "my" or "at" is not supported.

Names
Item Name
Property openOptions.position

open-options.position.at :Object

Defines which position on the target element ("of") to align the positioned element against.
Names
Item Name
Property openOptions.position.at

open-options.position.at.horizontal :"start"|"end"|"left"|"center"|"right"

Defines the horizontal alignment of what the menu is aligned to. For top-level menus, the default value is "start". For submenus, the default value is "end".
Supported Values:
Value Description
center
end evaluates to "right" in LTR mode and "left" in RTL mode.
left
right
start evaluates to "left" in LTR mode and "right" in RTL mode.
Names
Item Name
Property openOptions.position.at.horizontal

open-options.position.at.vertical :"top"|"center"|"bottom"

Defines the vertical alignment of what the menu is aligned to. For top-level menus, the default value is "bottom". For submenus, the default value is "top".
Supported Values:
Value
bottom
center
top
Names
Item Name
Property openOptions.position.at.vertical

open-options.position.collision :"flip"|"fit"|"flipfit"|"flipcenter"|"none"

Rule for alternate alignment.
Supported Values:
Value Description
fit shift the element away from the edge of the window.
flip the element to the opposite side of the target and the collision detection is run again to see if it will fit. Whichever side allows more of the element to be visible will be used.
flipcenter first applies the flip rule and follows with center alignment.
flipfit first applies the flip logic, placing the element on whichever side allows more of the element to be visible. Then the fit logic is applied to ensure as much of the element is visible as possible.
none no collision detection.
Default Value:
  • 'flipfit'
Names
Item Name
Property openOptions.position.collision

open-options.position.my :Object

Defines which edge on the menu to align with the target ("of") element.
Names
Item Name
Property openOptions.position.my

open-options.position.my.horizontal :"start"|"end"|"left"|"center"|"right"

Defines the horizontal alignment of the menu.
Supported Values:
Value Description
center
end evaluates to "right" in LTR mode and "left" in RTL mode.
left
right
start evaluates to "left" in LTR mode and "right" in RTL mode.
Default Value:
  • 'start'
Names
Item Name
Property openOptions.position.my.horizontal

open-options.position.my.vertical :"top"|"center"|"bottom"

Defines the vertical alignment of the menu.
Supported Values:
Value
bottom
center
top
Default Value:
  • 'top'
Names
Item Name
Property openOptions.position.my.vertical

open-options.position.of :string|Object

Which element to position the menu against. The default is the launcher argument passed to the open method. If the value is a string, it should be a selector or the literal string value of window. Otherwise, a point of x,y. When a point is used, the values are relative to the whole document. Page horizontal and vertical scroll offsets need to be factored into this point - see UIEvent pageX, pageY.
Names
Item Name
Property openOptions.position.of

open-options.position.offset :Object

Defines a point offset in pixels from the ("my") alignment.
Names
Item Name
Property openOptions.position.offset

open-options.position.offset.x :number

Horizontal alignment offset.
Default Value:
  • 0
Names
Item Name
Property openOptions.position.offset.x

open-options.position.offset.y :number

Vertical alignment offset.
Default Value:
  • 0
Names
Item Name
Property openOptions.position.offset.y

translations :object|null

A collection of translated resources from the translation bundle, or null if this component has no resources. Resources may be accessed and overridden individually or collectively, as seen in the examples.

If the component does not contain any translatable resource, the default value of this attribute will be null. If not, an object containing all resources relevant to the component.

If this component has translations, their documentation immediately follows this doc entry.

Names
Item Name
Property translations
Property change event translationsChanged
Property change listener attribute (must be of type function, see Events and Listeners for additional information.) on-translations-changed

Label assigned to a hidden anchor tag used for accessibility navigation on platforms supporting VoiceOver. The link is injected before the first menu item. It is used for establishing VO cursor focus. Activation of the link will move focus to the first menu item.

Default Value:
  • "Focus is within the menu, double tap or swipe to move focus to the first menu item."
Since:
  • 6.0.0
See:
Names
Item Name
Property translations.ariaFocusSkipLink

(nullable) translations.label-cancel :string

Label for the "Cancel" menu item.

See the translations attribute for usage examples.

Default Value:
  • "Cancel"
Since:
  • 2.1.0
Names
Item Name
Property translations.labelCancel

Events

ojAction

Triggered when a menu item (other than the built-in "Cancel" item) is selected.

To ensure keyboard accessibility, the only correct, supported way to react to the selection of a menu item is to listen for this event. Click listeners should not be used.

To find the value of the menu item that triggered an action event, the event.target.value should be used.

See Events and Listeners for additional information.

Deprecated:
Since Description
10.0.0 This event is no longer supported, use the ojMenuAction event instead.
Since:
  • 10.0.0

ojAnimateEnd

Triggered when a default animation has ended, such as when the component is being opened/closed or a child item is being added/removed. This event is not triggered if the application has called preventDefault on the animateStart event.
Deprecated:
Since Description
12.1.0 This web component no longer supports this event.
Properties:

All of the event payloads listed below can be found under event.detail. See Events and Listeners for additional information.

Name Type Argument Description
action "open" | "close" The action that triggered the animation.

The number of actions can vary from element to element. Suggested values are:
  • "open" - when a menu element is opened
  • "close" - when a menu element is closed
element Element <not nullable>
target of animation

ojAnimateStart

Triggered when a default animation is about to start, such as when the component is being opened/closed or a child item is being added/removed. The default animation can be cancelled by calling event.preventDefault.
Deprecated:
Since Description
12.1.0 This web component no longer supports this event.
Properties:

All of the event payloads listed below can be found under event.detail. See Events and Listeners for additional information.

Name Type Argument Description
action "open" | "close" The action that triggers the animation.

The number of actions can vary from element to element. Suggested values are:
  • "open" - when a menu element is opened
  • "close" - when a menu element is closed
element Element <not nullable>
target of animation
endCallback function():void <not nullable>
If the event listener calls event.preventDefault to cancel the default animation, it must call the endCallback function when it finishes its own animation handling and any custom animation has ended.

ojBeforeOpen

Triggered before this menu is launched via the open method or via menu button or context menu functionality. The launch can be cancelled by calling event.preventDefault().

The event.detail.openOptions payload field contains the settings being used for this menu launch, resulting from merging the openOptions passed to open(), if any, with the openOptions component option.

This field is "live", meaning that the listener can alter fields such as position to affect this launch without affecting the component option. Since these changes are applied to the merged object, they supersede both the openOptions passed to open() and the openOptions component option.

If any of the above techniques are used to alter the built-in menu button or context menu functionality, it is the app's responsibility to ensure that the result is both correct and accessible.

Properties:

All of the event payloads listed below can be found under event.detail. See Events and Listeners for additional information.

Name Type Description
openOptions oj.ojMenu.OpenOptions effecting the open operation

ojClose

Triggered after this menu is closed.

Properties:

All of the event payloads listed below can be found under event.detail. See Events and Listeners for additional information.

Name Type Description
event Event a custom event
Since:
  • 2.0.0

ojMenuAction

Triggered when a menu item (other than the built-in "Cancel" item) is selected.

To ensure keyboard accessibility, the only correct, supported way to react to the selection of a menu item is to listen for this event. Click listeners should not be used.

To find the value of the menu item that triggered an menu action event, the event.detail.selectedValue should be used.

Properties:

All of the event payloads listed below can be found under event.detail. See Events and Listeners for additional information.

Name Type Description
selectedValue any The value of current selected menu item.
Since:
  • 10.0.0

ojOpen

Triggered after this menu is launched via the open method or via menu button or context menu functionality.

Properties:

All of the event payloads listed below can be found under event.detail. See Events and Listeners for additional information.

Name Type Description
event Event a custom event
Since:
  • 2.0.0

Methods

close : {void}

Closes the menu. This method does not accept any arguments.
Returns:
Type
void

getProperty(property) : {any}

Retrieves the value of a property or a subproperty. The return type will be the same as the type of the property as specified in this API document. If the method is invoked with an incorrect property/subproperty name, it returns undefined.
Parameters:
Name Type Description
property string The property name to get. Supports dot notation for subproperty access.
Since:
  • 4.0.0
Returns:
Type
any
Example

Get a single subproperty of a complex property:

let subpropValue = myComponent.getProperty('complexProperty.subProperty1.subProperty2');

open(event, openOptions) : {void}

Launches this menu after firing the ojBeforeOpen event. Listeners to that event can cancel the launch via event.preventDefault(). If the launch is not canceled, then the the open event is fired after the launch.

This method's optional openOptionsparam can be used to specify per-launch values for the settings in the corresponding component options, without altering those options. Those per-launch values can be further customized by a ojBeforeOpen listener.

Menus launched manually (as opposed to those launched by built-in functionality such as the menu button and context menu functionality) must be launched via this API, not by simply unhiding the Menu DOM (such as via jQuery's show() API.

Parameters:
Name Type Argument Description
event Event <optional>
What triggered the menu launch. May be null. May be omitted if subsequent params are omitted.
openOptions oj.ojMenu.OpenOptions <optional>
Options to merge with the openOptions option. May be null. May be omitted if subsequent params are omitted.
Fires:
  • oj.ojMenu#event:ojBeforeOpen
  • oj.ojMenu#event:ojOpen
Returns:
Type
void

refresh : {void}

Refreshes the disclosed state of the menu. JET elements require a refresh() after the DOM is programmatically changed underneath the component. The menu will implicitly refresh each time it is open. Calling refresh before the menu is open will trigger any content contained within an oj-defer to disclose before the menu is actually open.
Returns:
Type
void

setProperties(properties) : {void}

Performs a batch set of properties. The type of value for each property being set must match the type of the property as specified in this API document.
Parameters:
Name Type Description
properties Object An object containing the property and value pairs to set.
Since:
  • 4.0.0
Returns:
Type
void
Example

Set a batch of properties:

myComponent.setProperties({"prop1": "value1", "prop2.subprop": "value2", "prop3": "value3"});

setProperty(property, value) : {void}

Sets a property or a subproperty (of a complex property) and notifies the component of the change, triggering a [property]Changed event. The value should be of the same type as the type of the attribute mentioned in this API document.
Parameters:
Name Type Description
property string The property name to set. Supports dot notation for subproperty access.
value any The new value to set the property to.
Since:
  • 4.0.0
Returns:
Type
void
Example

Set a single subproperty of a complex property:

myComponent.setProperty('complexProperty.subProperty1.subProperty2', "someValue");

Type Definitions

OpenOptions

Properties:
Name Type Argument Description
display string <optional>
Determines whether the menu is displayed as a drop down menu or a sheet menu.
initialFocus string <optional>
Determines focus behavior when the menu is initially opened.
launcher string | Element <optional>
The DOM node (which may or may not be a JET element) that launches this menu.
position oj.ojMenu.Position <optional>
Determines the position of a drop down menu when launched. Ignored for sheet menus.

Position

Properties:
Name Type Argument Description
at oj.ojMenu.PositionAlign <optional>
Defines which position on the target element ("of") to align the positioned element against.
collision "flip" | "fit" | "flipfit" | "flipcenter" | "none" <optional>
Rule for alternate alignment.

  • "flip" the element to the opposite side of the target and the collision detection is run again to see if it will fit. Whichever side allows more of the element to be visible will be used.
  • "fit" shift the element away from the edge of the window.
  • "flipfit" first applies the flip logic, placing the element on whichever side allows more of the element to be visible. Then the fit logic is applied to ensure as much of the element is visible as possible.
  • flipcenter first applies the flip rule and follows with center alignment.
  • "none" no collision detection.

my oj.ojMenu.PositionAlign <optional>
Defines which edge on the menu to align with the target ("of") element.
of string | oj.ojMenu.PositionPoint <optional>
Which element to position the menu against. The default is the launcher argument passed to the open method.

If the value is a string, it should be a selector or the literal string value of window. Otherwise, a point of x,y. When a point is used, the values are relative to the whole document. Page horizontal and vertical scroll offsets need to be factored into this point - see UIEvent pageX, pageY.

offset oj.ojMenu.PositionPoint <optional>
Defines a point offset in pixels from the ("my") alignment.

PositionAlign

Properties:
Name Type Argument Description
horizontal "start" | "end" | "left" | "center" | "bottom" <optional>
Horizontal alignment.

  • "start" evaluates to "left" in LTR mode and "right" in RTL mode.
  • "end" evaluates to "right" in LTR mode and "left" in RTL mode.

vertical "top" | "bottom" | "center" <optional>
Vertical alignment.

PositionPoint

Properties:
Name Type Argument Description
x number <optional>
Horizontal alignment offset.
y number <optional>
Vertical alignment offset.