Mixin: module:delite/KeyNav

module:delite/KeyNav

A mixin to allow arrow key and letter key navigation of child Elements. It can be used by delite/Container based widgets with a flat list of children, or more complex widgets like a Tree.

To use this mixin, the subclass must:

  • Implement one method for each keystroke that subclass wants to handle, with names based on the keys defined in delite/keys. For example, DOWN_ARROW --> downArrowKeyHandler(). The method takes two parameters: the events, and the currently navigated node. For BIDI support, the left and right arrows are handled specially, mapped to the previousArrowKeyHandler() and nextArrowKeyHandler() methods in LTR mode, or reversed in RTL mode. Most subclasses will want to implement either previousArrowKeyHandler() and nextArrowKeyHandler(), or downArrowKeyHandler() and upArrowKeyHandler().
  • Set all navigable descendants' initial tabIndex to "-1"; both initial descendants and any descendants added later, by for example addChild(). Exception: if focusDescendants is false then the descendants shouldn't have any tabIndex at all.
  • Define descendantSelector as a function or string that identifies navigable child Elements.
  • If the descendant elements contain text, they should have a label attribute. KeyNav uses the label attribute for letter key navigation.
Source:

Extends

Show inherited

Members

<protected> attached :boolean

Set to true when attachedCallback() has completed.

Type:
  • boolean
Inherited From:
Source:

<protected> baseClass :string

Root CSS class of the widget (ex: "d-text-box")

Type:
  • string
Inherited From:
Source:

<protected> created :boolean

Set to true when createdCallback() has completed.

Type:
  • boolean
Inherited From:
Source:

<protected, constant> descendantSelector :string|function

Selector to identify which descendant Elements are navigable via arrow keys or keyboard search. Note that for subclasses like a Tree, one navigable node could be a descendant of another.

It's either a function that takes an Element parameter and returns true/false, or a CSS selector string, for example ".list-item".

By default, the direct DOM children of this widget are considered the selectable descendants.

Must be set in the prototype rather than on the instance.

Type:
  • string | function
Source:

<protected> focusDescendants :boolean

When true, focus the descendant widgets as the user navigates to them via arrow keys or keyboard letter search. When false, rather than focusing the widgets, it merely sets navigatedDescendant, and sets the d-active-descendant class on the descendant widget the user has navigated to.

False mode is intended for widgets like ComboBox where the focus is somewhere outside this widget (typically on an <input>) and keystrokes are merely being forwarded to the KeyNav widget.

When set to false:

  • All navigable descendants must specify an id.
  • Navigable descendants shouldn't have any tabIndex (as opposed to having tabIndex=-1).
  • The focused element should specify aria-owns to point to this KeyNav Element.
  • The focused Element must be kept synced so that aria-activedescendant points to the currently navigated descendant. Do this responding to the keynav-child-navigated event emitted by this widget, or by calling observe() and monitoring changed to navigatedDescendant.
  • The focused Element must forward keystrokes by calling emit("keydown", ...) and/or emit("keypress", ...) on this widget.
  • You must somehow set the initial navigated descendant, typically by calling navigateToFirst() either when the the dropdown is opened, or on the first call to downArrowKeyHandler().
  • You must have some CSS styling so that the currently navigated node is apparent.

See http://www.w3.org/WAI/GL/wiki/Using_aria-activedescendant_to_allow_changes_in_focus_within_widgets_to_be_communicated_to_Assistive_Technology#Example_1:_Combobox for details.

Type:
  • boolean
Default Value:
  • true
Source:

<protected> focused :boolean

This widget or a widget it contains has focus, or is "active" because it was recently clicked.

Type:
  • boolean
Inherited From:
Default Value:
  • false
Source:

The currently navigated descendant, or null if there isn't one.

Type:
  • Element
Source:

<protected> started :boolean

Set to true when startup() has completed.

Type:
  • boolean
Inherited From:
Source:

<protected> template :function

Value returned by delite/handlebars! or compatible template engine. Specifies how to build the widget DOM initially and also how to update the DOM when widget properties change.

Type:
  • function
Inherited From:
Source:

<protected, constant> widgetId :number

Unique id for this widget, separate from id attribute (which may or may not be set). Useful when widget creates subnodes that need unique id's.

