You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
641 lines
20 KiB
641 lines
20 KiB
define([ |
|
"dojo/_base/array", |
|
"dojo/_base/lang", |
|
"dojo/_base/declare", |
|
"dojo/_base/connect", |
|
"dojo/_base/event", |
|
"dojo/_base/sniff", |
|
"dojo/query", |
|
"./util", |
|
"dojo/_base/html" |
|
], function(array, lang, declare, connect, event, has, query, util, html){ |
|
|
|
// focus management |
|
return declare("dojox.grid._FocusManager", 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; |
|
this._connects = []; |
|
this._headerConnects = []; |
|
this.headerMenu = this.grid.headerMenu; |
|
this._connects.push(connect.connect(this.grid.domNode, "onfocus", this, "doFocus")); |
|
this._connects.push(connect.connect(this.grid.domNode, "onblur", this, "doBlur")); |
|
this._connects.push(connect.connect(this.grid.domNode, "mousedown", this, "_mouseDown")); |
|
this._connects.push(connect.connect(this.grid.domNode, "mouseup", this, "_mouseUp")); |
|
this._connects.push(connect.connect(this.grid.domNode, "oncontextmenu", this, "doContextMenu")); |
|
this._connects.push(connect.connect(this.grid.lastFocusNode, "onfocus", this, "doLastNodeFocus")); |
|
this._connects.push(connect.connect(this.grid.lastFocusNode, "onblur", this, "doLastNodeBlur")); |
|
this._connects.push(connect.connect(this.grid,"_onFetchComplete", this, "_delayedCellFocus")); |
|
this._connects.push(connect.connect(this.grid,"postrender", this, "_delayedHeaderFocus")); |
|
}, |
|
destroy: function(){ |
|
array.forEach(this._connects, connect.disconnect); |
|
array.forEach(this._headerConnects, connect.disconnect); |
|
delete this.grid; |
|
delete this.cell; |
|
}, |
|
_colHeadNode: null, |
|
_colHeadFocusIdx: null, |
|
_contextMenuBindNode: null, |
|
tabbingOut: false, |
|
focusClass: "dojoxGridCellFocus", |
|
focusView: null, |
|
initFocusView: function(){ |
|
this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0]; |
|
this._initColumnHeaders(); |
|
}, |
|
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(){ |
|
if(this.cell){ |
|
return (this.rowIndex == this.grid.rowCount-1) && (this.cell.index == this.grid.layout.cellCount-1); |
|
} |
|
return false; |
|
}, |
|
isFirstFocusCell: function(){ |
|
if(this.cell){ |
|
return (this.rowIndex === 0) && (this.cell.index === 0); |
|
} |
|
return false; |
|
}, |
|
isNoFocusCell: function(){ |
|
return (this.rowIndex < 0) || !this.cell; |
|
}, |
|
isNavHeader: function(){ |
|
// summary: |
|
// states whether currently navigating among column headers. |
|
// returns: |
|
// true if focus is on a column header; false otherwise. |
|
return (!!this._colHeadNode); |
|
}, |
|
getHeaderIndex: function(){ |
|
// summary: |
|
// if one of the column headers currently has focus, return its index. |
|
// returns: |
|
// index of the focused column header, or -1 if none have focus. |
|
if(this._colHeadNode){ |
|
return array.indexOf(this._findHeaderCells(), this._colHeadNode); |
|
}else{ |
|
return -1; |
|
} |
|
}, |
|
_focusifyCellNode: function(inBork){ |
|
var n = this.cell && this.cell.getNode(this.rowIndex); |
|
if(n){ |
|
html.toggleClass(n, this.focusClass, inBork); |
|
if(inBork){ |
|
var sl = this.scrollIntoView(); |
|
try{ |
|
if(has("webkit") || !this.grid.edit.isEditing()){ |
|
util.fire(n, "focus"); |
|
if(sl){ this.cell.view.scrollboxNode.scrollLeft = sl; } |
|
} |
|
}catch(e){} |
|
} |
|
} |
|
}, |
|
_delayedCellFocus: function(){ |
|
if(this.isNavHeader()||!this.grid.focused){ |
|
return; |
|
} |
|
var n = this.cell && this.cell.getNode(this.rowIndex); |
|
if(n){ |
|
try{ |
|
if(!this.grid.edit.isEditing()){ |
|
html.toggleClass(n, this.focusClass, true); |
|
if(this._colHeadNode){ |
|
this.blurHeader(); |
|
} |
|
util.fire(n, "focus"); |
|
} |
|
} |
|
catch(e){} |
|
} |
|
}, |
|
_delayedHeaderFocus: function(){ |
|
if(this.isNavHeader()){ |
|
this.focusHeader(); |
|
//this.grid.domNode.focus(); |
|
} |
|
}, |
|
_initColumnHeaders: function(){ |
|
array.forEach(this._headerConnects, connect.disconnect); |
|
this._headerConnects = []; |
|
var headers = this._findHeaderCells(); |
|
for(var i = 0; i < headers.length; i++){ |
|
this._headerConnects.push(connect.connect(headers[i], "onfocus", this, "doColHeaderFocus")); |
|
this._headerConnects.push(connect.connect(headers[i], "onblur", this, "doColHeaderBlur")); |
|
} |
|
}, |
|
_findHeaderCells: function(){ |
|
// This should be a one liner: |
|
// query("th[tabindex=-1]", this.grid.viewsHeaderNode); |
|
// But there is a bug in query() for IE -- see trac #7037. |
|
var allHeads = query("th", this.grid.viewsHeaderNode); |
|
var headers = []; |
|
for (var i = 0; i < allHeads.length; i++){ |
|
var aHead = allHeads[i]; |
|
var hasTabIdx = html.hasAttr(aHead, "tabIndex"); |
|
var tabindex = html.attr(aHead, "tabIndex"); |
|
if (hasTabIdx && tabindex < 0) { |
|
headers.push(aHead); |
|
} |
|
} |
|
return headers; |
|
}, |
|
_setActiveColHeader: function(/*Node*/colHeaderNode, /*Integer*/colFocusIdx, /*Integer*/ prevColFocusIdx){ |
|
//console.log("setActiveColHeader() - colHeaderNode:colFocusIdx:prevColFocusIdx = " + colHeaderNode + ":" + colFocusIdx + ":" + prevColFocusIdx); |
|
this.grid.domNode.setAttribute("aria-activedescendant",colHeaderNode.id); |
|
if (prevColFocusIdx != null && prevColFocusIdx >= 0 && prevColFocusIdx != colFocusIdx){ |
|
html.toggleClass(this._findHeaderCells()[prevColFocusIdx],this.focusClass,false); |
|
} |
|
html.toggleClass(colHeaderNode,this.focusClass, true); |
|
this._colHeadNode = colHeaderNode; |
|
this._colHeadFocusIdx = colFocusIdx; |
|
this._scrollHeader(this._colHeadFocusIdx); |
|
}, |
|
scrollIntoView: function(){ |
|
var info = (this.cell ? this._scrollInfo(this.cell) : null); |
|
if(!info || !info.s){ |
|
return null; |
|
} |
|
var rt = this.grid.scroller.findScrollTop(this.rowIndex); |
|
// place cell within horizontal view |
|
if(info.n && info.sr){ |
|
if(info.n.offsetLeft + info.n.offsetWidth > info.sr.l + info.sr.w){ |
|
info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w; |
|
}else if(info.n.offsetLeft < info.sr.l){ |
|
info.s.scrollLeft = info.n.offsetLeft; |
|
} |
|
} |
|
// place cell within vertical view |
|
if(info.r && info.sr){ |
|
if(rt + info.r.offsetHeight > info.sr.t + info.sr.h){ |
|
this.grid.setScrollTop(rt + info.r.offsetHeight - info.sr.h); |
|
}else if(rt < info.sr.t){ |
|
this.grid.setScrollTop(rt); |
|
} |
|
} |
|
|
|
return info.s.scrollLeft; |
|
}, |
|
_scrollInfo: function(cell, domNode){ |
|
if(cell){ |
|
var cl = cell, |
|
sbn = cl.view.scrollboxNode, |
|
sbnr = { |
|
w: sbn.clientWidth, |
|
l: sbn.scrollLeft, |
|
t: sbn.scrollTop, |
|
h: sbn.clientHeight |
|
}, |
|
rn = cl.view.getRowNode(this.rowIndex); |
|
return { |
|
c: cl, |
|
s: sbn, |
|
sr: sbnr, |
|
n: (domNode ? domNode : cell.getNode(this.rowIndex)), |
|
r: rn |
|
}; |
|
} |
|
return null; |
|
}, |
|
_scrollHeader: function(currentIdx){ |
|
var info = null; |
|
if(this._colHeadNode){ |
|
var cell = this.grid.getCell(currentIdx); |
|
if(!cell){ return; } |
|
info = this._scrollInfo(cell, cell.getNode(0)); |
|
} |
|
if(info && info.s && info.sr && info.n){ |
|
// scroll horizontally as needed. |
|
var scroll = info.sr.l + info.sr.w; |
|
if(info.n.offsetLeft + info.n.offsetWidth > scroll){ |
|
info.s.scrollLeft = info.n.offsetLeft + info.n.offsetWidth - info.sr.w; |
|
}else if(info.n.offsetLeft < info.sr.l){ |
|
info.s.scrollLeft = info.n.offsetLeft; |
|
}else if(has('ie') <= 7 && cell && cell.view.headerNode){ |
|
// Trac 7158: scroll dojoxGridHeader for IE7 and lower |
|
cell.view.headerNode.scrollLeft = info.s.scrollLeft; |
|
} |
|
} |
|
}, |
|
_isHeaderHidden: function(){ |
|
// summary: |
|
// determine if the grid headers are hidden |
|
// relies on documented technique of setting .dojoxGridHeader { display:none; } |
|
// returns: Boolean |
|
// true if headers are hidden |
|
// false if headers are not hidden |
|
|
|
var curView = this.focusView; |
|
if (!curView){ |
|
// find one so we can determine if headers are hidden |
|
// there is no focusView after adding items to empty grid (test_data_grid_empty.html) |
|
for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) { |
|
if(cView.headerNode ){ |
|
curView=cView; |
|
break; |
|
} |
|
} |
|
} |
|
return (curView && html.getComputedStyle(curView.headerNode).display == "none"); |
|
}, |
|
colSizeAdjust: function (e, colIdx, delta){ // adjust the column specified by colIdx by the specified delta px |
|
var headers = this._findHeaderCells(); |
|
var view = this.focusView; |
|
if(!view || !view.header.tableMap.map){ |
|
for(var i = 0, cView; (cView = this.grid.views.views[i]); i++){ |
|
// find first view with a tableMap in order to work with empty grid |
|
if(cView.header.tableMap.map){ |
|
view=cView; |
|
break; |
|
} |
|
} |
|
} |
|
var curHeader = headers[colIdx]; |
|
if (!view || (colIdx == headers.length-1 && colIdx === 0)){ |
|
return; // can't adjust single col. grid |
|
} |
|
view.content.baseDecorateEvent(e); |
|
// need to adjust event with header cell info since focus is no longer on header cell |
|
e.cellNode = curHeader; //this.findCellTarget(e.target, e.rowNode); |
|
e.cellIndex = view.content.getCellNodeIndex(e.cellNode); |
|
e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null); |
|
if (view.header.canResize(e)){ |
|
var deltaObj = { |
|
l: delta |
|
}; |
|
var drag = view.header.colResizeSetup(e,false); |
|
view.header.doResizeColumn(drag, null, deltaObj); |
|
view.update(); |
|
} |
|
}, |
|
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; |
|
if (this._colHeadNode){ |
|
this.blurHeader(); |
|
} |
|
this._colHeadNode = this._colHeadFocusIdx = null; |
|
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(has('opera')){ |
|
setTimeout(lang.hitch(this.grid, 'onCellFocus', this.cell, this.rowIndex), 1); |
|
}else{ |
|
this.grid.onCellFocus(this.cell, this.rowIndex); |
|
} |
|
}, |
|
next: function(){ |
|
// summary: |
|
// focus next grid cell |
|
if(this.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; |
|
} |
|
if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells |
|
var nextCell = this.grid.getCell(col); |
|
if (!this.isLastFocusCell() && (!nextCell.editable || |
|
this.grid.canEdit && !this.grid.canEdit(nextCell, row))){ |
|
this.cell=nextCell; |
|
this.rowIndex=row; |
|
this.next(); |
|
return; |
|
} |
|
} |
|
this.setFocusIndex(row, col); |
|
} |
|
}, |
|
previous: function(){ |
|
// summary: |
|
// focus previous grid cell |
|
if(this.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; |
|
} |
|
if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells |
|
var prevCell = this.grid.getCell(col); |
|
if (!this.isFirstFocusCell() && !prevCell.editable){ |
|
this.cell=prevCell; |
|
this.rowIndex=row; |
|
this.previous(); |
|
return; |
|
} |
|
} |
|
this.setFocusIndex(row, col); |
|
} |
|
}, |
|
move: function(inRowDelta, inColDelta) { |
|
// summary: |
|
// focus grid cell or simulate focus to column header based on position relative to current focus |
|
// inRowDelta: int |
|
// vertical distance from current focus |
|
// inColDelta: int |
|
// horizontal distance from current focus |
|
|
|
var colDir = inColDelta < 0 ? -1 : 1; |
|
// Handle column headers. |
|
if(this.isNavHeader()){ |
|
var headers = this._findHeaderCells(); |
|
var savedIdx = currentIdx = array.indexOf(headers, this._colHeadNode); |
|
currentIdx += inColDelta; |
|
while(currentIdx >=0 && currentIdx < headers.length && headers[currentIdx].style.display == "none"){ |
|
// skip over hidden column headers |
|
currentIdx += colDir; |
|
} |
|
if((currentIdx >= 0) && (currentIdx < headers.length)){ |
|
this._setActiveColHeader(headers[currentIdx],currentIdx, savedIdx); |
|
} |
|
}else{ |
|
if(this.cell){ |
|
// Handle grid proper. |
|
var sc = this.grid.scroller, |
|
r = this.rowIndex, |
|
rc = this.grid.rowCount-1, |
|
row = Math.min(rc, Math.max(0, r+inRowDelta)); |
|
if(inRowDelta){ |
|
if(inRowDelta>0){ |
|
if(row > sc.getLastPageRow(sc.page)){ |
|
//need to load additional data, let scroller do that |
|
this.grid.setScrollTop(this.grid.scrollTop+sc.findScrollTop(row)-sc.findScrollTop(r)); |
|
} |
|
}else if(inRowDelta<0){ |
|
if(row <= sc.getPageRow(sc.page)){ |
|
//need to load additional data, let scroller do that |
|
this.grid.setScrollTop(this.grid.scrollTop-sc.findScrollTop(r)-sc.findScrollTop(row)); |
|
} |
|
} |
|
} |
|
var cc = this.grid.layout.cellCount-1, |
|
i = this.cell.index, |
|
col = Math.min(cc, Math.max(0, i+inColDelta)); |
|
var cell = this.grid.getCell(col); |
|
while(col>=0 && col < cc && cell && cell.hidden === true){ |
|
// skip hidden cells |
|
col += colDir; |
|
cell = this.grid.getCell(col); |
|
} |
|
if (!cell || cell.hidden === true){ |
|
// don't change col if would move to hidden |
|
col = i; |
|
} |
|
//skip hidden row|cell |
|
var n = cell.getNode(row); |
|
if(!n && inRowDelta){ |
|
if((row + inRowDelta) >= 0 && (row + inRowDelta) <= rc){ |
|
this.move(inRowDelta > 0 ? ++inRowDelta : --inRowDelta, inColDelta); |
|
} |
|
return; |
|
}else if((!n || html.style(n, "display") === "none") && inColDelta){ |
|
if((col + inColDelta) >= 0 && (col + inColDelta) <= cc){ |
|
this.move(inRowDelta, inColDelta > 0 ? ++inColDelta : --inColDelta); |
|
} |
|
return; |
|
} |
|
this.setFocusIndex(row, col); |
|
if(inRowDelta){ |
|
this.grid.updateRow(r); |
|
} |
|
} |
|
} |
|
}, |
|
previousKey: function(e){ |
|
if(this.grid.edit.isEditing()){ |
|
event.stop(e); |
|
this.previous(); |
|
}else if(!this.isNavHeader() && !this._isHeaderHidden()) { |
|
this.grid.domNode.focus(); // will call doFocus and set focus into header. |
|
event.stop(e); |
|
}else{ |
|
this.tabOut(this.grid.domNode); |
|
if (this._colHeadFocusIdx != null) { // clear grid header focus |
|
html.toggleClass(this._findHeaderCells()[this._colHeadFocusIdx], this.focusClass, false); |
|
this._colHeadFocusIdx = null; |
|
} |
|
this._focusifyCellNode(false); |
|
} |
|
}, |
|
nextKey: function(e) { |
|
var isEmpty = (this.grid.rowCount === 0); |
|
if(e.target === this.grid.domNode && this._colHeadFocusIdx == null){ |
|
this.focusHeader(); |
|
event.stop(e); |
|
}else if(this.isNavHeader()){ |
|
// if tabbing from col header, then go to grid proper. |
|
this.blurHeader(); |
|
if(!this.findAndFocusGridCell()){ |
|
this.tabOut(this.grid.lastFocusNode); |
|
} |
|
this._colHeadNode = this._colHeadFocusIdx= null; |
|
}else if(this.grid.edit.isEditing()){ |
|
event.stop(e); |
|
this.next(); |
|
}else{ |
|
this.tabOut(this.grid.lastFocusNode); |
|
} |
|
}, |
|
tabOut: function(inFocusNode){ |
|
this.tabbingOut = true; |
|
inFocusNode.focus(); |
|
}, |
|
focusGridView: function(){ |
|
util.fire(this.focusView, "focus"); |
|
}, |
|
focusGrid: function(inSkipFocusCell){ |
|
this.focusGridView(); |
|
this._focusifyCellNode(true); |
|
}, |
|
findAndFocusGridCell: function(){ |
|
// summary: |
|
// find the first focusable grid cell |
|
// returns: Boolean |
|
// true if focus was set to a cell |
|
// false if no cell found to set focus onto |
|
|
|
var didFocus = true; |
|
var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0 |
|
if (this.isNoFocusCell() && !isEmpty){ |
|
var cellIdx = 0; |
|
var cell = this.grid.getCell(cellIdx); |
|
if (cell.hidden) { |
|
// if first cell isn't visible, use _colHeadFocusIdx |
|
// could also use a while loop to find first visible cell - not sure that is worth it |
|
cellIdx = this.isNavHeader() ? this._colHeadFocusIdx : 0; |
|
} |
|
this.setFocusIndex(0, cellIdx); |
|
} |
|
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 { |
|
didFocus = false; |
|
} |
|
this._colHeadNode = this._colHeadFocusIdx= null; |
|
return didFocus; |
|
}, |
|
focusHeader: function(){ |
|
var headerNodes = this._findHeaderCells(); |
|
var saveColHeadFocusIdx = this._colHeadFocusIdx; |
|
if (this._isHeaderHidden()){ |
|
// grid header is hidden, focus a cell |
|
this.findAndFocusGridCell(); |
|
} |
|
else if (!this._colHeadFocusIdx) { |
|
if (this.isNoFocusCell()) { |
|
this._colHeadFocusIdx = 0; |
|
} |
|
else { |
|
this._colHeadFocusIdx = this.cell.index; |
|
} |
|
} |
|
this._colHeadNode = headerNodes[this._colHeadFocusIdx]; |
|
while(this._colHeadNode && this._colHeadFocusIdx >=0 && this._colHeadFocusIdx < headerNodes.length && |
|
this._colHeadNode.style.display == "none"){ |
|
// skip over hidden column headers |
|
this._colHeadFocusIdx++; |
|
this._colHeadNode = headerNodes[this._colHeadFocusIdx]; |
|
} |
|
if(this._colHeadNode && this._colHeadNode.style.display != "none"){ |
|
// Column header cells know longer receive actual focus. So, for keyboard invocation of |
|
// contextMenu to work, the contextMenu must be bound to the grid.domNode rather than the viewsHeaderNode. |
|
// unbind the contextmenu from the viewsHeaderNode and to the grid when header cells are active. Reset |
|
// the binding back to the viewsHeaderNode when header cells are no longer acive (in blurHeader) #10483 |
|
if (this.headerMenu && this._contextMenuBindNode != this.grid.domNode){ |
|
this.headerMenu.unBindDomNode(this.grid.viewsHeaderNode); |
|
this.headerMenu.bindDomNode(this.grid.domNode); |
|
this._contextMenuBindNode = this.grid.domNode; |
|
} |
|
this._setActiveColHeader(this._colHeadNode, this._colHeadFocusIdx, saveColHeadFocusIdx); |
|
this._scrollHeader(this._colHeadFocusIdx); |
|
this._focusifyCellNode(false); |
|
}else { |
|
// all col head nodes are hidden - focus the grid |
|
this.findAndFocusGridCell(); |
|
} |
|
}, |
|
blurHeader: function(){ |
|
html.removeClass(this._colHeadNode, this.focusClass); |
|
html.removeAttr(this.grid.domNode,"aria-activedescendant"); |
|
// reset contextMenu onto viewsHeaderNode so right mouse on header will invoke (see focusHeader) |
|
if (this.headerMenu && this._contextMenuBindNode == this.grid.domNode) { |
|
var viewsHeader = this.grid.viewsHeaderNode; |
|
this.headerMenu.unBindDomNode(this.grid.domNode); |
|
this.headerMenu.bindDomNode(viewsHeader); |
|
this._contextMenuBindNode = viewsHeader; |
|
} |
|
}, |
|
doFocus: function(e){ |
|
// trap focus only for grid dom node |
|
if(e && e.target != e.currentTarget){ |
|
event.stop(e); |
|
return; |
|
} |
|
// don't change focus if clicking on scroller bar |
|
if(this._clickFocus){ |
|
return; |
|
} |
|
// do not focus for scrolling if grid is about to blur |
|
if(!this.tabbingOut){ |
|
this.focusHeader(); |
|
} |
|
this.tabbingOut = false; |
|
event.stop(e); |
|
}, |
|
doBlur: function(e){ |
|
event.stop(e); // FF2 |
|
}, |
|
doContextMenu: function(e){ |
|
//stop contextMenu event if no header Menu to prevent default/browser contextMenu |
|
if (!this.headerMenu){ |
|
event.stop(e); |
|
} |
|
}, |
|
doLastNodeFocus: function(e){ |
|
if (this.tabbingOut){ |
|
this._focusifyCellNode(false); |
|
}else if(this.grid.rowCount >0){ |
|
if (this.isNoFocusCell()){ |
|
this.setFocusIndex(0,0); |
|
} |
|
this._focusifyCellNode(true); |
|
}else { |
|
this.focusHeader(); |
|
} |
|
this.tabbingOut = false; |
|
event.stop(e); // FF2 |
|
}, |
|
doLastNodeBlur: function(e){ |
|
event.stop(e); // FF2 |
|
}, |
|
doColHeaderFocus: function(e){ |
|
this._setActiveColHeader(e.target,html.attr(e.target, "idx"),this._colHeadFocusIdx); |
|
this._scrollHeader(this.getHeaderIndex()); |
|
event.stop(e); |
|
}, |
|
doColHeaderBlur: function(e){ |
|
html.toggleClass(e.target, this.focusClass, false); |
|
}, |
|
_mouseDown: function(e){ |
|
// a flag indicating grid is being focused by clicking |
|
this._clickFocus = dojo.some(this.grid.views.views, function(v){ |
|
return v.scrollboxNode === e.target; |
|
}); |
|
}, |
|
_mouseUp: function(e){ |
|
this._clickFocus = false; |
|
} |
|
}); |
|
}); |