dijit/_KeyNavContainer.js

  • Provides:

    • dijit._KeyNavContainer
  • dijit._KeyNavContainer

    • type
      Function
    • chains:
      • dijit._Container: (prototype)
      • dijit._Container: (call)
    • summary
      A _Container with keyboard navigation of its children.
    • description
      To use this mixin, call connectKeyNavHandlers() in
      postCreate() and call startupKeyNavChildren() in startup().
      It provides normalized keyboard and focusing code for Container
      widgets.
  • dijit._KeyNavContainer.focusedChild

    • tags: protected
    • type
      Widget
    • summary
      The currently focused child widget, or null if there isn't one
  • dijit._KeyNavContainer.tabIndex

    • type
      Integer
    • summary
      Tab index of the container; same as HTML tabIndex attribute.
      Note then when user tabs into the container, focus is immediately
      moved to the first item in the container.
  • dijit._KeyNavContainer._keyNavCodes

    • type
      Object
    • summary
  • dijit._KeyNavContainer.connectKeyNavHandlers

    • type
      Function
    • parameters:
      • prevKeyCodes: (typeof dojo.keys[])
      • nextKeyCodes: (typeof dojo.keys[])
        dojo.keys[]
        Key codes for navigating to the next child.
    • source: [view]
         var keyCodes = (this._keyNavCodes = {});
         var prev = dojo.hitch(this, this.focusPrev);
         var next = dojo.hitch(this, this.focusNext);
         dojo.forEach(prevKeyCodes, function(code){ keyCodes[code] = prev; });
         dojo.forEach(nextKeyCodes, function(code){ keyCodes[code] = next; });
         keyCodes[dojo.keys.HOME] = dojo.hitch(this, "focusFirstChild");
         keyCodes[dojo.keys.END] = dojo.hitch(this, "focusLastChild");
         this.connect(this.domNode, "onkeypress", "_onContainerKeypress");
         this.connect(this.domNode, "onfocus", "_onContainerFocus");
    • summary
      Call in postCreate() to attach the keyboard handlers
      to the container.
      preKeyCodes: dojo.keys[]
      Key codes for navigating to the previous child.
    • tags:
  • dijit._KeyNavContainer.startupKeyNavChildren

    • type
      Function
    • source: [view]
         dojo.forEach(this.getChildren(), dojo.hitch(this, "_startupChild"));
    • summary
      Call in startup() to set child tabindexes to -1
    • tags:
  • dijit._KeyNavContainer.addChild

    • type
      Function
    • parameters:
      • widget: (typeof dijit._Widget)
      • insertIndex: (typeof int)
    • source: [view]
         dijit._KeyNavContainer.superclass.addChild.apply(this, arguments);
         this._startupChild(widget);
    • summary
      Add a child to our _Container
    • chains:
      • dijit._KeyNavContainer.superclass.addChild: (call)
  • dijit._KeyNavContainer.focus

    • type
      Function
    • source: [view]
         this.focusFirstChild();
    • summary
      Default focus() implementation: focus the first child.
  • dijit._KeyNavContainer.focusFirstChild

    • type
      Function
    • source: [view]
         var child = this._getFirstFocusableChild();
         if(child){ // edge case: Menu could be empty or hidden
          this.focusChild(child);
         }
    • summary
      Focus the first focusable child in the container.
    • tags:
  • dijit._KeyNavContainer.focusLastChild

    • type
      Function
    • source: [view]
         var child = this._getLastFocusableChild();
         if(child){ // edge case: Menu could be empty or hidden
          this.focusChild(child);
         }
    • summary
      Focus the last focusable child in the container.
    • tags:
  • dijit._KeyNavContainer.focusNext

    • type
      Function
    • source: [view]
         var child = this._getNextFocusableChild(this.focusedChild, 1);
         this.focusChild(child);
    • summary
      Focus the next widget
    • tags:
  • dijit._KeyNavContainer.focusPrev

    • type
      Function
    • source: [view]
         var child = this._getNextFocusableChild(this.focusedChild, -1);
         this.focusChild(child, true);
    • summary
      Focus the last focusable node in the previous widget
      (ex: go to the ComboButton icon section rather than button section)
    • tags:
  • dijit._KeyNavContainer.focusChild

    • type
      Function
    • parameters:
      • widget: (typeof dijit._Widget)
        Reference to container's child widget
      • last: (typeof Boolean)
        If true and if widget has multiple focusable nodes, focus the
        last one instead of the first one
    • source: [view]
         if(this.focusedChild && widget !== this.focusedChild){
          this._onChildBlur(this.focusedChild);
         }
         widget.set("tabIndex", this.tabIndex); // for IE focus outline to appear, must set tabIndex before focs
         widget.focus(last ? "end" : "start");
         this._set("focusedChild", widget);
    • summary
      Focus widget.
    • tags:
  • dijit._KeyNavContainer._startupChild

    • type
      Function
    • parameters:
      • widget: (typeof dijit._Widget)
    • source: [view]
         widget.set("tabIndex", "-1");

         
         this.connect(widget, "_onFocus", function(){
          // Set valid tabIndex so tabbing away from widget goes to right place, see #10272
          widget.set("tabIndex", this.tabIndex);
         });
         this.connect(widget, "_onBlur", function(){
          widget.set("tabIndex", "-1");
         });
    • summary
      Setup for each child widget
    • description
      Sets tabIndex=-1 on each child, so that the tab key will
      leave the container rather than visiting each child.
    • tags:
  • dijit._KeyNavContainer._onContainerFocus

    • type
      Function
    • parameters:
      • evt: (typeof )
    • source: [view]
      define("dijit/_KeyNavContainer", ["dojo", "dijit", "dijit/_Container"], function(dojo, dijit) {


      dojo.declare("dijit._KeyNavContainer",
       dijit._Container,
       {


        // summary:
        //  A _Container with keyboard navigation of its children.
        // description:
        //  To use this mixin, call connectKeyNavHandlers() in
        //  postCreate() and call startupKeyNavChildren() in startup().
        //  It provides normalized keyboard and focusing code for Container
        //  widgets.


        // focusedChild: [protected] Widget
        //  The currently focused child widget, or null if there isn't one
        focusedChild: null,




        // tabIndex: Integer
        //  Tab index of the container; same as HTML tabIndex attribute.
        //  Note then when user tabs into the container, focus is immediately
        //  moved to the first item in the container.
        tabIndex: "0",


        _keyNavCodes: {},


        connectKeyNavHandlers: function(/*dojo.keys[]*/ prevKeyCodes, /*dojo.keys[]*/ nextKeyCodes){
         // summary:
         //  Call in postCreate() to attach the keyboard handlers
         //  to the container.
         // preKeyCodes: dojo.keys[]
         //  Key codes for navigating to the previous child.
         // nextKeyCodes: dojo.keys[]
         //  Key codes for navigating to the next child.
         // tags:
         //  protected


         var keyCodes = (this._keyNavCodes = {});
         var prev = dojo.hitch(this, this.focusPrev);
         var next = dojo.hitch(this, this.focusNext);
         dojo.forEach(prevKeyCodes, function(code){ keyCodes[code] = prev; });
         dojo.forEach(nextKeyCodes, function(code){ keyCodes[code] = next; });
         keyCodes[dojo.keys.HOME] = dojo.hitch(this, "focusFirstChild");
         keyCodes[dojo.keys.END] = dojo.hitch(this, "focusLastChild");
         this.connect(this.domNode, "onkeypress", "_onContainerKeypress");
         this.connect(this.domNode, "onfocus", "_onContainerFocus");
        },


        startupKeyNavChildren: function(){
         // summary:
         //  Call in startup() to set child tabindexes to -1
         // tags:
         //  protected
         dojo.forEach(this.getChildren(), dojo.hitch(this, "_startupChild"));
        },


        addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
         // summary:
         //  Add a child to our _Container
         dijit._KeyNavContainer.superclass.addChild.apply(this, arguments);
         this._startupChild(widget);
        },


        focus: function(){
         // summary:
         //  Default focus() implementation: focus the first child.
         this.focusFirstChild();
        },


        focusFirstChild: function(){
         // summary:
         //  Focus the first focusable child in the container.
         // tags:
         //  protected
         var child = this._getFirstFocusableChild();
         if(child){ // edge case: Menu could be empty or hidden
          this.focusChild(child);
         }
        },


        focusLastChild: function(){
         // summary:
         //  Focus the last focusable child in the container.
         // tags:
         //  protected
         var child = this._getLastFocusableChild();
         if(child){ // edge case: Menu could be empty or hidden
          this.focusChild(child);
         }
        },


        focusNext: function(){
         // summary:
         //  Focus the next widget
         // tags:
         //  protected
         var child = this._getNextFocusableChild(this.focusedChild, 1);
         this.focusChild(child);
        },


        focusPrev: function(){
         // summary:
         //  Focus the last focusable node in the previous widget
         //  (ex: go to the ComboButton icon section rather than button section)
         // tags:
         //  protected
         var child = this._getNextFocusableChild(this.focusedChild, -1);
         this.focusChild(child, true);
        },


        focusChild: function(/*dijit._Widget*/ widget, /*Boolean*/ last){
         // summary:
         //  Focus widget.
         // widget:
         //  Reference to container's child widget
         // last:
         //  If true and if widget has multiple focusable nodes, focus the
         //  last one instead of the first one
         // tags:
         //  protected

         
         if(this.focusedChild && widget !== this.focusedChild){
          this._onChildBlur(this.focusedChild);
         }
         widget.set("tabIndex", this.tabIndex); // for IE focus outline to appear, must set tabIndex before focs
         widget.focus(last ? "end" : "start");
         this._set("focusedChild", widget);
        },


        _startupChild: function(/*dijit._Widget*/ widget){
         // summary:
         //  Setup for each child widget
         // description:
         //  Sets tabIndex=-1 on each child, so that the tab key will
         //  leave the container rather than visiting each child.
         // tags:
         //  private

         
         widget.set("tabIndex", "-1");

         
         this.connect(widget, "_onFocus", function(){
          // Set valid tabIndex so tabbing away from widget goes to right place, see #10272
          widget.set("tabIndex", this.tabIndex);
         });
         this.connect(widget, "_onBlur", function(){
          widget.set("tabIndex", "-1");
         });
        },


        _onContainerFocus: function(evt){
         // summary:
         //  Handler for when the container gets focus
         // description:
         //  Initially the container itself has a tabIndex, but when it gets
         //  focus, switch focus to first child...
         // tags:
         //  private


         // Note that we can't use _onFocus() because switching focus from the
         // _onFocus() handler confuses the focus.js code
         // (because it causes _onFocusNode() to be called recursively)


         // focus bubbles on Firefox,
         // so just make sure that focus has really gone to the container
         if(evt.target !== this.domNode){ return; }


         this.focusFirstChild();


         // and then set the container's tabIndex to -1,
         // (don't remove as that breaks Safari 4)
         // so that tab or shift-tab will go to the fields after/before
         // the container, rather than the container itself
         dojo.attr(this.domNode, "tabIndex", "-1");
    • summary
      Handler for when the container gets focus
    • description
      Initially the container itself has a tabIndex, but when it gets
      focus, switch focus to first child...
  • dijit._KeyNavContainer._onBlur

    • type
      Function
    • parameters:
      • evt: (typeof )
    • source: [view]
      define("dijit/_KeyNavContainer", ["dojo", "dijit", "dijit/_Container"], function(dojo, dijit) {


      dojo.declare("dijit._KeyNavContainer",
       dijit._Container,
       {


        // summary:
        //  A _Container with keyboard navigation of its children.
        // description:
        //  To use this mixin, call connectKeyNavHandlers() in
        //  postCreate() and call startupKeyNavChildren() in startup().
        //  It provides normalized keyboard and focusing code for Container
        //  widgets.


        // focusedChild: [protected] Widget
        //  The currently focused child widget, or null if there isn't one
        focusedChild: null,




        // tabIndex: Integer
        //  Tab index of the container; same as HTML tabIndex attribute.
        //  Note then when user tabs into the container, focus is immediately
        //  moved to the first item in the container.
        tabIndex: "0",


        _keyNavCodes: {},


        connectKeyNavHandlers: function(/*dojo.keys[]*/ prevKeyCodes, /*dojo.keys[]*/ nextKeyCodes){
         // summary:
         //  Call in postCreate() to attach the keyboard handlers
         //  to the container.
         // preKeyCodes: dojo.keys[]
         //  Key codes for navigating to the previous child.
         // nextKeyCodes: dojo.keys[]
         //  Key codes for navigating to the next child.
         // tags:
         //  protected


         var keyCodes = (this._keyNavCodes = {});
         var prev = dojo.hitch(this, this.focusPrev);
         var next = dojo.hitch(this, this.focusNext);
         dojo.forEach(prevKeyCodes, function(code){ keyCodes[code] = prev; });
         dojo.forEach(nextKeyCodes, function(code){ keyCodes[code] = next; });
         keyCodes[dojo.keys.HOME] = dojo.hitch(this, "focusFirstChild");
         keyCodes[dojo.keys.END] = dojo.hitch(this, "focusLastChild");
         this.connect(this.domNode, "onkeypress", "_onContainerKeypress");
         this.connect(this.domNode, "onfocus", "_onContainerFocus");
        },


        startupKeyNavChildren: function(){
         // summary:
         //  Call in startup() to set child tabindexes to -1
         // tags:
         //  protected
         dojo.forEach(this.getChildren(), dojo.hitch(this, "_startupChild"));
        },


        addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
         // summary:
         //  Add a child to our _Container
         dijit._KeyNavContainer.superclass.addChild.apply(this, arguments);
         this._startupChild(widget);
        },


        focus: function(){
         // summary:
         //  Default focus() implementation: focus the first child.
         this.focusFirstChild();
        },


        focusFirstChild: function(){
         // summary:
         //  Focus the first focusable child in the container.
         // tags:
         //  protected
         var child = this._getFirstFocusableChild();
         if(child){ // edge case: Menu could be empty or hidden
          this.focusChild(child);
         }
        },


        focusLastChild: function(){
         // summary:
         //  Focus the last focusable child in the container.
         // tags:
         //  protected
         var child = this._getLastFocusableChild();
         if(child){ // edge case: Menu could be empty or hidden
          this.focusChild(child);
         }
        },


        focusNext: function(){
         // summary:
         //  Focus the next widget
         // tags:
         //  protected
         var child = this._getNextFocusableChild(this.focusedChild, 1);
         this.focusChild(child);
        },


        focusPrev: function(){
         // summary:
         //  Focus the last focusable node in the previous widget
         //  (ex: go to the ComboButton icon section rather than button section)
         // tags:
         //  protected
         var child = this._getNextFocusableChild(this.focusedChild, -1);
         this.focusChild(child, true);
        },


        focusChild: function(/*dijit._Widget*/ widget, /*Boolean*/ last){
         // summary:
         //  Focus widget.
         // widget:
         //  Reference to container's child widget
         // last:
         //  If true and if widget has multiple focusable nodes, focus the
         //  last one instead of the first one
         // tags:
         //  protected

         
         if(this.focusedChild && widget !== this.focusedChild){
          this._onChildBlur(this.focusedChild);
         }
         widget.set("tabIndex", this.tabIndex); // for IE focus outline to appear, must set tabIndex before focs
         widget.focus(last ? "end" : "start");
         this._set("focusedChild", widget);
        },


        _startupChild: function(/*dijit._Widget*/ widget){
         // summary:
         //  Setup for each child widget
         // description:
         //  Sets tabIndex=-1 on each child, so that the tab key will
         //  leave the container rather than visiting each child.
         // tags:
         //  private

         
         widget.set("tabIndex", "-1");

         
         this.connect(widget, "_onFocus", function(){
          // Set valid tabIndex so tabbing away from widget goes to right place, see #10272
          widget.set("tabIndex", this.tabIndex);
         });
         this.connect(widget, "_onBlur", function(){
          widget.set("tabIndex", "-1");
         });
        },


        _onContainerFocus: function(evt){
         // summary:
         //  Handler for when the container gets focus
         // description:
         //  Initially the container itself has a tabIndex, but when it gets
         //  focus, switch focus to first child...
         // tags:
         //  private


         // Note that we can't use _onFocus() because switching focus from the
         // _onFocus() handler confuses the focus.js code
         // (because it causes _onFocusNode() to be called recursively)


         // focus bubbles on Firefox,
         // so just make sure that focus has really gone to the container
         if(evt.target !== this.domNode){ return; }


         this.focusFirstChild();


         // and then set the container's tabIndex to -1,
         // (don't remove as that breaks Safari 4)
         // so that tab or shift-tab will go to the fields after/before
         // the container, rather than the container itself
         dojo.attr(this.domNode, "tabIndex", "-1");
        },


        _onBlur: function(evt){
         // When focus is moved away the container, and its descendant (popup) widgets,
         // then restore the container's tabIndex so that user can tab to it again.
         // Note that using _onBlur() so that this doesn't happen when focus is shifted
         // to one of my child widgets (typically a popup)
         if(this.tabIndex){
          dojo.attr(this.domNode, "tabIndex", this.tabIndex);
         }
         this.inherited(arguments);
    • summary
  • dijit._KeyNavContainer._onContainerKeypress

    • type
      Function
    • parameters:
      • evt: (typeof )
    • source: [view]
         if(evt.ctrlKey || evt.altKey){ return; }
         var func = this._keyNavCodes[evt.charOrCode];
         if(func){
          func();
          dojo.stopEvent(evt);
         }
    • summary
      When a key is pressed, if it's an arrow key etc. then
      it's handled here.
    • tags:
  • dijit._KeyNavContainer._onChildBlur

    • type
      Function
    • parameters:
      • widget: (typeof dijit._Widget)
    • source: [view]
         // summary:
         //  Called when focus leaves a child widget to go
         //  to a sibling widget.
         // tags:
         //  protected
    • summary
      Called when focus leaves a child widget to go
      to a sibling widget.
    • tags:
  • dijit._KeyNavContainer._getFirstFocusableChild

    • type
      Function
    • source: [view]
         return this._getNextFocusableChild(null, 1); // dijit._Widget
    • summary
      Returns first child that can be focused
    • returns
      dijit._Widget
  • dijit._KeyNavContainer._getLastFocusableChild

    • type
      Function
    • source: [view]
         return this._getNextFocusableChild(null, -1); // dijit._Widget
    • summary
      Returns last child that can be focused
    • returns
      dijit._Widget
  • dijit._KeyNavContainer._getNextFocusableChild

    • type
      Function
    • parameters:
      • child: (typeof Widget)
        The current widget
      • dir: (typeof Integer)
        * 1 = after
        * -1 = before
    • source: [view]
         if(child){
          child = this._getSiblingOfChild(child, dir);
         }
         var children = this.getChildren();
         for(var i=0; i < children.length; i++){
          if(!child){
           child = children[(dir>0) ? 0 : (children.length-1)];
          }
          if(child.isFocusable()){
           return child; // dijit._Widget
          }
          child = this._getSiblingOfChild(child, dir);
         }
         // no focusable child found
         return null; // dijit._Widget
    • summary
      Returns the next or previous focusable child, compared
      to &quot;child&quot;
    • returns
      dijit._Widget
  • dijit

    • type
      Object
    • summary