Type:
  • number
Inherited From:
Source:

Methods

<protected> _get(name) → {*}

Internal helper for directly accessing an attribute value.

Directly get the value of an attribute on an object, bypassing any accessor getter. It is designed to be used by descendant class if they want to access the value in their custom getter before returning it.

Parameters:
Name Type Description
name string

Name of property.

Inherited From:
Source:
Returns:

Value of property.

Type
*

<protected> _set(name, value)

Internal helper for directly setting a property value without calling the custom setter.

Directly change the value of an attribute on an object, bypassing any accessor setter. Also notifies callbacks registered via observe(). Custom setters should call _set to actually record the new value.

Parameters:
Name Type Description
name string

The property to set.

value *

Value to set the property to.

Inherited From:
Source:

attachedCallback()

Called when the element is added to the document, after createdCallback() completes. Note though that for programatically created custom elements, the app must manually call this method.

This method is automatically chained, so subclasses generally do not need to use dcl.superCall(), dcl.advise(), etc.

Inherited From:
Source:
Fires:

computeProperties(newValues, oldValues)

Callback function to calculate computed properties upon property changes.

Parameters:
Name Type Description
newValues Object

The hash table of new property values, keyed by property names.

oldValues Object

The hash table of old property values, keyed by property names.

Inherited From:
Source:

<protected> createdCallback()

Kick off the life-cycle of a widget.

Calls a number of widget methods (preRender(), render(), and postRender()), some of which of you'll want to override.

Of course, adventurous developers could override createdCallback entirely, but this should only be done as a last resort.

Inherited From:
Source:

<protected> defer(fcn, delay) → {Object}

Wrapper to setTimeout to avoid deferred functions executing after the originating widget has been destroyed.

Parameters:
Name Type Description
fcn function

Function to be executed after specified delay (or 0ms if no delay specified).

delay number

Delay in ms, defaults to 0.

Inherited From:
Source:
Returns:

Handle with a remove method that deschedules the callback from being called.

Type
Object

deliver()

Synchronously deliver change records for computed properties and then UI rendering so that refreshingRendering() is called if there are pending change records.

Inherited From:
Source:

deliverComputing()

Synchronously deliver change records for computed properties so that refreshingComputing() is called if there are pending change records.

Inherited From:
Source:

destroy()

Destroy this widget and its descendants.

Inherited From:
Source:

discardChanges()

Discard change records.

Inherited From:
Source:

discardComputing()

Discard change records for computed properties.

Inherited From:
Source:

<protected> emit(type, eventObj) → {boolean}

Emits a synthetic event of specified type, based on eventObj.

Parameters:
Name Type Argument Description
type string

Name of event.

eventObj Object <optional>

Properties to mix in to emitted event. Can also contain bubbles and cancelable properties to control how the event is emitted.

Inherited From:
Source:
Returns:

True if the event was not canceled, false if it was canceled.

Type
boolean
Example
myWidget.emit("query-success", {});

<protected> endKeyHandler(evt, navigatedDescendant)

Called on end key.

Parameters:
Name Type Description
evt Event
navigatedDescendant Element
Source:

findCustomElements(root)

Search subtree under root returning custom elements found.

Parameters:
Name Type Argument Description
root Element <optional>

Node to search under.

Inherited From:
Source:

focus()

