if(!dojo._hasResource["dojox.grid._grid.focus"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. dojo._hasResource["dojox.grid._grid.focus"] = true; dojo.provide("dojox.grid._grid.focus"); // focus management dojo.declare("dojox.grid.focus", null, { // summary: // Controls grid cell focus. Owned by grid and used internally for focusing. // Note: grid cell actually receives keyboard input only when cell is being edited. constructor: function(inGrid){ this.grid = inGrid; this.cell = null; this.rowIndex = -1; dojo.connect(this.grid.domNode, "onfocus", this, "doFocus"); }, tabbingOut: false, focusClass: "dojoxGrid-cell-focus", focusView: null, initFocusView: function(){ this.focusView = this.grid.views.getFirstScrollingView(); }, isFocusCell: function(inCell, inRowIndex){ // summary: // states if the given cell is focused // inCell: object // grid cell object // inRowIndex: int // grid row index // returns: // true of the given grid cell is focused return (this.cell == inCell) && (this.rowIndex == inRowIndex); }, isLastFocusCell: function(){ return (this.rowIndex == this.grid.rowCount-1) && (this.cell.index == this.grid.layout.cellCount-1); }, isFirstFocusCell: function(){ return (this.rowIndex == 0) && (this.cell.index == 0); }, isNoFocusCell: function(){ return (this.rowIndex < 0) || !this.cell; }, _focusifyCellNode: function(inBork){ var n = this.cell && this.cell.getNode(this.rowIndex); if(n){ dojo.toggleClass(n, this.focusClass, inBork); if (inBork){ this.scrollIntoView(); try{ if(!this.grid.edit.isEditing()) dojox.grid.fire(n, "focus"); }catch(e){} } } }, scrollIntoView: function() { if(!this.cell){ return; } var c = this.cell, s = c.view.scrollboxNode, sr = { w: s.clientWidth, l: s.scrollLeft, t: s.scrollTop, h: s.clientHeight }, n = c.getNode(this.rowIndex), r = c.view.getRowNode(this.rowIndex), rt = this.grid.scroller.findScrollTop(this.rowIndex); // place cell within horizontal view if(n.offsetLeft + n.offsetWidth > sr.l + sr.w){ s.scrollLeft = n.offsetLeft + n.offsetWidth - sr.w; }else if(n.offsetLeft < sr.l){ s.scrollLeft = n.offsetLeft; } // place cell within vertical view if(rt + r.offsetHeight > sr.t + sr.h){ this.grid.setScrollTop(rt + r.offsetHeight - sr.h); }else if(rt < sr.t){ this.grid.setScrollTop(rt); } }, styleRow: function(inRow){ return; }, setFocusIndex: function(inRowIndex, inCellIndex){ // summary: // focuses the given grid cell // inRowIndex: int // grid row index // inCellIndex: int // grid cell index this.setFocusCell(this.grid.getCell(inCellIndex), inRowIndex); }, setFocusCell: function(inCell, inRowIndex){ // summary: // focuses the given grid cell // inCell: object // grid cell object // inRowIndex: int // grid row index if(inCell && !this.isFocusCell(inCell, inRowIndex)){ this.tabbingOut = false; this.focusGridView(); this._focusifyCellNode(false); this.cell = inCell; this.rowIndex = inRowIndex; this._focusifyCellNode(true); } // even if this cell isFocusCell, the document focus may need to be rejiggered // call opera on delay to prevent keypress from altering focus if(dojo.isOpera){ setTimeout(dojo.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1); }else{ this.grid.onCellFocus(this.cell, this.rowIndex); } }, next: function(){ // summary: // focus next grid cell var row=this.rowIndex, col=this.cell.index+1, cc=this.grid.layout.cellCount-1, rc=this.grid.rowCount-1; if(col > cc){ col = 0; row++; } if(row > rc){ col = cc; row = rc; } this.setFocusIndex(row, col); }, previous: function(){ // summary: // focus previous grid cell var row=(this.rowIndex || 0), col=(this.cell.index || 0) - 1; if(col < 0){ col = this.grid.layout.cellCount-1; row--; } if(row < 0){ row = 0; col = 0; } this.setFocusIndex(row, col); }, move: function(inRowDelta, inColDelta) { // summary: // focus grid cell based on position relative to current focus // inRowDelta: int // vertical distance from current focus // inColDelta: int // horizontal distance from current focus var rc = this.grid.rowCount-1, cc = this.grid.layout.cellCount-1, r = this.rowIndex, i = this.cell.index, row = Math.min(rc, Math.max(0, r+inRowDelta)), col = Math.min(cc, Math.max(0, i+inColDelta)); this.setFocusIndex(row, col); if(inRowDelta){ this.grid.updateRow(r); } }, previousKey: function(e){ if(this.isFirstFocusCell()){ this.tabOut(this.grid.domNode); }else{ dojo.stopEvent(e); this.previous(); } }, nextKey: function(e) { if(this.isLastFocusCell()){ this.tabOut(this.grid.lastFocusNode); }else{ dojo.stopEvent(e); this.next(); } }, tabOut: function(inFocusNode){ this.tabbingOut = true; inFocusNode.focus(); }, focusGridView: function(){ dojox.grid.fire(this.focusView, "focus"); }, focusGrid: function(inSkipFocusCell){ this.focusGridView(); this._focusifyCellNode(true); }, doFocus: function(e){ // trap focus only for grid dom node if(e && e.target != e.currentTarget){ return; } // do not focus for scrolling if grid is about to blur if(!this.tabbingOut && this.isNoFocusCell()){ // establish our virtual-focus, if necessary this.setFocusIndex(0, 0); } this.tabbingOut = false; } }); }