/**
* Copyright (c) 2014, Oracle and/or its affiliates.
* All rights reserved.
*/
(function () {
/**
* @ojcomponent oj.ojNavigationList
* @augments oj.baseComponent
* @since 1.1.0
*
* @classdesc
* <h3 id="navlistOverview-section">
* JET Navigation List Component
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#navlistOverview-section"></a>
* </h3>
*
* <p>Description: The JET Navigation List enhances a HTML list element into a themable, WAI-ARIA compliant, mobile friendly component with advance interactive features.
*
* <p>The JET Navigation List gets its data in following ways. </p>
* <ul>
* <li><b>Using table datasource</b>. This is typically used in case of flat list.There are several types of TableDataSource that
* are available out of the box like oj.ArrayTableDataSource,oj.CollectionTableDataSource.NOTE: oj.PagingTableDataSource is not supported by navigation list.
* For large amount of data, It is recommended to use hierarhcial navigation list with tree data source.</li>
* <li><b>Using TreeDataSource</b>. This is typically used to display hierarchical navigation list. There are several types
* of TreeDataSource that are available out of the box like oj.JsonTreeDataSource, oj.CollectionTreeDataSource </li>
* <li><b>Using static content </b>. The structure of the content can be either flat or hierarhical.</li>
* </ul>
* <p>Example of flat static content</p>
* <pre class="prettyprint">
* <code>
* <div id="navigationlist">
* <ul>
* <li><a href="#">Item 1</a></li>
* <li><a href="#">Item 2</a></li>
* <li><a href="#">Item 3</a></li>
* </ul>
* </div>
* </code></pre>
*
* <p>Example of hierarchical static content</p>
* <pre class="prettyprint">
* <code>
* <div id="navigationlist">
* <ul >
* <li><a href="#">Item 1</a></li>
* <li><a href="#">Item 2</a></li>
* <li><a href="#">Item 3</a>
* <ul>
* <li><a href="#">Item 3-1</a></li>
* <li><a href="#">Item 3-2</a></li>
* <li><a href="#">Item 3-3</a></li>
* <li><a href="#">Item 3-4</a></li>
* <li><a href="#">Item 3-5</a></li>
* </ul>
* </li>
* <li><a href="#">Item 4</a></li>
* <li><a href="#">Item 5</a></li>
* </ul>
* </div>
* </code></pre>
* <p>NOTE: Currently, the only supported way to react to the selection of a list item is to listen for <a href="#event:optionChange">optionChange</a> event. Click listeners and href navigation should not be used. </p>
* <h4 id="treeJSON-section"> JSON Tree Node Format</h4>
* </br>
* Each node object typically have an
* <code class="prettyprint">attr</code> property. This attr value will be provided as <code class="prettyprint">itemContext.data</code> to renderer function. See <a href="#itemContext">itemContext</a> section. Any node can be defined as a parent by supplying
* a <code class="prettyprint">children</code> property, which is an array of one or more node definitions.
* (Note: lazy-loading is not supported in navigation list so <code class="prettyprint">children</code> property should be a non empty array)
* <p>Example: Basic JSON Tree definition
* <pre class="prettyprint">
* <code>
*[
* {
* "attr": {
* "id": "home",
* "title": "Home"
* },
* },
* {
* "attr": {
* "id": "news",
* "title": "News"
* }
* },
* {
* "attr": {
* "id": "blogs",
* "title": "Blogs"
* },
* "children": [ {
*
* "attr": {
* "id": "today",
* "title": "Today"
* }
* },
* {
* "attr": {
* "id": "yesterday",
* "title": "Yesterday"
* }
* }
* ]
* }
*]
*</code></pre>
*</p></br>
* <p>Any list item can be disabled by adding the <code class="prettyprint">oj-disabled</code> class to that element. As with any DOM change, doing so post-init
* requires a <code class="prettyprint">refresh()</code> of the component.
*
*
* <h3 id="icons-section">
* Icons
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#icons-section"></a>
* </h3>
*
* <p>Sublist icons are inserted automatically. To add other icons to list items, include them in the markup and include the <code class="prettyprint">oj-navigationlist-item-icon</code> class, as follows:
*
* <pre class="prettyprint">
* <code><ul id="navigationlist">
* <li id="foo"><a href="#"><span class="oj-navigationlist-item-icon demo-icon-font-24 demo-palette-icon-24"></span>Foo</a></li>
* </ul>
* </code></pre>
*
* <h3 id="styling-section">
* Styling
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#styling-section"></a>
* </h3>
*
* <table class="generic-table styling-table">
* <thead>
* <tr>
* <th>Class(es)</th>
* <th>Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td>oj-navigationlist-stack-icon-label</td>
* <td>Add this class to display Navigation List with Stacked icon and label. Applicable only when edge is top.</td>
* </tr>
* <tr>
* <td>oj-navigationlist-category-divider</td>
* <td>Use this class to add horizontal divider line between two categories of items.</td>
* </tr>
* <tr>
* <td>oj-navigationlist-item-icon</td>
* <td>Use this class to add icon to list item.</td>
* </tr>
* <tr>
* <td>oj-navigationlist-item-title</td>
* <td>When arbitrary content is placed in side item, mark item title using this marker class.
* <p>Example of item markup with arbitrary content.
* <pre class="prettyprint">
* <code>
*<li>
* <div>
* <span class="oj-navigationlist-item-title">Play</span>
* <button>Button</button>
* </div>
*</li>
* </code>
* </pre>
* </p>
* </td>
* </tr>
* </tbody>
* </table>
* <h3 id="touch-section">
* Touch End User Information
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#touch-section"></a>
* </h3>
*
* {@ojinclude "name":"touchDoc"}
*
* <h3 id="keyboard-section">
* Keyboard End User Information
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#keyboard-section"></a>
* </h3>
* {@ojinclude "name":"keyboardDoc"}
*
* <p>Disabled items will not receive keyboard focus and do not allow any interaction.
*
*<h3 id="context-section">
* Item Context
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#context-section"></a>
* </h3>
*
* <p>For all item options, developers can specify a function as the return value. The function takes a single argument, which is an object that contains contextual information about the particular item. This gives developers the flexibility to return different value depending on the context.</p>
*
* <p>The context paramter contains the following keys:</p>
* <table class="keyboard-table">
* <thead>
* <tr>
* <th>Key</th>
* <th>Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td><kbd>component</kbd></td>
* <td>A reference to the NavigationList widget constructor.</td>
* </tr>
* <tr>
* <td><kbd>datasource</kbd></td>
* <td>A reference to the data source object. (Not available for static content)</td>
* </tr>
* <tr>
* <td><kbd>index</kbd></td>
* <td>The index of the item, where 0 is the index of the first item. In the hierarchical case the index is relative to its parent.</td>
* </tr>
* <tr>
* <td><kbd>key</kbd></td>
* <td>The key of the item.</td>
* </tr>
* <tr>
* <td><kbd>data</kbd></td>
* <td>The data object for the item.</td>
* </tr>
* <tr>
* <td><kbd>parentElement</kbd></td>
* <td>The list item element. The renderer can use this to directly append content.</td>
* </tr>
* </tbody>
* </table>
*
* <p></p>
* <p>If the data is hierarchical, the following additional contextual information are available:</p>
* <table class="keyboard-table">
* <thead>
* <tr>
* <th>Key</th>
* <th>Description</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td><kbd>depth</kbd></td>
* <td>The depth of the item. The depth of the first level children under the invisible root is 1.</td>
* </tr>
* <tr>
* <td><kbd>parentKey</kbd></td>
* <td>The key of the parent item. The parent key is null for root node.</td>
* </tr>
* <tr>
* <td><kbd>leaf</kbd></td>
* <td>Whether the item is a leaf or a group item.</td>
* </tr>
* </tbody>
* </table>
* <h3 id="perf-section">
* Performance
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#perf-section"></a>
* </h3>
*
* <h4>Data Set Size</h4>
* <p>As a rule of thumb, it's recommended that applications limit the amount of data to display. Displaying large
* number of items in Navigation List makes it hard for user to find what they are looking for, but affects the load time.
* If displaying large number of items is neccessary, it is recommended to group the items in to hierarchial navigation list.
*
* <h4>Item Content</h4>
* <p>Navigation List allows developers to specify arbitrary content inside its item. In order to minimize any negative effect on
* performance, you should avoid putting a large number of heavy-weight components inside because as you add more complexity
* to the structure, the effect will be multiplied because there can be many items in the Navigation List.</p>
*
* <h4>Expand All</h4>
* <p>While Navigation List provides a convenient way to initially expand all group items, it might have an impact
* on the initial rendering performance since expanding each group item might cause a fetch from the server depending on
* the TreeDataSource. Other factors that could impact performance includes the depth of the tree, and the number of children
* in each level.</p>
*
* <h3 id="a11y-section">
* Accessibility
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#a11y-section"></a>
* </h3>
*
* <p>Disabled content: JET supports an accessible luminosity contrast ratio,
* as specified in <a href="http://www.w3.org/TR/WCAG20/#visual-audio-contrast-contrast">WCAG 2.0 - Section 1.4.3 "Contrast"</a>,
* 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.<p>
*
*
* <h3 id="rtl-section">
* Reading direction
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#rtl-section"></a>
* </h3>
*
* <p>The only supported way to set the reading direction (LTR or RTL) is to set the <code class="prettyprint">"dir"</code> attribute on the
* <code class="prettyprint"><html></code> element of the page. As with any JET component, in the unusual case that the reading direction
* is changed post-init, the navigation list must be <code class="prettyprint">refresh()</code>ed, or the page must be reloaded.
*
*
* <h3 id="pseudos-section">
* Pseudo-selectors
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#pseudos-section"></a>
* </h3>
*
* <p>The <code class="prettyprint">:oj-navigationlist</code> pseudo-selector can be used in jQuery expressions to select JET Navigation Lists. For example:
*
* <pre class="prettyprint">
* <code>$( ":oj-navigationlist" ) // selects all JET Navigation lists on the page
* $myEventTarget.closest( ":oj-navigationlist" ) // selects the closest ancestor that is a JET Navigation lists
* </code></pre>
*
* <!-- - - - - Above this point, the tags are for the class.
* Below this point, the tags are for the constructor (initializer). - - - - - - -->
*
*
* @desc Creates a JET Navigation List.
*
* @param {Object=} options a map of option-value pairs to set on the component
*
* @example <caption>Initialize the Navigation list with no options specified:</caption>
* $( ".selector" ).ojNavigationList();
*
* @example <caption>Initialize the Navigation list with some options and callbacks specified:</caption>
* $( ".selector" ).ojNavigationList( { "drillMode": "none", "beforeSelect": function( event, ui ) {} } );
*
* @example <caption>Initialize the Navigation list via the JET <code class="prettyprint">ojComponent</code> binding:</caption>
* <div id="navigationlist" data-bind="ojComponent: { component: 'ojNavigationList',
* drillMode: 'none',
* beforeSelect: beforeSelectItem }">
*/
oj.__registerWidget("oj.ojNavigationList", $['oj']['baseComponent'], {
widgetEventPrefix: 'oj',
options: {
/**
* Key of the current item. Current item is the list item which is having active focus. Note that if currentItem
* is set to an item that is currently not available (not fetched or
* inside a collapsed parent node), then the value is ignored.
*
* @expose
* @public
* @instance
* @memberof! oj.ojNavigationList
* @type {Object}
* @default <code class="prettyprint">null</code>
*
* @example <caption>Get the current item:</caption>
* $( ".selector" ).ojNavigationList("option", "currentItem");
*
* @example <caption>Set the current item on the NavigationList during initialization:</caption>
* $(".selector").ojNavigationList({"currentItem", "item2"});
*/
currentItem: null,
/**
* Defines style of navigation used to drill down hierarchical list items.
* <ul>
* <li>none</li>
* <li>collapsible</li>
* <li>sliding</li>
* </ul>
*
* @expose
* @memberof oj.ojNavigationList
* @instance
* @type {string}
* @default <code class="prettyprint">"none"</code>
* @ojvalue {string} "none" All group items are expanded by default and user not allowed to collapse them.
* @ojvalue {string} "collapsible" Allows user to expand and collapse group items. If there are more than two levels in hierarchy, <code class="prettyprint">sliding</code> is preferered drill mode.
* @ojvalue {string} "sliding" This is typically used for hierarchical lists. This allows user to view one level at a time.
*
* @example <caption>Initialize the menu with the <code class="prettyprint">drillMode</code> option specified:</caption>
* $( ".selector" ).ojNavigationList({ drillMode: "collapsible" });
*
* @example <caption>Get the <code class="prettyprint">drillMode</code> option, after initialization:</caption>
* // getter
* var drillMode = $( ".selector" ).ojNavigationList( "option", "drillMode" );
*/
drillMode: "none",
/**
* The position of the Navigation List. Valid Values: top and start.
* <p> NOTE: when value is <code class="prettyprint">top</code>,<code class="prettyprint">"none"</code> is the only supported drillMode and it also does't support hierarchical items.
* @expose
* @name edge
* @memberof oj.ojNavigationList
* @instance
* @type {string|null}
* @ojvalue {string} "top" This renders list items horizontally.
* @ojvalue {string} "start" This renders list items vertically.
* @default <code class="prettyprint">"start"</code>
*/
edge: "start",
/**
* Label for top level list items.
* <p>NOTE: This is needed only for sliding navigation list where
* this will be used as title for the top level list elements.
* @type {?string}
* @default <code class="prettyprint">Navigation List</code>
* @expose
* @instance
* @memberof oj.ojNavigationList
*/
rootLabel: null,
/**
* Item key of currently selected list item. If the value is modified
* by an application, navigation list UI is modified to match the new value.
* @type {string|null}
* @default <code class="prettyprint">null</code>
* @expose
* @instance
* @memberof oj.ojNavigationList
*/
selection: null,
/**
* Specifies which items in NavigationList should be expanded. Specifies "all" value to expand all items. Specifies
* an array of keys to expand specific items.
*
* The default value is "auto", which means that NavigationList will determine which items are expanded by default.
* Specifically, if drillMode is set to "none", then all items are expanded, any other values for
* drillMode will not cause any items to expand by default.
*
* Note that expanded does not return the currently expanded items. This only returns what is specified
* by default. To retrieve the keys of currently expanded items, use the <code class="prettyprint">getExpanded</code>
* method.
* @type {Array|string}
* @default <code class="prettyprint">[]</code>
* @expose
* @instance
* @memberof oj.ojNavigationList
*/
expanded: "auto",
/**
* The data source for the NavigationList accepts either a oj.TableDataSource or oj.TreeDataSource.
* See the data source section in the introduction for out of the box data source types.
* If the data attribute is not specified, the child elements are used as content. If there's no
* content specified, then an empty list is rendered.
*
* @expose
* @memberof! oj.ojNavigationList
* @instance
* @type {oj.TableDataSource|oj.TreeDataSource}
* @default <code class="prettyprint">null</code>
*
* @example <caption>Initialize the NavigationList with a one-dimensional array:</caption>
* $( ".selector" ).ojNavigationList({ "data": new oj.ArrayTableDataSource([1,2,3])});
*
* @example <caption>Initialize the NavigationList with an oj.Collection:</caption>
* $( ".selector" ).ojNavigationList({ "data": new oj.CollectionTableDataSource(collection)});
*/
data: null,
/**
* Whether to display both the label and icons (<code class="prettyprint">"all"</code>) or just the icons (<code class="prettyprint">"icons"</code>).
* In the latter case, the label is displayed in a tooltip instead, unless a tooltip was already supplied at create time.
* Note: <code class="prettyprint">display="icons"</code> is valid only when <code class="prettyprint">drillMode=none</code> and navigation list is a flat list.
* It is also mandatory to provide icons for each item as stated in <a href="#icons-section">icons section</a>.
*
* @expose
* @memberof oj.ojNavigationList
* @instance
* @type {string}
* @ojvalue {string} "all" Display both the label and icons.
* @ojvalue {string} "icons" Display only the icons.This option
* @default <code class="prettyprint">"all"</code>
*
* @example <caption>Initialize the NavigationList with the <code class="prettyprint">display</code> option specified:</caption>
* $( ".selector" ).ojNavigationList( { "display": "icons" } );
*
* @example <caption>Get or set the <code class="prettyprint">display</code> option, after initialization:</caption>
* // getter
* var display = $( ".selector" ).ojNavigationList( "option", "display" );
*
* // setter
* $( ".selector" ).ojNavigationList( "option", "display", "icons" );
*/
display: "all",
/**
* The item option contains a subset of options for items.
*
* @expose
* @memberof! oj.ojNavigationList
* @instance
*/
item: {
/**
* The renderer function that renders the content of the item. See <a href="#context-section">itemContext</a>
* in the introduction to see the object passed into the renderer function.
* The function returns either a String or a DOM element of the content inside the item.
* If the developer chooses to manipulate the list element directly, the function should return
* nothing. If no renderer is specified, Navigation List will treat the data as a String.
*
* @expose
* @alias item.renderer
* @memberof! oj.ojNavigationList
* @instance
* @type {function(Object)|null}
* @default <code class="prettyprint">null</code>
*
* @example <caption>Initialize the NavigationList with a renderer:</caption>
* $( ".selector" ).ojNavigationList({ "data":data, "item": { "renderer": function(itemContext) {
* return itemContext['data'].get('FIRST_NAME');}}});
*
* @example <caption>Get or set the <code class="prettyprint">renderer</code> option, after initialization:</caption>
* // set the renderer function
* $( ".selector" ).ojNavigationList( "option", "item.renderer", myFunction});
*/
renderer: null,
/**
* Whether the item is selectable.
* See <a href="#context-section">itemContext</a> in the introduction to see the object passed into the selectable function.
*
* @expose
* @alias item.selectable
* @memberof! oj.ojNavigationList
* @instance
* @type {function(Object)|boolean}
* @default <code class="prettyprint">true</code>
*
* @example <caption>Initialize the NavigationList such that the first 3 items are not selectable:</caption>
* $( ".selector" ).ojNavigationList({ "data":data, "item": { "selectable": function(itemContext) {
* return itemContext['index'] > 3;}}});
*/
selectable: true
/**
* The knockout template used to render the content of the item.
*
* This attribute is only exposed via the <code class="prettyprint">ojComponent</code> binding, and is not a
* component option.
*
* @ojbindingonly
* @name item.template
* @memberof! oj.ojNavigationList
* @instance
* @type {string|null}
* @default <code class="prettyprint">null</code>
*
* @example <caption>Specify the <code class="prettyprint">template</code> when initializing NavigationList:</caption>
* // set the template
* <div id="navlist" data-bind="ojComponent: {component: 'ojNavigationList', data: dataSource, template: 'my_template'}"></div>
*/
},
//Events
/**
* <p>Triggered before this list item is selected.
* To prevent the item selection, return <code class="prettyprint">false</code> from event handler or invoke <code class="prettyprint">event.preventDefault()</code>.
* <p>The <code class="prettyprint">ui.key</code> contains item key which uniquely identifies the item.
* <code class="prettyprint">ui.item</code> payload field contains item element being selected.
*
* @expose
* @event
* @memberof! oj.ojNavigationList
* @instance
* @property {Event} event <code class="prettyprint">jQuery</code> event object
* @property {Object} ui Parameters
* @property {Object} ui.key Selected list item key.
* @property {jQuery} ui.item Selected list item.
*
* @example <caption>Initialize the Navigation List with the <code class="prettyprint">beforeSelect</code> callback specified:</caption>
* $( ".selector" ).ojNavigationList({
* "beforeSelect": function( event, ui ) {}
* });
*
* @example <caption>Bind an event listener to the <code class="prettyprint">ojbeforeselect</code> event:</caption>
* $( ".selector" ).on( "ojbeforeselect", function( event, ui ) {} );
*/
beforeSelect: null,
/**
* Triggered before an item is collapse via the <code class="prettyprint">expanded</code> option,
* the <code class="prettyprint">collapse</code> method, or via the UI.
* To prevent the item being collapsed, return <code class="prettyprint">false</code> from event handler or invoke <code class="prettyprint">event.preventDefault()</code>.
*
* @expose
* @event
* @memberof! oj.ojNavigationList
* @instance
* @property {Event} event <code class="prettyprint">jQuery</code> event object
* @property {Object} ui Parameters
* @property {Object} ui.key the key of the item to be collapse
* @property {jQuery} ui.item the item to be collapse
*
* @example <caption>Initialize the NavigationList with the <code class="prettyprint">beforeCollapse</code> callback specified:</caption>
* $( ".selector" ).ojNavigationList({
* "beforeCollapse": function( event, ui ) {
* // return false to veto the event, which prevents the item to collapse
* }
* });
*
* @example <caption>Bind an event listener to the <code class="prettyprint">ojbeforecollapse</code> event:</caption>
* $( ".selector" ).on( "ojbeforecollapse", function( event, ui ) {} );
*/
beforeCollapse: null,
/**
* Triggered before the current item is changed via the <code class="prettyprint">currentItem</code> option or via the UI.
* To prevent the item being focused, return <code class="prettyprint">false</code> from event handler or invoke <code class="prettyprint">event.preventDefault()</code>.
* @expose
* @event
* @memberof! oj.ojNavigationList
* @instance
* @property {Event} event <code class="prettyprint">jQuery</code> event object
* @property {Object} ui Parameters
* @property {Object} ui.previousKey the key of the previous item
* @property {jQuery} ui.previousItem the previous item
* @property {Object} ui.key the key of the new current item
* @property {jQuery} ui.item the new current item
*
* @example <caption>Initialize the NavigationList with the <code class="prettyprint">beforeCurrentItem</code> callback specified:</caption>
* $( ".selector" ).ojNavigationList({
* "beforeCurrentItem": function( event, ui ) {
* // return false to veto the event, which prevents the item to become focus
* }
* });
*
* @example <caption>Bind an event listener to the <code class="prettyprint">ojbeforecurrentitem</code> event:</caption>
* $( ".selector" ).on( "ojbeforecurrentitem", function( event, ui ) {} );
*/
beforeCurrentItem: null,
/**
* Triggered after an item has been collapsed via the <code class="prettyprint">expanded</code> option,
* the <code class="prettyprint">collapse</code> method, or via the UI.
*
* @expose
* @event
* @memberof! oj.ojNavigationList
* @instance
* @property {Event} event <code class="prettyprint">jQuery</code> event object
* @property {Object} ui Parameters
* @property {Object} ui.key The key of the item that was just collapsed.
* @property {jQuery} ui.item The list item that was just collapsed.
*
* @example <caption>Initialize the NavigationList with the <code class="prettyprint">expand</code> callback specified:</caption>
* $( ".selector" ).ojNavigationList({
* "collapse": function( event, ui ) {}
* });
*
* @example <caption>Bind an event listener to the <code class="prettyprint">ojcollapse</code> event:</caption>
* $( ".selector" ).on( "ojcollapse", function( event, ui ) {} );
*/
collapse: null,
/**
* Triggered before an item is expand via the <code class="prettyprint">expanded</code> option,
* the <code class="prettyprint">expand</code> method, or via the UI.
* To prevent the item being expanded, return <code class="prettyprint">false</code> from event handler or invoke <code class="prettyprint">event.preventDefault()</code>.
* @expose
* @event
* @memberof! oj.ojNavigationList
* @instance
* @property {Event} event <code class="prettyprint">jQuery</code> event object
* @property {Object} ui Parameters
* @property {Object} ui.key the key of the item to be expand
* @property {jQuery} ui.item the item to be expand
*
* @example <caption>Initialize the NavigationList with the <code class="prettyprint">beforeExpand</code> callback specified:</caption>
* $( ".selector" ).ojNavigationList({
* "beforeExpand": function( event, ui ) {
* // return false to veto the event, which prevents the item to expand
* }
* });
*
* @example <caption>Bind an event listener to the <code class="prettyprint">ojbeforeexpand</code> event:</caption>
* $( ".selector" ).on( "ojbeforeexpand", function( event, ui ) {} );
*/
beforeExpand: null,
/**
* Triggered after an item has been expanded via the <code class="prettyprint">expanded</code> option,
* the <code class="prettyprint">expand</code> method, or via the UI.
*
* @expose
* @event
* @memberof! oj.ojNavigationList
* @instance
* @property {Event} event <code class="prettyprint">jQuery</code> event object
* @property {Object} ui Parameters
* @property {Object} ui.key The key of the item that was just expanded.
* @property {jQuery} ui.item The list item that was just expanded.
*
* @example <caption>Initialize the NavigationList with the <code class="prettyprint">expand</code> callback specified:</caption>
* $( ".selector" ).ojNavigationList({
* "expand": function( event, ui ) {}
* });
*
* @example <caption>Bind an event listener to the <code class="prettyprint">ojexpand</code> event:</caption>
* $( ".selector" ).on( "ojexpand", function( event, ui ) {} );
*/
expand: null,
/**
* Fired whenever a supported component option changes, whether due to user interaction or programmatic
* intervention. If the new value is the same as the previous value, no event will be fired.
*
* <p>NOTE: Currently, the only supported way to react to the selection of a list item is
* to listen for this event. Click listeners and href navigation should not be used. </p>
* @expose
* @event
* @memberof! oj.ojNavigationList
* @instance
* @property {Event} event <code class="prettyprint">jQuery</code> event object
* @property {Object} ui Parameters
* @property {string} ui.option the name of the option that is changing
* @property {boolean} ui.previousValue the previous value of the option
* @property {boolean} ui.value the current value of the option
* @property {Object} ui.optionMetadata information about the option that is changing
* @property {string} ui.optionMetadata.writeback <code class="prettyprint">"shouldWrite"</code> or
* <code class="prettyprint">"shouldNotWrite"</code>. For use by the JET writeback mechanism.
*
* @example <caption>Initialize component with the <code class="prettyprint">optionChange</code> callback</caption>
* $(".selector").ojNavigationList({
* 'optionChange': function (event, data) {
* if (data['option'] === 'selection') { // handle selection change }
* }
* });
* @example <caption>Bind an event listener to the ojoptionchange event</caption>
* $(".selector").on({
* 'ojoptionchange': function (event, data) {
* window.console.log("option that changed is: " + data['option']);
* };
* });
*/
optionChange: null
},
/**
* Create the Navigation List
* @override
* @memberof! oj.ojNavigationList
* @protected
*/
_ComponentCreate: function () {
this._super();
this._setup();
},
/**
* Initialize the NavigationList after creation
* @protected
* @override
* @memberof! oj.ojNavigationList
*/
_AfterCreate: function ()
{
this._super();
this.navlist.afterCreate();
},
/**
* When the <a href="#contextMenu">contextMenu</a> option is set, this method is called when the user invokes the context menu via
* the default gestures: right-click, pressHold, and <kbd>Shift-F10</kbd>. Components should not call this method directly.
*
* @param {!Object} menu The JET Menu to open as a context menu. Always non-<code class="prettyprint">null</code>.
* @param {!Event} event What triggered the menu launch. Always non-<code class="prettyprint">null</code>.
* @param {string} eventType "mouse", "touch", or "keyboard". Never <code class="prettyprint">null</code>.
* @private
*/
_NotifyContextMenuGesture: function (menu, event, eventType)
{
this.navlist.notifyContextMenuGesture(menu, event, eventType);
},
/**
* Initialize DOM structure for navigation list.
* @private
* @memberof! oj.ojNavigationList
*/
_setup: function () {
for (var key in this.options) {
this._validateOptionValues(key, this.options[key]);
}
this._validateOptionsForIconsOnlyAndHorizontalList(this.options['drillMode'], this.options['display'], this.options['edge']);
this.navlist = new _ojNavigationListView();
var opts = {};
opts.ojContext = this;
opts = $.extend(this.options, opts);
this.navlist.init(opts);
},
/**
* Return the subcomponent node represented by the documented locator attribute values.
* <p>
* To lookup the list items the locator object should have the following:
* <ul>
* <li><b>subId</b>: 'oj-navigationlist-item'</li>
* <li><b>key</b>: the key of the item</li>
* </ul>
*
* For sliding navigation list, To lookup the previous link the locator object should have the following:
* <ul>
* <li><b>subId</b>: 'oj-navigationlist-previous-link'</li>
* </ul>
*
* For sliding navigation list, To lookup the hierarchical menu button the locator object should have the following:
* <ul>
* <li><b>subId</b>: 'oj-navigationlist-hierarchical-button'</li>
* </ul>
*
* For sliding navigation list, To lookup the hierarchical menu the locator object should have the following:
* <ul>
* <li><b>subId</b>: 'oj-navigationlist-hierarchical-menu'</li>
* </ul>
*
*
* @expose
* @memberof! oj.ojNavigationList
* @instance
* @override
* @param {Object} locator An Object containing at minimum a subId property
* whose value is a string, documented by the component, that allows
* the component to look up the subcomponent associated with that
* string. It contains:<p>
* component: optional - in the future there may be more than one
* component contained within a page element<p>
* subId: the string, documented by the component, that the component
* expects in getNodeBySubId to locate a particular subcomponent
* @returns {Array.<(Element|null)>|Element|null} the subcomponent located by the subId string passed
* in locator, if found.<p>
*/
getNodeBySubId: function (locator)
{
return this.navlist.getNodeBySubId(locator);
},
/**
* Expand an item.<p>
* Note when vetoable is set to false, beforeExpand event will still be fired but the event cannot be veto.<p>
*
* @expose
* @memberof oj.ojNavigationList
* @instance
* @param {Object} key the key of the item to expand
* @param {boolean} vetoable if event is vetoable
*/
expand: function (key, vetoable)
{
this.navlist.expandKey(key, vetoable, true);
},
/**
* Collapse an item.<p>
* Note when vetoable is set to false, beforeCollapse event will still be fired but the event cannot be veto.<p>
*
* @expose
* @memberof oj.ojNavigationList
* @instance
* @param {Object} key the key of the item to collapse
* @param {boolean} vetoable if event is vetoable
*/
collapse: function (key, vetoable)
{
this.navlist.collapseKey(key, vetoable, true);
},
/**
* Gets the key of currently expanded items.
*
* @expose
* @memberof oj.ojNavigationList
* @instance
* @return {Array} array of keys of currently expanded items
*/
getExpanded: function ()
{
return this.navlist.getExpanded();
},
_validateOptionsForIconsOnlyAndHorizontalList: function (drillMode, display, edge) {
if (drillMode !== 'none') {
if (display === 'icons') {
throw "Icon only navigation list should have drillMode set to 'none'.";
}
if (edge === 'top') {
throw "Horizontal navigation list should have drillMode set to 'none'.";
}
}
},
_validateOptionValues: function (key, value) {
var valid = true;
if (key === "drillMode") {
valid = (value === 'none' || value === 'collapsible' || value === 'sliding');
} else if (key === "display") {
valid = (value === 'all' || value === 'icons');
} else if (key === "edge") {
valid = (value === 'top' || value === 'start');
}
if (!valid) {
throw "Invalid value: " + value + " for key: " + key;
}
},
/**
* Set single option
* @param {string} key the option key
* @param {Object} value value for option
* @override
* @memberof oj.ojNavigationList
* @instance
* @private
*/
_setOption: function (key, value) {
this._validateOptionValues(key, value);
switch (key) {
case "drillMode":
this._validateOptionsForIconsOnlyAndHorizontalList(value, this.options['display'], this.options['edge']);
break;
case "display":
this._validateOptionsForIconsOnlyAndHorizontalList(this.options['drillMode'], value, this.options['edge']);
break;
case "edge":
this._validateOptionsForIconsOnlyAndHorizontalList(this.options['drillMode'], this.options['display'], value);
break;
}
this._super(key, value);
},
/**
* Sets multiple options
* @param {Object} options the options object
* @param {Object} flags additional flags for option
* @override
* @private
*/
_setOptions: function (options, flags)
{
var needRefresh = this.navlist.setOptions(options, flags);
// updates the options last
this._super(options, flags);
if (needRefresh)
{
this.navlist.refresh();
}
},
/**
* In browsers [Chrome v35, Firefox v24.5, IE9, Safari v6.1.4], blur and mouseleave events are generated for hidden content but not detached content,
* so for detached content only, we must use this hook to remove the focus and hover classes.
* @override
* @private
*/
_NotifyDetached: function ()
{
this.navlist.notifyDetached();
},
/**
* Invoked when application calls oj.Components.subtreeShown.
* @override
* @private
*/
_NotifyShown: function()
{
this.navlist.notifyShown();
},
/**
* Refreshes the visual state of the Navigation List. JET components require a <code class="prettyprint">refresh()</code> after the DOM is
* programmatically changed underneath the component.
* <p>This method does not accept any arguments.
*
* @expose
* @memberof oj.ojNavigationList
* @instance
*
* @example <caption>Invoke the <code class="prettyprint">refresh</code> method:</caption>
* $( ".selector" ).ojNavigationList( "refresh" );
*/
refresh: function () {
this._super();
this.navlist.refresh();
},
/**
* Destroy the Navigation List
* @memberof! oj.ojNavigationList
* @private
*/
_destroy: function ()
{
this.navlist.destroy();
this._super();
delete this.navlist;
}
// Fragments:
/**
* <table class="keyboard-table">
* <thead>
* <tr>
* <th>Target</th>
* <th>Gesture</th>
* <th>Action</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td rowspan="2">List Item</td>
* <td><kbd>Tap</kbd></td>
* <td>Selects the item.</td>
* </tr>
* <tr>
* <td><kbd>Press & Hold</kbd></td>
* <td>Display context menu</td>
* </tr>
* <tr>
* <td rowspan="2">Group Item</td>
* <td><kbd>Tap</kbd></td>
* <td>Expand or collapse the group item if <code class="prettyprint">drillMode</code> is set to collapsible.
* When <code class="prettyprint">drillMode</code> is set to sliding, sublist will silde in.
* When <code class="prettyprint">drillMode</code> is set to none, group item will be selecetd.</td>
* </tr>
* <tr>
* <td><kbd>Press & Hold</kbd></td>
* <td>Display context menu</td>
* </tr>
* <tr>
* <td>Hierarchical Menu button</td>
* <td><kbd>Tap</kbd></td>
* <td>Open menu. Refer <a href="oj.ojButton.html#touch-section">menu button</a> touch documentation. Note: This is applicable only for Sliding Navigation List. </td>
* </tr>
* <tr>
* <td>Previous Icon or List Header</td>
* <td><kbd>Tap</kbd></td>
* <td>Collapses the sublist and slides to parent list. Note: This is applicable only for Sliding Navigation List. </td>
* </tr>
* </tbody>
* </table>
*
* @ojfragment touchDoc - Used in touch gesture section of classdesc, and standalone gesture doc
* @memberof oj.ojNavigationList
*/
/**
* <table class="keyboard-table">
* <thead>
* <tr>
* <th>Target</th>
* <th>Key</th>
* <th>Action</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td rowspan="10">List Item</td>
* <td><kbd>Enter</kbd> or <kbd>Space</kbd></td>
* <td>Selects list item.</td>
* </tr>
* <tr>
* <td><kbd>UpArrow</kbd></td>
* <td>Moves focus to the previous visible list item.</td>
* </tr>
* <tr>
* <td><kbd>DownArrow</kbd></td>
* <td>Moves focus to the next visible list item</td>
* </tr>
* <tr>
* <td><kbd>RightArrow</kbd> (<kbd>LeftArrow</kbd> in RTL)</td>
* <td>For horizontal navigation list,focus will be moved to next visible item.
* </td>
* </tr>
* <tr>
* <td><kbd>LeftArrow</kbd> (<kbd>RightArrow</kbd> in RTL)</td>
* <td>For horizontal navigation list,focus will be moved to previous visible item.</td>
* </tr>
* <tr>
* <td><kbd>Home</kbd></td>
* <td>Moves focus to the first visible list item.</td>
* </tr>
* <tr>
* <td><kbd>End</kbd></td>
* <td>Moves focus to the last visible list item.</td>
* </tr>
* <tr>
* <td><kbd>F2</kbd></td>
* <td>If focus is on a list item, pressing F2 will make its contents accessible using TAB.</td>
* </tr>
* <tr>
* <td><kbd>Esc</kbd></td>
* <td>When F2 mode is enabled, press Esc to exit F2 mode.</td>
* </tr>
* <tr>
* <td><kbd>Shift+Tab</kbd></td>
* <td>Move fous to hierarchical menu button.Only applicable for sliding navigation list and when hierarchial menu button is enabled.</td>
* </tr>
* <tr>
* <td rowspan="2">Group Item</td>
* <td><kbd>RightArrow</kbd> (<kbd>LeftArrow</kbd> in RTL)</td>
* <td>If focus is on collapsed node, expands the sub list.</td>
* </tr>
* <tr>
* <td><kbd>LeftArrow</kbd> (<kbd>RightArrow</kbd> in RTL)</td>
* <td>If focus is on expanded node, collapses the sub list.</td>
* </tr>
* <tr>
* <td>List Item in sublist</td>
* <td><kbd>Esc</kbd></td>
* <td>Applicable only for sliding navigation list. If focus is in a sub list, closes the sublist and moves focus to the parent list item.</td>
* </tr>
* <tr>
* <td rowspan="3">Hierarchical Menu button</td>
* <td><kbd>Enter</kbd></td>
* <td>Open menu. Refer <a href="oj.ojButton.html#keyboard-section">menu button</a> keyboard documentation. Note: This target is visible only for Sliding Navigation List.</td>
* </tr>
* <tr>
* <td><kbd>Tab</kbd></td>
* <td>Moves focus to current list item. Note: This target is visible only for Sliding Navigation List. </td>
* </tr>
* <tr>
* <td><kbd>Shift + Tab</kbd></td>
* <td>Moves focus to Previous Icon. Note: This target is visible only for Sliding Navigation List.</td>
* </tr>
* <tr>
* <td rowspan="2">Previous Icon or List Header</td>
* <td><kbd>Enter</kbd></td>
* <td>Collapses the sublist and slides to parent list.Note: This target is visible only for Sliding Navigation List. </td>
* </tr>
* <tr>
* <td><kbd>Tab</kbd></td>
* <td>Moves focus to Hierarchical Menu button. Note: This target is visible only for Sliding Navigation List. </td>
* </tr>
*
* </tbody>
* </table>
*
*
* @ojfragment keyboardDoc - Used in keyboard section of classdesc, and standalone gesture doc
* @memberof oj.ojNavigationList
*/
});
}());
Source: src/main/javascript/oracle/oj/ojnavigationlist/ojnavigationlist.js
Oracle® JavaScript Extension Toolkit (JET)
1.1.2
E65298-01