/** Default focus() implementation: navigate to the first navigable descendant. Note that if focusDescendants is false, this will merely set the d-active-descendant class rather than actually focusing the descendant.

Source:

getEnclosingWidget(node)

Returns the widget whose DOM tree contains the specified DOMNode, or null if the node is not contained within the DOM tree of any widget

Parameters:
Name Type Description
node Element
Inherited From:
Source:

<protected> getNext(child, dir) → {Element}

Returns the next or previous navigable descendant, relative to "child". If "child" is this, then it returns the first focusable descendant (when dir === 1) or last focusable descendant (when dir === -1).

Parameters:
Name Type Description
child Element

The current child Element.

dir number

1 = after, -1 = before

Source:
Returns:
Type
Element

getParent()

Returns the parent widget of this widget.

Inherited From:
Source:

<protected> homeKeyHandler(evt, navigatedDescendant)

Called on home key.

Parameters:
Name Type Description
evt Event
navigatedDescendant Element
Source:

<protected> initializeInvalidating()

Sets up observers, one for computed properties, one for UI rendering. Normally this method is called automatically by the constructor, and should not be called manually, but the method is exposed for custom elements since they do not call the constructor() method.

Inherited From:
Source:

<protected> isLeftToRight() → {boolean}

Return this widget's explicit or implicit orientation (true for LTR, false for RTL).

Inherited From:
Source:
Returns:
Type
boolean

mix(hash)

Set a hash of properties on a Stateful instance.

Parameters:
Name Type Description
hash Object

Hash of properties.

Inherited From:
Source:
Example
myObj.mix({
    foo: "Howdy",
    bar: 3
});

Navigate to the specified descendant. Note that if focusDescendants is false, this will merely set the d-active-descendant class rather than actually focusing the descendant.

Parameters:
Name Type Description
child Element

Reference to the descendant.

last boolean

If true and if descendant has multiple focusable nodes, focus the last one instead of the first one. This assumes that the child's focus() method takes a boolean parameter where true means to focus the last child.

Source:

Navigate to the first navigable descendant. Note that if focusDescendants is false, this will merely set the d-active-descendant class rather than actually focusing the descendant.

Source:

Navigate to the last navigable descendant. Note that if focusDescendants is false, this will merely set the d-active-descendant class rather than actually focusing the descendant.

Source:

notifyCurrentValue(name)

Notify current value to observers. Handy to manually schedule invocation of observer callbacks when there is no change in value.

Parameters:
Name Type Description
name string

The property name.

Inherited From:
Source:

observe(callback) → {module:decor/Stateful.PropertyListObserver}

Observe for change in properties. Callback is called at the end of micro-task of changes with a hash table of old values keyed by changed property. Multiple changes to a property in a micro-task is squashed .

Parameters:
Name Type Description
callback function

The callback.

Inherited From:
Source:
Returns:

The observer that can be used to stop observation or synchronously deliver/discard pending change records.

Type
module:decor/Stateful.PropertyListObserver
Example
var stateful = new (dcl(Stateful, {
        foo: undefined,
        bar: undefined,
        baz: undefined
    }))({
        foo: 3,
        bar: 5,
        baz: 7
    });
stateful.observe(function (oldValues) {
    // oldValues is {foo: 3, bar: 5, baz: 7}
});
stateful.foo = 4;
stateful.bar = 6;
stateful.baz = 8;
stateful.foo = 6;
stateful.bar = 8;
stateful.baz = 10;

on(type, func, node) → {Object}

Call specified function when event occurs.

Note that the function is not run in any particular scope, so if (for example) you want it to run in the widget's scope you must do myWidget.on("click", myWidget.func.bind(myWidget)).

Parameters:
Name Type Argument Description
type string

Name of event (ex: "click").

func function

Callback function.

node Element <optional>

Element to attach handler to, defaults to this.

Inherited From:
Source:
Returns:

Handle with remove() method to cancel the event.

Type
Object

<protected> own() → {Array.<Object>}

Track specified handles and remove/destroy them when this instance is destroyed, unless they were already removed/destroyed manually.

Inherited From:
Source:
Returns:

The array of specified handles, so you can do for example: var handle = this.own(on(...))[0];

Type
Array.<Object>

<protected> parseAttribute(name, value)

Helper for parsing declarative widgets. Interpret a given attribute specified in markup, returning either:

  • undefined: ignore
  • {prop: prop, value: value}: set this[prop] = value
  • {event: event, callback: callback}: call this.on(event, callback)
Parameters:
Name Type Description
name string

Attribute name.

value string

Attribute value.

Inherited From:
Source:

<protected> parseFunctionAttribute(value, params)

Helper to parse function attribute in markup. Unlike _parsePrototypeAttr(), does not require a corresponding widget property. Functions can be specified as global variables or as inline javascript:

Parameters:
Name Type Description
value string

Value of the attribute.

params Array.<string>

When generating a function from inline javascript, give it these parameter names.

Inherited From:
Source:

<protected> placeAt(reference, position) → {module:delite/Widget}

Place this widget somewhere in the dom, and allow chaining.

Parameters:
Name Type Argument Description
reference string | Element | DocumentFragment

Element, DocumentFragment, or id of Element to place this widget relative to.

position string | number <optional>

Numeric index or a string with the values:

  • number - place this widget as n'th child of reference node
  • "first" - place this widget as first child of reference node
  • "last" - place this widget as last child of reference node
  • "before" - place this widget as previous sibling of reference node
  • "after" - place this widget as next sibling of reference node
  • "replace" - replace specified reference node with this widget
  • "only" - replace all children of reference node with this widget
Inherited From:
Source:
Returns:

This widget, for chaining.

Type
module:delite/Widget
Examples
// create a Button with no srcNodeRef, and place it in the body:
var button = new Button({ label:"click" }).placeAt(document.body);
// place a new button as the first element of some div
var button = new Button({ label:"click" }).placeAt("wrapper","first");
// create a contentpane and add it to a TabContainer
var tc = document.getElementById("myTabs");
new ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)

<protected> postRender()

Processing after the DOM fragment is created.

Called after the DOM fragment has been created, but not necessarily added to the document. Do not include any operations which rely on node dimensions or placement.

This method is automatically chained, so subclasses generally do not need to use dcl.superCall(), dcl.advise(), etc.

Inherited From:
Source:

<protected> preRender()

Processing before render().

This method is automatically chained, so subclasses generally do not need to use dcl.superCall(), dcl.advise(), etc.

Inherited From:
Source:

<protected> processConstructorParameters()

Called after Object is created to process parameters passed to constructor.

Inherited From:
Source:

refreshRendering(newValues, oldValues)

Callback function to render UI upon property changes.

Parameters:
Name Type Description
newValues Object

The hash table of new property values, keyed by property names.

oldValues Object

The hash table of old property values, keyed by property names.

Inherited From:
Source:

<protected> render()

Construct the UI for this widget, filling in subnodes and/or text inside of this. Most widgets will leverage delite/handlebars! to set template, rather than defining this method.

Inherited From:
Source:

<protected> setClassComponent(component, value, node)

Helper method to set a class (or classes) on a given node, removing the class (or classes) set by the previous call to setClassComponent() for the specified component and node. Used mainly by template.js to set classes without overwriting classes set by the user or other code (ex: CssState).

Parameters:
Name Type Argument Description
component string

Specifies the category.

value string

Class (or classes) to set.

node HTMLElement <optional>

The node to set the property on; defaults to widget root node.

Inherited From:
Source:

<protected> setOrRemoveAttribute(node, name, value)

Helper method to set/remove an attribute based on the given value:

  • If value is undefined, the attribute is removed. Useful for attributes like aria-valuenow.
  • If value is boolean, the attribute is set to "true" or "false". Useful for attributes like aria-selected.
  • If value is a number, it's converted to a string.
Parameters:
Name Type Description
node Element

The node to set the property on.

name string

Name of the property.

value string

Value of the property.

Inherited From:
Source:

startup()

Called after a widget and its children have been created and added to the page, and all related widgets have finished their creation cycle, up through postRender().

Most widgets should add initialization code to attachedCallback() rather than startup(). Code in startup() is only necessary for widgets that can't be initialized until related widgets have been created. For example, hypothetically, if DisplayContainer#selectedChildId could not be processed until the specified child DOM node existed, and had been upgraded from a plain DOM node into a widget. startup() may be removed in the future.

Note that startup() may be called while the widget is still hidden, for example if the widget is inside a hidden dialog or an unselected tab of a TabContainer, so the widget shouldn't try to do layout in startup().

Inherited From:
Source:

Events

customelement-attached

Dispatched after the CustomElement has been attached. This is useful to be notified when an HTMLElement has been upgraded to a CustomElement and attached to the DOM, in particular on browsers supporting native Custom Element.

Inherited From:
Source:
Example
element.addEventListener("customelement-attached", function (evt) {
     console.log("custom element: "+evt.target.id+" has been attached");
});

keynav-child-navigated

Dispatched after the user has selected a different descendant, by clicking, arrow keys, or keyboard search.

Properties:
Name Type Description
oldValue number

The previously selected item.

newValue number

The new selected item.

Source:
Example
widget.on("keynav-child-navigated", function (evt) {
	console.log("old value: " + evt.oldValue);
	console.log("new value: " + evt.newValue);
}