/**
* Copyright (c) 2015, Oracle and/or its affiliates.
* All rights reserved.
*/
/**
* @ojcomponent oj.ojListView
* @augments oj.baseComponent
* @since 1.1.0
*
* @classdesc
* <h3 id="listViewOverview-section">
* JET ListView Component
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#listViewOverview-section"></a>
* </h3>
*
* <p>Description: The JET ListView enhances a HTML list element into a themable, WAI-ARIA compliant, mobile friendly component with advance interactive features.</p>
*
* <h3 id="data-section">
* Data
* <a class="bookmarkable-link" title="Bookmarkable Link" href="#data-section"></a>
* </h3>
* <p>The JET ListView gets its data in three different ways. The first way is from a TableDataSource. There are several types of TableDataSource that
* are available out of the box:</p>
* <ul>
* <li>oj.ArrayTableDataSource</li>
* <li>oj.CollectionTableDataSource</li>
* <li>oj.PagingTableDataSource</li>
* </ul>
*
* <p><b>oj.ArrayTableDataSource</b> - Use this when the underlying data is an array object or an observableArray. In the observableArray case, ListView will automatically react
* when items are added or removed from the array. See the documentation for oj.ArrayTableDataSource for more details on the available options.</p>
*
* <p><b>oj.CollectionTableDataSource</b> - Use this when oj.Collection is the model for the underlying data. Note that the ListView will automatically react to model event from
* the underlying oj.Collection. See the documentation for oj.CollectionTableDataSource for more details on the available options.</p>
*
* <p><b>oj.PagingTableDataSource</b> - Use this when the ListView is driven by an associating ojPagingControl. See the documentation for oj.PagingTableDataSource for more
* details on the available options.</p>
*
* <p>The second way is from a TreeDataSource. This is typically used to display data that are logically categorized in groups. There are several types
* of TreeDataSource that are available out of the box:</p>
* <ul>
* <li>oj.JsonTreeDataSource</li>
* <li>oj.CollectionTreeDataSource</li>
* </ul>
*
* <p><b>oj.JsonTreeDataSource</b> - Use this when the underlying data is a JSON object. See the documentation for oj.JsonTreeDataSource for more details on the available options.</p>
*
* <p><b>oj.CollectionTreeDataSource</b> - Use this when oj.Collection is the model for each group of data. See the documentation for oj.CollectionTableDataSource
* for more details on the available options.</p>
*
* <p>Finally, ListView also supports static HTML content as data. The structure of the content can be either flat or hierarhical.</p>
*
* <p>Example of flat static content</p>
* <pre class="prettyprint">
* <code><ul id="listView" data-bind="ojComponent: {component: 'ojListView'}">
* <li><a id="item1" href="#">Item 1</a></li>
* <li><a id="item2" href="#">Item 2</a></li>
* <li><a id="item3" href="#">Item 3</a></li>
* </ul>
* </code></pre>
*
* <p>Example of hierarchical static content</p>
* <pre class="prettyprint">
* <code><ul id="listView" data-bind="ojComponent: {component: 'ojListView'}">
* <li><a id="group1" href="#">Group 1</a>
* <ul>
* <li><a id="item1-1" href="#">Item 1-1</a></li>
* <li><a id="item1-2" href="#">Item 1-2</a></li>
* </ul>
* </li>
* <li><a id="group2" href="#">Group 2</a>
* <ul>
* <li><a id="item2-1" href="#">Item 2-1</a></li>
* <li><a id="item2-2" href="#">Item 2-2</a></li>
* </ul>
* </li>
* </ul>
* </code></pre>
*
* <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"}
*
* <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 ListView 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 ListView makes it hard for user to find what they are looking for, but affects the load time and
* scrolling performance as well. If displaying large number of items is neccessary, use a paging control with ListView
* to limit the number of items to display at a time. Setting <code class="prettyprint">scrollPolicy</code> to
* 'loadMoreOnScroll' will also reduce the number of items to display initially.</p>
*
* <h4>Item Content</h4>
* <p>ListView 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 ListView.</p>
*
* <h4>Expand All</h4>
* <p>While ListView provides a convenient way to initially expand all group items in the ListView, 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>
*/
oj.__registerWidget('oj.ojListView', $['oj']['baseComponent'],
{
widgetEventPrefix: 'oj',
options:
{
/**
* The current item. This is typically the item the user navigated to. Note that if current
* is set to an item that is currently not available (not fetched in highwater mark scrolling case or
* inside a collapsed parent node), then the value is ignored.
*
* @expose
* @public
* @instance
* @memberof! oj.ojListView
* @type {Object}
* @default <code class="prettyprint">null</code>
*
* @example <caption>Get the current item:</caption>
* $( ".selector" ).ojListView("option", "currentItem");
*
* @example <caption>Set the current item on the ListView during initialization:</caption>
* $(".selector").ojListView({"currentItem", "item2"});
*/
currentItem: null,
/**
* The data source for the ListView 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.ojListView
* @instance
* @type {oj.TableDataSource|oj.TreeDataSource}
* @default <code class="prettyprint">null</code>
*
* @example <caption>Initialize the ListView with a one-dimensional array:</caption>
* $( ".selector" ).ojListView({ "data": new oj.ArrayTableDataSource([1,2,3])});
*
* @example <caption>Initialize the ListView with an oj.Collection:</caption>
* $( ".selector" ).ojListView({ "data": new oj.CollectionTableDataSource(collection)});
*/
data: null,
/**
* Changes the expand and collapse operations on ListView. If "none" is specified, then
* the current expanded state is fixed and user cannot expand or collapse an item.
*
* @expose
* @memberof! oj.ojListView
* @instance
* @type {string}
* @default <code class="prettyprint">collapsible</code>
* @ojvalue {string} "collapsible" group item can be expanded or collapsed by user.
* @ojvalue {string} "none" the expand state of a group item cannot be changed by user.
*
* @example <caption>Initialize the list view with a fixed expanded state:</caption>
* $( ".selector" ).ojListView({ "drillMode": "none" });
*/
drillMode: "collapsible",
/**
* Specifies which items in ListView 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 ListView 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.
*
* @expose
* @memberof! oj.ojListView
* @instance
* @type {Array.<Object>|string}
* @default <code class="prettyprint">[]</code>
*
* @example <caption>Initialize the list view with a fixed expanded state:</caption>
* $( ".selector" ).ojListView({ "expanded": ["group1", "group2"] });
*/
expanded: "auto",
/**
* The item option contains a subset of options for items.
*
* @expose
* @memberof! oj.ojListView
* @instance
*/
item: {
/**
* Whether the item is focusable. An item that is not focusable cannot be clicked on or navigated to.
* See <a href="#context-section">itemContext</a> in the introduction to see the object passed into the focusable function.
*
* @expose
* @alias item.focusable
* @memberof! oj.ojListView
* @instance
* @type {function(Object)|boolean}
* @default <code class="prettyprint">true</code>
*
* @example <caption>Initialize the ListView such that only leaf items are focusable:</caption>
* $( ".selector" ).ojListView({ "data":data, "item": { "focusable": function(itemContext) {
* return itemContext['leaf'];}}});
*/
focusable: true,
/**
* 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, ListView will treat the data as a String.
*
* @expose
* @alias item.renderer
* @memberof! oj.ojListView
* @instance
* @type {function(Object)|null}
* @default <code class="prettyprint">null</code>
*
* @example <caption>Initialize the ListView with a renderer:</caption>
* $( ".selector" ).ojListView({ "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" ).ojListView( "option", "item.renderer", myFunction});
*/
renderer: null,
/**
* Whether the item is selectable. Note that if selectionMode is set to "none" this option is ignored. In addition,
* if selectable is set to true, then the focusable option is automatically overridden and set to true.
* 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.ojListView
* @instance
* @type {function(Object)|boolean}
* @default <code class="prettyprint">true</code>
*
* @example <caption>Initialize the ListView such that the first 3 items are not selectable:</caption>
* $( ".selector" ).ojListView({ "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.ojListView
* @instance
* @type {string|null}
* @default <code class="prettyprint">null</code>
*
* @example <caption>Specify the <code class="prettyprint">template</code> when initializing ListView:</caption>
* // set the template
* <ul id="listview" data-bind="ojComponent: {component: 'ojListView', data: dataSource, item: {template: 'my_template'}}"></ul>
*/
},
/**
* Specifies the mechanism used to scroll the data inside the list view. Possible values are: auto and loadMoreOnScroll.
* When loadMoreOnScroll is specified, additional data is fetched when the user scrolls to the bottom of the ListView.
* Note that currently this option is only available when TableDataSource is used.
*
* @expose
* @memberof! oj.ojListView
* @instance
* @type {string|null}
* @default <code class="prettyprint">auto</code>
* @ojvalue {string} "auto" the behavior is determined by the component.
* @ojvalue {string} "loadMoreOnScroll" additional data is fetched when the user scrolls to the bottom of the ListView.
*
* @example <caption>Initialize the list view with a fixed expanded state:</caption>
* $( ".selector" ).ojListView({ "scrollPolicy": "loadMoreOnScroll" });
*/
scrollPolicy: "auto",
/**
* scrollPolicy options.
* <p>
* The following options are supported:
* <ul>
* <li>fetchSize: Fetch size for scroll.</li>
* <li>maxCount: Maximum rows which will be displayed before fetching more rows will be stopped.</li>
* </ul>
* When scrollPolicy is loadMoreOnScroll, the next block of rows is fetched
* when the user scrolls to the end of the list. The fetchSize option
* determines how many rows are fetched in each block.
* Note that currently this option is only available when TableDataSource is used.
*
* @expose
* @instance
* @memberof! oj.ojListView
* @type {Object.<string, number>|null}
* @property {number} fetchSize the number of rows to fetch in each block of rows
* @default <code class="prettyprint">25</code>
* @property {number} maxCount the maximum total number of rows to fetch
* @default <code class="prettyprint">500</code>
*/
scrollPolicyOptions: {'fetchSize': 25, 'maxCount': 500},
/**
* The current selections in the ListView. An empty array indicates nothing is selected.
*
* @expose
* @memberof! oj.ojListView
* @instance
* @type {Array.<Object>}
* @default <code class="prettyprint">[]</code>
*
* @example <caption>Initialize the list view with specific selection:</caption>
* $( ".selector" ).ojListView({ "data":data, "selection": ["item1", "item2"] });
*/
selection: [],
/**
* Specifies whether selection can be made and the cardinality of selection in the ListView.
* Selection is initially disabled, but setting the value to null will disable selection.
*
* @expose
* @memberof! oj.ojListView
* @instance
* @type {string}
* @default <code class="prettyprint">none</code>
* @ojvalue {string} "none" selection is disabled.
* @ojvalue {string} "single" only one item can be selected at a time.
* @ojvalue {string} "multiple": multiple items can be selected at the same time.
*
* @example <caption>Initialize the list view to enable multiple selection:</caption>
* $( ".selector" ).ojListView({ "data":data, "selectionMode": "multiple" });
*/
selectionMode: "none",
/**
* Triggered before the current item is changed via the <code class="prettyprint">current</code> option or via the UI.
*
* @expose
* @event
* @memberof! oj.ojListView
* @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 ListView with the <code class="prettyprint">beforeCurrentItem</code> callback specified:</caption>
* $( ".selector" ).ojListView({
* "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 before an item is expanded via the <code class="prettyprint">expanded</code> option,
* the <code class="prettyprint">expand</code> method, or via the UI.
*
* @expose
* @event
* @memberof! oj.ojListView
* @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 expanded
* @property {jQuery} ui.item the item to be expanded
*
* @example <caption>Initialize the ListView with the <code class="prettyprint">beforeExpand</code> callback specified:</caption>
* $( ".selector" ).ojListView({
* "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 before an item is collapsed via the <code class="prettyprint">expanded</code> option,
* the <code class="prettyprint">collapse</code> method, or via the UI.
*
* @expose
* @event
* @memberof! oj.ojListView
* @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 collapsed
* @property {jQuery} ui.item the item to be collapsed
*
* @example <caption>Initialize the ListView with the <code class="prettyprint">beforeCollapse</code> callback specified:</caption>
* $( ".selector" ).ojListView({
* "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 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.ojListView
* @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 ListView with the <code class="prettyprint">expand</code> callback specified:</caption>
* $( ".selector" ).ojListView({
* "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 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.ojListView
* @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 ListView with the <code class="prettyprint">expand</code> callback specified:</caption>
* $( ".selector" ).ojListView({
* "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.
*
* @expose
* @event
* @memberof! oj.ojListView
* @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").ojListView({
* '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,
/**
* Triggered after all items in the ListView has been rendered. Note that in the highwatermark scrolling case,
* all items means the items that are fetched so far.
*
* @expose
* @event
* @memberof! oj.ojListView
* @instance
* @property {Event} event <code class="prettyprint">jQuery</code> event object
* @property {Object} ui Parameters
*
* @example <caption>Initialize the ListView with the <code class="prettyprint">ready</code> callback specified:</caption>
* $( ".selector" ).ojListView({
* "ready": function( event, ui ) {}
* });
*
* @example <caption>Bind an event listener to the <code class="prettyprint">ojready</code> event:</caption>
* $( ".selector" ).on( "ojready", function( event, ui ) {} );
*/
ready: null
},
/**
* Create the listview
* @override
* @memberof! oj.ojListView
* @protected
*/
_ComponentCreate: function()
{
this._super();
this._setup();
},
/**
* Initialize the listview
* @private
*/
_setup: function()
{
var opts = {};
opts.element = this.element;
opts.ojContext = this;
opts = $.extend(this.options, opts);
this.listview = new oj._ojListView();
this.listview.init(opts);
},
/**
* Initialize the listview after creation
* @protected
* @override
* @memberof! oj.ojListView
*/
_AfterCreate: function ()
{
this._super();
this.listview.afterCreate();
},
/**
* Destroy the list view
* @memberof! oj.ojListView
* @private
*/
_destroy: function()
{
this.listview.destroy();
this._super();
},
/**
* 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.listview.notifyContextMenuGesture(menu, event, eventType);
},
/**
* 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.listview.setOptions(options, flags);
// updates the options last
this._super(options, flags);
if (needRefresh)
{
this.listview.refresh();
}
},
/**
* Sets a single option
* @param {Object} key the key for the option
* @param {Object} value the value for the option
* @override
* @private
*/
_setOption: function(key, value)
{
// checks whether value is valid for the key
var valid = true;
if (key == "selectionMode")
{
valid = (value == "none" || value == "single" || value == "multiple");
}
else if (key == "drillMode")
{
valid = (value == "collapsible" || value == "none");
}
else if (key == "scrollPolicy")
{
valid = (value == "auto" || value == "loadMoreOnScroll");
}
// update option if it's valid otherwise throw an error
if (valid)
{
this._super(key, value);
}
else
{
throw "Invalid value: "+value+" for key: "+key;
}
},
/**
* 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.listview.notifyDetached();
},
/**
* Invoked when application calls oj.Components.subtreeShown.
* @override
* @private
*/
_NotifyShown: function()
{
this.listview.notifyShown();
},
/********************************* public methods **************************************/
/**
* Returns a jQuery object containing the root dom element of the table
*
* <p>This method does not accept any arguments.
*
* @expose
* @override
* @memberof oj.ojListView
* @instance
* @return {jQuery} the root DOM element of list
*/
'widget' : function ()
{
return this.listview.getRootElement();
},
/**
* Redraw the entire list view after having made some external modifications.
*
* <p>This method does not accept any arguments.
*
* @expose
* @memberof! oj.ojListView
* @instance
*
* @example <caption>Invoke the <code class="prettyprint">refresh</code> method:</caption>
* $( ".selector" ).ojListView( "refresh" );
*/
refresh: function()
{
this._super();
this.listview.refresh();
},
/**
* Return the subcomponent node represented by the documented locator attribute values.
* <p>
* To lookup the expand/collapse icon the locator object should have the following:
* <ul>
* <li><b>subId</b>: 'oj-listview-icon'</li>
* <li><b>key</b>: the key of the item</li>
* </ul>
*
* @expose
* @memberof! oj.ojListView
* @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.listview.getNodeBySubId(locator);
},
/**
* <p>Returns the subId string for the given child DOM node. For more details, see
* <a href="#getNodeBySubId">getNodeBySubId</a>.
*
* @expose
* @memberof! oj.ojListView
* @instance
* @override
* @param {!Element} node - child DOM node
* @return {string|null} The subId for the DOM node, or <code class="prettyprint">null</code> when none is found.
*/
getSubIdByNode: function(node)
{
return this.listview.getSubIdByNode(node);
},
/**
* 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.ojListView
* @instance
* @param {Object} key the key of the item to expand
* @param {boolean} vetoable whether the event should be vetoable
*/
expand: function (key, vetoable)
{
this.listview.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.ojListView
* @instance
* @param {Object} key the key of the item to collapse
* @param {boolean} vetoable whether the event should be vetoable
*/
collapse: function (key, vetoable)
{
this.listview.collapseKey(key, vetoable, true);
},
/**
* Gets the key of currently expanded items.
*
* @expose
* @memberof oj.ojListView
* @instance
* @return {Array} array of keys of currently expanded items
*/
getExpanded: function ()
{
return this.listview.getExpanded();
}
// 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>Focus on the item. If <code class="prettyprint">selectionMode</code> is enabled, selects the item as well.</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.</td>
* </tr>
* <tr>
* <td><kbd>Press & Hold</kbd></td>
* <td>Display context menu</td>
* </tr>
* </tbody>
* </table>
*
* @ojfragment touchDoc - Used in touch gesture section of classdesc, and standalone gesture doc
* @memberof oj.ojListView
*/
/**
* <table class="keyboard-table">
* <thead>
* <tr>
* <th>Target</th>
* <th>Key</th>
* <th>Action</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <td rowspan = "13" nowrap>List Item</td>
* <td><kbd>F2</kbd></td>
* <td>Enters Actionable mode. This enables keyboard action on elements inside the item, including navigate between focusable elements inside the item.</td>
* </tr>
* <tr>
* <td><kbd>Esc</kbd></td>
* <td>Exits Actionable mode.</td>
* </tr>
* <tr>
* <td><kbd>Tab</kbd></td>
* <td>When in Actionable Mode, navigates to next focusable element within the item. If the last focusable element is reached, shift focus back to the first focusable element.
* When not in Actionable Mode, navigates to next focusable element on page (outside ListView).</td>
* </tr>
* <tr>
* <td><kbd>Shift+Tab</kbd></td>
* <td>When in Actionable Mode, navigates to previous focusable element within the item. If the first focusable element is reached, shift focus back to the last focusable element.
* When not in Actionable Mode, navigates to previous focusable element on page (outside ListView).</td>
* </tr>
* <tr>
* <td><kbd>DownArrow</kbd></td>
* <td>Move focus to the item below.</td>
* </tr>
* <tr>
* <td><kbd>UpArrow</kbd></td>
* <td>Move focus to the item above.</td>
* </tr>
* <tr>
* <td><kbd>Shift+DownArrow</kbd></td>
* <td>Extend the selection to the item below.</td>
* </tr>
* <tr>
* <td><kbd>Shift+UpArrow</kbd></td>
* <td>Extend the selection to the item above.</td>
* </tr>
* <tr>
* <td><kbd>Shift+F10</kbd></td>
* <td>Launch the context menu if there is one associated with the current item.</td>
* </tr>
* <tr>
* <td><kbd>Enter</kbd></td>
* <td>Selects the current item. No op if the item is already selected.</td>
* </tr>
* <tr>
* <td><kbd>Space</kbd></td>
* <td>Toggles to select and deselect the current item. If previous items have been selected, deselects them and selects the current item.</td>
* </tr>
* <tr>
* <td><kbd>Shift+Space</kbd></td>
* <td>Selects contiguous items from the last selected item to the current item.</td>
* </tr>
* <tr>
* <td><kbd>Ctrl+Space</kbd></td>
* <td>Toggles to select and deselect the current item while maintaining previous selected items.</td>
* </tr>
* <tr>
* <td rowspan = "2" nowrap>Group Item</td>
* <td><kbd>LeftArrow</kbd></td>
* <td>Collapse the current item if it is expanded and is collapsible. For non-hierarchical data, do nothing.</td>
* </tr>
* <tr>
* <td><kbd>RightArrow</kbd></td>
* <td>Expand the current item if it has children and is expandable. For non-hierarchical data, do nothing.</td>
* </tr>
* </tbody>
* </table>
*
* @ojfragment keyboardDoc - Used in keyboard section of classdesc, and standalone gesture doc
* @memberof oj.ojListView
*/
});
////////////////// SUB-IDS //////////////////
/**
* <p>Sub-ID for the ojListView component's disclosure icon in group items. See the <a href="#getNodeBySubId">getNodeBySubId</a>
* method for details.</p>
*
* @ojsubid
* @member
* @name oj-listview-icon
* @memberof oj.ojListView
* @instance
*
* @example <caption>Get the disclosure icon for the group item with key 'foo':</caption>
* var node = $( ".selector" ).ojListView( "getNodeBySubId", {'subId': 'oj-listview-icon', 'key': 'foo'} );
*/
Source: src/main/javascript/oracle/oj/ojlistview/ojlistview.js
Oracle® JavaScript Extension Toolkit (JET)
1.1.2
E65298-01