diff options
Diffstat (limited to 'js/dojo-1.6/dojox/grid/enhanced/_FocusManager.js')
| -rw-r--r-- | js/dojo-1.6/dojox/grid/enhanced/_FocusManager.js | 784 |
1 files changed, 784 insertions, 0 deletions
diff --git a/js/dojo-1.6/dojox/grid/enhanced/_FocusManager.js b/js/dojo-1.6/dojox/grid/enhanced/_FocusManager.js new file mode 100644 index 0000000..0d1cd2e --- /dev/null +++ b/js/dojo-1.6/dojox/grid/enhanced/_FocusManager.js @@ -0,0 +1,784 @@ +/*
+ Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+ Available via Academic Free License >= 2.1 OR the modified BSD license.
+ see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["dojox.grid.enhanced._FocusManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["dojox.grid.enhanced._FocusManager"] = true;
+dojo.provide("dojox.grid.enhanced._FocusManager");
+
+dojo.declare("dojox.grid.enhanced._FocusArea",null,{
+ // summary:
+ // This is a friend class of _FocusManager
+/*=====
+ // name: string
+ // Name of this area.
+ name: "",
+
+ // onFocus: function(event, step)
+ // Called when this area logically gets focus.
+ // event: Event object
+ // May be unavailable, should check before use.
+ // step: Integer
+ // The distance in the tab sequence from last focused area to this area.
+ // returns:
+ // whether this area is successfully focused. If not, the next area will get focus.
+ onFocus: function(event, step){return true;},
+
+ // onBlur: function(event, step)
+ // Called when this area logically loses focus.
+ // event: Event object
+ // May be unavailable, should check before use.
+ // step: Integer
+ // The distance in the tab sequence from this area to the area to focus.
+ // returns:
+ // If Boolean, means whether this area has successfully blurred. If not, the next area to focus is still this one.
+ // If String, means the next area to focus is given by this returned name.
+ onBlur: function(event, step){return true;},
+
+ // onMove: function(rowStep, colStep, event)
+ // Called when focus is moving around within this area.
+ // rowStep: Integer
+ // colStep: Integer
+ // event: Event object
+ // May be unavailable, should check before use.
+ onMove: function(rowStep, colStep, event){},
+
+ // onKey: function(event, isBubble)
+ // Called when some key is pressed when focus is logically in this area.
+ // event: Event object
+ // isBubble: Boolean
+ // Whether is in bubble stage (true) or catch stage (false).
+ // returns:
+ // If you do NOT want the event to propagate any further along the area stack, return exactly false.
+ // So if you return nothing (undefined), this event is still propagating.
+ onKey: function(event, isBubble){return true},
+
+ // getRegions: function()
+ // Define the small regions (dom nodes) in this area.
+ // returns: Array of dom nodes.
+ getRegions: function(){},
+
+ // onRegionFocus: function(event)
+ // Connected to the onfocus event of the defined regions (if any)
+ onRegionFocus: function(event){},
+
+ // onRegionBlur: function(event)
+ // Connected to the onblur event of the defined regions (if any)
+ onRegionBlur: function(event){},
+=====*/
+ constructor: function(area, focusManager){
+ this._fm = focusManager;
+ this._evtStack = [area.name];
+ var dummy = function(){return true;};
+ area.onFocus = area.onFocus || dummy;
+ area.onBlur = area.onBlur || dummy;
+ area.onMove = area.onMove || dummy;
+ area.onKeyUp = area.onKeyUp || dummy;
+ area.onKeyDown = area.onKeyDown || dummy;
+ dojo.mixin(this, area);
+ },
+ move: function(rowStep, colStep, evt){
+ if(this.name){
+ var i, len = this._evtStack.length;
+ for(i = len - 1; i >= 0; --i){
+ if(this._fm._areas[this._evtStack[i]].onMove(rowStep, colStep, evt) === false){
+ return false;
+ }
+ }
+ }
+ return true;
+ },
+ _onKeyEvent: function(evt, funcName){
+ if(this.name){
+ var i, len = this._evtStack.length;
+ for(i = len - 1; i >= 0; --i){
+ if(this._fm._areas[this._evtStack[i]][funcName](evt, false) === false){
+ return false;
+ }
+ }
+ for(i = 0; i < len; ++i){
+ if(this._fm._areas[this._evtStack[i]][funcName](evt, true) === false){
+ return false;
+ }
+ }
+ }
+ return true;
+ },
+ keydown: function(evt){
+ return this._onKeyEvent(evt, "onKeyDown");
+ },
+ keyup: function(evt){
+ return this._onKeyEvent(evt, "onKeyUp");
+ },
+ contentMouseEventPlanner: function(){
+ return 0;
+ },
+ headerMouseEventPlanner: function(){
+ return 0;
+ }
+});
+dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
+ _stopEvent: function(evt){
+ try{
+ if(evt && evt.preventDefault){
+ dojo.stopEvent(evt);
+ }
+ }catch(e){}
+ },
+
+ constructor: function(grid){
+ this.grid = grid;
+ this._areas = {};
+ this._areaQueue = [];
+ this._contentMouseEventHandlers = [];
+ this._headerMouseEventHandlers = [];
+ this._currentAreaIdx = -1;
+ this._gridBlured = true;
+ this._connects.push(dojo.connect(grid, "onBlur", this, "_doBlur"));
+
+ this.addArea({
+ name: "header",
+ onFocus: dojo.hitch(this, this.focusHeader),
+ onBlur: dojo.hitch(this, this._blurHeader),
+ onMove: dojo.hitch(this, this._navHeader),
+ getRegions: dojo.hitch(this, this._findHeaderCells),
+ onRegionFocus: dojo.hitch(this, this.doColHeaderFocus),
+ onRegionBlur: dojo.hitch(this, this.doColHeaderBlur),
+ onKeyDown: dojo.hitch(this, this._onHeaderKeyDown)
+ });
+ this.addArea({
+ name: "content",
+ onFocus: dojo.hitch(this, this._focusContent),
+ onBlur: dojo.hitch(this, this._blurContent),
+ onMove: dojo.hitch(this, this._navContent),
+ onKeyDown: dojo.hitch(this, this._onContentKeyDown)
+ });
+ this.addArea({
+ name: "editableCell",
+ onFocus: dojo.hitch(this, this._focusEditableCell),
+ onBlur: dojo.hitch(this, this._blurEditableCell),
+ onKeyDown: dojo.hitch(this, this._onEditableCellKeyDown),
+ onContentMouseEvent: dojo.hitch(this, this._onEditableCellMouseEvent),
+ contentMouseEventPlanner: function(evt, areas){ return -1; }
+ });
+ this.placeArea("header");
+ this.placeArea("content");
+ this.placeArea("editableCell");
+ this.placeArea("editableCell","above","content");
+ },
+ destroy: function(){
+ for(var name in this._areas){
+ var area = this._areas[name];
+ dojo.forEach(area._connects, dojo.disconnect);
+ area._connects = null;
+ if(area.uninitialize){
+ area.uninitialize();
+ }
+ }
+ this.inherited(arguments);
+ },
+ addArea: function(area){
+ if(area.name && dojo.isString(area.name)){
+ if(this._areas[area.name]){
+ //Just replace the original area, instead of remove it, so the position does not change.
+ dojo.forEach(area._connects, dojo.disconnect);
+ }
+ this._areas[area.name] = new dojox.grid.enhanced._FocusArea(area, this);
+ if(area.onHeaderMouseEvent){
+ this._headerMouseEventHandlers.push(area.name);
+ }
+ if(area.onContentMouseEvent){
+ this._contentMouseEventHandlers.push(area.name);
+ }
+ }
+ },
+ getArea: function(areaName){
+ return this._areas[areaName];
+ },
+ _bindAreaEvents: function(){
+ var area, hdl, areas = this._areas;
+ dojo.forEach(this._areaQueue, function(name){
+ area = areas[name];
+ if(!area._initialized && dojo.isFunction(area.initialize)){
+ area.initialize();
+ area._initialized = true;
+ }
+ if(area.getRegions){
+ area._regions = area.getRegions() || [];
+ dojo.forEach(area._connects || [], dojo.disconnect);
+ area._connects = [];
+ dojo.forEach(area._regions, function(r){
+ if(area.onRegionFocus){
+ hdl = dojo.connect(r, "onfocus", area.onRegionFocus);
+ area._connects.push(hdl);
+ }
+ if(area.onRegionBlur){
+ hdl = dojo.connect(r, "onblur", area.onRegionBlur);
+ area._connects.push(hdl);
+ }
+ });
+ }
+ });
+ },
+ removeArea: function(areaName){
+ var area = this._areas[areaName];
+ if(area){
+ this.ignoreArea(areaName);
+ var i = dojo.indexOf(this._contentMouseEventHandlers, areaName);
+ if(i >= 0){
+ this._contentMouseEventHandlers.splice(i, 1);
+ }
+ i = dojo.indexOf(this._headerMouseEventHandlers, areaName);
+ if(i >= 0){
+ this._headerMouseEventHandlers.splice(i, 1);
+ }
+ dojo.forEach(area._connects, dojo.disconnect);
+ if(area.uninitialize){
+ area.uninitialize();
+ }
+ delete this._areas[areaName];
+ }
+ },
+ currentArea: function(areaName, toBlurOld){
+ // summary:
+ // Set current area to the one areaName refers.
+ // areaName: String
+ var idx, cai = this._currentAreaIdx;
+ if(dojo.isString(areaName) && (idx = dojo.indexOf(this._areaQueue, areaName)) >= 0){
+ if(cai != idx){
+ this.tabbingOut = false;
+ if(toBlurOld && cai >= 0 && cai < this._areaQueue.length){
+ this._areas[this._areaQueue[cai]].onBlur();
+ }
+ this._currentAreaIdx = idx;
+ }
+ }else{
+ return (cai < 0 || cai >= this._areaQueue.length) ?
+ new dojox.grid.enhanced._FocusArea({}, this) :
+ this._areas[this._areaQueue[this._currentAreaIdx]];
+ }
+ return null;
+ },
+ placeArea: function(name, pos, otherAreaName){
+ // summary:
+ // Place the area refered by *name* at some logical position relative to an existing area.
+ // example:
+ // placeArea("myarea","before"|"after",...)
+ // placeArea("myarea","below"|"above",...)
+ if(!this._areas[name]){ return; }
+ var idx = dojo.indexOf(this._areaQueue,otherAreaName);
+ switch(pos){
+ case "after":
+ if(idx >= 0){ ++idx; }
+ //intentional drop through
+ case "before":
+ if(idx >= 0){
+ this._areaQueue.splice(idx,0,name);
+ break;
+ }
+ //intentional drop through
+ default:
+ this._areaQueue.push(name);
+ break;
+ case "above":
+ var isAbove = true;
+ //intentional drop through
+ case "below":
+ var otherArea = this._areas[otherAreaName];
+ if(otherArea){
+ if(isAbove){
+ otherArea._evtStack.push(name);
+ }else{
+ otherArea._evtStack.splice(0,0,name);
+ }
+ }
+ }
+ },
+ ignoreArea: function(name){
+ this._areaQueue = dojo.filter(this._areaQueue,function(areaName){
+ return areaName != name;
+ });
+ },
+ focusArea: function(/* int|string|areaObj */areaId,evt){
+ var idx;
+ if(typeof areaId == "number"){
+ idx = areaId < 0 ? this._areaQueue.length + areaId : areaId;
+ }else{
+ idx = dojo.indexOf(this._areaQueue,
+ dojo.isString(areaId) ? areaId : (areaId && areaId.name));
+ }
+ if(idx < 0){ idx = 0; }
+ var step = idx - this._currentAreaIdx;
+ this._gridBlured = false;
+ if(step){
+ this.tab(step, evt);
+ }else{
+ this.currentArea().onFocus(evt, step);
+ }
+ },
+ tab: function(step,evt){
+ //console.log("===========tab",step,"curArea",this._currentAreaIdx,"areaCnt",this._areaQueue.length);
+ this._gridBlured = false;
+ this.tabbingOut = false;
+ if(step === 0){
+ return;
+ }
+ var cai = this._currentAreaIdx;
+ var dir = step > 0 ? 1:-1;
+ if(cai < 0 || cai >= this._areaQueue.length){
+ cai = (this._currentAreaIdx += step);
+ }else{
+ var nextArea = this._areas[this._areaQueue[cai]].onBlur(evt,step);
+ if(nextArea === true){
+ cai = (this._currentAreaIdx += step);
+ }else if(dojo.isString(nextArea) && this._areas[nextArea]){
+ cai = this._currentAreaIdx = dojo.indexOf(this._areaQueue,nextArea);
+ }
+ }
+ //console.log("target area:",cai);
+ for(; cai >= 0 && cai < this._areaQueue.length; cai += dir){
+ this._currentAreaIdx = cai;
+ if(this._areaQueue[cai] && this._areas[this._areaQueue[cai]].onFocus(evt,step)){
+ //console.log("final target area:",this._currentAreaIdx);
+ return;
+ }
+ }
+ //console.log("tab out");
+ this.tabbingOut = true;
+ if(step < 0){
+ this._currentAreaIdx = -1;
+ dijit.focus(this.grid.domNode);
+ }else{
+ this._currentAreaIdx = this._areaQueue.length;
+ dijit.focus(this.grid.lastFocusNode);
+ }
+ },
+ _onMouseEvent: function(type, evt){
+ var lowercase = type.toLowerCase(),
+ handlers = this["_" + lowercase + "MouseEventHandlers"],
+ res = dojo.map(handlers, function(areaName){
+ return {
+ "area": areaName,
+ "idx": this._areas[areaName][lowercase + "MouseEventPlanner"](evt, handlers)
+ };
+ }, this).sort(function(a, b){
+ return b.idx - a.idx;
+ }),
+ resHandlers = dojo.map(res, function(handler){
+ return res.area;
+ }),
+ i = res.length;
+ while(--i >= 0){
+ if(this._areas[res[i].area]["on" + type + "MouseEvent"](evt, resHandlers) === false){
+ return;
+ }
+ }
+ },
+ contentMouseEvent: function(evt){
+ this._onMouseEvent("Content", evt);
+ },
+ headerMouseEvent: function(evt){
+ this._onMouseEvent("Header", evt);
+ },
+ initFocusView: function(){
+ // summary:
+ // Overwritten
+ this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0];
+ this._bindAreaEvents();
+ },
+ isNavHeader: function(){
+ // summary:
+ // Overwritten
+ // Check whether currently navigating among column headers.
+ // return:
+ // true - focus is on a certain column header | false otherwise
+ return this._areaQueue[this._currentAreaIdx] == "header";
+ },
+ previousKey: function(e){
+ // summary:
+ // Overwritten
+ this.tab(-1,e);
+ },
+ nextKey: function(e){
+ // summary:
+ // Overwritten
+ this.tab(1,e);
+ },
+ setFocusCell: function(/* Object */inCell, /* Integer */inRowIndex){
+ // summary:
+ // Overwritten - focuses the given grid cell
+ if(inCell){
+ this.currentArea(this.grid.edit.isEditing() ? "editableCell" : "content", true);
+ //This is very slow when selecting cells!
+ //this.focusGridView();
+ this._focusifyCellNode(false);
+ this.cell = inCell;
+ this.rowIndex = inRowIndex;
+ this._focusifyCellNode(true);
+ }
+ this.grid.onCellFocus(this.cell, this.rowIndex);
+ },
+ doFocus: function(e){
+ // summary:
+ // Overwritten
+ // trap focus only for grid dom node
+ // do not focus for scrolling if grid is about to blur
+ if(e && e.target == e.currentTarget && !this.tabbingOut){
+ if(this._gridBlured){
+ this._gridBlured = false;
+ if(this._currentAreaIdx < 0 || this._currentAreaIdx >= this._areaQueue.length){
+ this.focusArea(0, e);
+ }else{
+ this.focusArea(this._currentAreaIdx, e);
+ }
+ }
+ }else{
+ this.tabbingOut = false;
+ }
+ dojo.stopEvent(e);
+ },
+ _doBlur: function(){
+ this._gridBlured = true;
+ },
+ doLastNodeFocus: function(e){
+ // summary:
+ // Overwritten
+ if(this.tabbingOut){
+ this.tabbingOut = false;
+ }else{
+ this.focusArea(-1, e);
+ }
+ },
+ _delayedHeaderFocus: function(){
+ // summary:
+ // Overwritten
+ if(this.isNavHeader()){
+ this.focusHeader();
+ }
+ },
+ _delayedCellFocus: function(){
+ // summary:
+ // Overwritten
+ if(this.currentArea().name == "content"){
+ this.focusArea(this._currentAreaIdx);
+ }
+ },
+ _changeMenuBindNode: function(oldBindNode, newBindNode){
+ var hm = this.grid.headerMenu;
+ if(hm && this._contextMenuBindNode == oldBindNode){
+ hm.unBindDomNode(oldBindNode);
+ hm.bindDomNode(newBindNode);
+ this._contextMenuBindNode = newBindNode;
+ }
+ },
+ //---------------Header Area------------------------------------------
+ focusHeader: function(evt, step){ //need a further look why these changes to parent's
+ // summary:
+ // Overwritten
+ var didFocus = false;
+ this.inherited(arguments);
+ if(this._colHeadNode && dojo.style(this._colHeadNode, 'display') != "none"){
+ dijit.focus(this._colHeadNode);
+ this._stopEvent(evt);
+ didFocus = true;
+ }
+ return didFocus;
+ },
+ _blurHeader: function(evt,step){
+ // summary:
+ // Overwritten
+ if(this._colHeadNode){
+ dojo.removeClass(this._colHeadNode, this.focusClass);
+ }
+ dojo.removeAttr(this.grid.domNode,"aria-activedescendant");
+ // reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader)
+ this._changeMenuBindNode(this.grid.domNode,this.grid.viewsHeaderNode);
+ //moved here from nextKey
+ this._colHeadNode = this._colHeadFocusIdx = null;
+ return true;
+ },
+ _navHeader: function(rowStep, colStep, evt){
+ var colDir = colStep < 0 ? -1 : 1,
+ savedIdx = dojo.indexOf(this._findHeaderCells(), this._colHeadNode);
+ if(savedIdx >= 0 && (evt.shiftKey && evt.ctrlKey)){
+ this.colSizeAdjust(evt, savedIdx, colDir * 5);
+ return;
+ }
+ this.move(rowStep, colStep);
+ },
+ _onHeaderKeyDown: function(e, isBubble){
+ if(isBubble){
+ var dk = dojo.keys;
+ switch(e.keyCode){
+ case dk.ENTER:
+ case dk.SPACE:
+ var colIdx = this.getHeaderIndex();
+ if(colIdx >= 0 && !this.grid.pluginMgr.isFixedCell(e.cell)/*TODO*/){
+ this.grid.setSortIndex(colIdx, null, e);
+ dojo.stopEvent(e);
+ }
+ break;
+ }
+ }
+ return true;
+ },
+ _setActiveColHeader: function(){
+ // summary:
+ // Overwritten
+ this.inherited(arguments);
+ //EDG now will decorate event on header key events, if no focus, the cell will be wrong
+ dijit.focus(this._colHeadNode);
+ },
+ //---------------Content Area------------------------------------------
+ findAndFocusGridCell: function(){
+ // summary:
+ // Overwritten
+ this._focusContent();
+ },
+ _focusContent: function(evt,step){
+ var didFocus = true;
+ var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0
+ if(this.isNoFocusCell() && !isEmpty){
+ //skip all the hidden cells
+ for(var i = 0, cell = this.grid.getCell(0); cell && cell.hidden; cell = this.grid.getCell(++i)){}
+ this.setFocusIndex(0, cell ? i : 0);
+ }else if(this.cell && !isEmpty){
+ if(this.focusView && !this.focusView.rowNodes[this.rowIndex]){
+ // if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
+ // scroll to that row
+ this.grid.scrollToRow(this.rowIndex);
+ this.focusGrid();
+ }else{
+ this.setFocusIndex(this.rowIndex, this.cell.index);
+ }
+ }else{
+ didFocus = false;
+ }
+ if(didFocus){ this._stopEvent(evt); }
+ return didFocus;
+ },
+ _blurContent: function(evt,step){
+ this._focusifyCellNode(false);
+ return true;
+ },
+ _navContent: function(rowStep, colStep, evt){
+ if((this.rowIndex === 0 && rowStep < 0) || (this.rowIndex === this.grid.rowCount - 1 && rowStep > 0)){
+ return;
+ }
+ this._colHeadNode = null;
+ this.move(rowStep, colStep, evt);
+ if(evt){
+ dojo.stopEvent(evt);
+ }
+ },
+ move: function(inRowDelta, inColDelta){
+ // summary:
+ // Overwritten
+ this.inherited(arguments);
+ var cell = this.cell, row = this.rowIndex;
+ if(!this.isNavHeader() && cell){
+ if(inRowDelta !== 0){//jump over hidden rows
+ var node = cell.view.getRowNode(row);//row node
+ if(node && dojo.style(node, "display") === "none"){
+ this.move(inRowDelta > 0 ? 1 : -1, inColDelta);
+ }
+ }else if(inColDelta !== 0){//jump over hidden cells
+ var node = cell.getNode(row);//cell node
+ if(node && dojo.style(node, "display") === "none"){
+ this.move(inRowDelta, inColDelta > 0 ? 1 : -1);
+ }
+ }
+ }
+ },
+ _onContentKeyDown: function(e, isBubble){
+ if(isBubble){
+ var dk = dojo.keys, s = this.grid.scroller;
+ switch(e.keyCode){
+ case dk.ENTER:
+ case dk.SPACE:
+ var g = this.grid;
+ if(g.indirectSelection){ break; }
+ g.selection.clickSelect(this.rowIndex, dojo.isCopyKey(e), e.shiftKey);
+ g.onRowClick(e);
+ dojo.stopEvent(e);
+ break;
+ case dk.PAGE_UP:
+ if(this.rowIndex !== 0){
+ if(this.rowIndex != s.firstVisibleRow + 1){
+ this._navContent(s.firstVisibleRow - this.rowIndex, 0);
+ }else{
+ this.grid.setScrollTop(s.findScrollTop(this.rowIndex - 1));
+ this._navContent(s.firstVisibleRow - s.lastVisibleRow + 1, 0);
+ }
+ dojo.stopEvent(e);
+ }
+ break;
+ case dk.PAGE_DOWN:
+ if(this.rowIndex + 1 != this.grid.rowCount){
+ dojo.stopEvent(e);
+ if(this.rowIndex != s.lastVisibleRow - 1){
+ this._navContent(s.lastVisibleRow - this.rowIndex - 1, 0);
+ }else{
+ this.grid.setScrollTop(s.findScrollTop(this.rowIndex + 1));
+ this._navContent(s.lastVisibleRow - s.firstVisibleRow - 1, 0);
+ }
+ dojo.stopEvent(e);
+ }
+ break;
+ }
+ }
+ return true;
+ },
+ //------------------editable content area-------------------------
+ _blurFromEditableCell: false,
+ _isNavigating: false,
+ _navElems: null,
+ _focusEditableCell: function(evt,step){
+ var didFocus = false;
+ if(this._isNavigating){
+ didFocus = true;
+ }else if(this.grid.edit.isEditing() && this.cell){
+ if(this._blurFromEditableCell || !this._blurEditableCell(evt, step)){
+ this.setFocusIndex(this.rowIndex,this.cell.index);
+ didFocus = true;
+ }
+ this._stopEvent(evt);
+ }
+ return didFocus;
+ },
+ _applyEditableCell: function(){
+ try{
+ this.grid.edit.apply();
+ }catch(e){
+ console.warn("_FocusManager._applyEditableCell() error:", e);
+ }
+ },
+ _blurEditableCell: function(evt,step){
+ this._blurFromEditableCell = false;
+ if(this._isNavigating){
+ var toBlur = true;
+ if(evt){
+ var elems = this._navElems;
+ var firstElem = elems.lowest || elems.first;
+ var lastElem = elems.last || elems.highest || firstElem;
+ var target = dojo.isIE ? evt.srcElement : evt.target;
+ toBlur = target == (step > 0 ? lastElem : firstElem);
+ }
+ if(toBlur){
+ this._isNavigating = false;
+ return "content";
+ }
+ return false;
+ }else if(this.grid.edit.isEditing() && this.cell){
+ if(!step || typeof step != "number"){ return false; }
+ var dir = step > 0 ? 1 : -1;
+ var cc = this.grid.layout.cellCount;
+ for(var cell, col = this.cell.index + dir; col >= 0 && col < cc; col += dir){
+ cell = this.grid.getCell(col);
+ if(cell.editable){
+ this.cell = cell;
+ this._blurFromEditableCell = true;
+ return false;
+ }
+ }
+ if((this.rowIndex > 0 || dir == 1) && (this.rowIndex < this.grid.rowCount || dir == -1)){
+ this.rowIndex += dir;
+ //this.cell = this.grid.getCell(0); //There must be an editable cell, so this is not necessary.
+ for(col = dir > 0 ? 0 : cc - 1; col >= 0 && col < cc; col += dir){
+ cell = this.grid.getCell(col);
+ if(cell.editable){
+ this.cell = cell;
+ break;
+ }
+ }
+ this._applyEditableCell();
+ return "content";
+ }
+ }
+ return true;
+ },
+ _initNavigatableElems: function(){
+ this._navElems = dijit._getTabNavigable(this.cell.getNode(this.rowIndex));
+ },
+ _onEditableCellKeyDown: function(e, isBubble){
+ var dk = dojo.keys,
+ g = this.grid,
+ edit = g.edit,
+ editApplied = false,
+ toPropagate = true;
+ switch(e.keyCode){
+ case dk.ENTER:
+ if(isBubble && edit.isEditing()){
+ this._applyEditableCell();
+ editApplied = true;
+ }
+ //intentional drop through
+ case dk.SPACE:
+ if(!isBubble && this._isNavigating){
+ toPropagate = false;
+ break;
+ }
+ if(isBubble){
+ if(!this.cell.editable && this.cell.navigatable){
+ this._initNavigatableElems();
+ var toFocus = this._navElems.lowest || this._navElems.first;
+ if(toFocus){
+ this._isNavigating = true;
+ dijit.focus(toFocus);
+ dojo.stopEvent(e);
+ this.currentArea("editableCell", true);
+ break;
+ }
+ }
+ if(!editApplied && !edit.isEditing() && !g.pluginMgr.isFixedCell(this.cell)){
+ edit.setEditCell(this.cell, this.rowIndex);
+ }
+ if(editApplied){
+ this.currentArea("content", true);
+ }else if(this.cell.editable && g.canEdit()){
+ this.currentArea("editableCell", true);
+ }
+ }
+ break;
+ case dk.PAGE_UP:
+ case dk.PAGE_DOWN:
+ if(!isBubble && edit.isEditing()){
+ //prevent propagating to content area
+ toPropagate = false;
+ }
+ break;
+ case dk.ESCAPE:
+ if(!isBubble){
+ edit.cancel();
+ this.currentArea("content", true);
+ }
+ }
+ return toPropagate;
+ },
+ _onEditableCellMouseEvent: function(evt){
+ if(evt.type == "click"){
+ var cell = this.cell || evt.cell;
+ if(cell && !cell.editable && cell.navigatable){
+ this._initNavigatableElems();
+ if(this._navElems.lowest || this._navElems.first){
+ var target = dojo.isIE ? evt.srcElement : evt.target;
+ if(target != cell.getNode(evt.rowIndex)){
+ this._isNavigating = true;
+ this.focusArea("editableCell", evt);
+ dijit.focus(target);
+ return false;
+ }
+ }
+ }else if(this.grid.singleClickEdit){
+ this.currentArea("editableCell");
+ return false;
+ }
+ }
+ return true;
+ }
+});
+
+}
|
