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.
263 lines
6.6 KiB
263 lines
6.6 KiB
define([ |
|
"dojo/_base/lang", |
|
"dojo/_base/array", |
|
"dojo/_base/declare", |
|
"dojo/_base/connect", |
|
"dojo/_base/sniff", |
|
"./util" |
|
], function(lang, array, declare, connect, has, util){ |
|
|
|
return declare("dojox.grid._EditManager", null, { |
|
// summary: |
|
// Controls grid cell editing process. Owned by grid and used internally for editing. |
|
constructor: function(inGrid){ |
|
// inGrid: dojox.Grid |
|
// The dojox.Grid this editor should be attached to |
|
this.grid = inGrid; |
|
this.connections = !has('ie') ? [] : [connect.connect(document.body, "onfocus", lang.hitch(this, "_boomerangFocus"))]; |
|
this.connections.push(connect.connect(this.grid, 'onBlur', this, 'apply')); |
|
this.connections.push(connect.connect(this.grid, 'prerender', this, '_onPreRender')); |
|
}, |
|
|
|
info: {}, |
|
|
|
destroy: function(){ |
|
array.forEach(this.connections, connect.disconnect); |
|
}, |
|
|
|
cellFocus: function(inCell, inRowIndex){ |
|
// summary: |
|
// Invoke editing when cell is focused |
|
// inCell: cell object |
|
// Grid cell object |
|
// inRowIndex: Integer |
|
// Grid row index |
|
if(this.grid.singleClickEdit || this.isEditRow(inRowIndex)){ |
|
// if same row or quick editing, edit |
|
this.setEditCell(inCell, inRowIndex); |
|
}else{ |
|
// otherwise, apply any pending row edits |
|
this.apply(); |
|
} |
|
// if dynamic or static editing... |
|
if(this.isEditing() || (inCell && inCell.editable && inCell.alwaysEditing)){ |
|
// let the editor focus itself as needed |
|
this._focusEditor(inCell, inRowIndex); |
|
} |
|
}, |
|
|
|
rowClick: function(e){ |
|
if(this.isEditing() && !this.isEditRow(e.rowIndex)){ |
|
this.apply(); |
|
} |
|
}, |
|
|
|
styleRow: function(inRow){ |
|
if(inRow.index == this.info.rowIndex){ |
|
inRow.customClasses += ' dojoxGridRowEditing'; |
|
} |
|
}, |
|
|
|
dispatchEvent: function(e){ |
|
var c = e.cell, ed = (c && c["editable"]) ? c : 0; |
|
return ed && ed.dispatchEvent(e.dispatch, e); |
|
}, |
|
|
|
// Editing |
|
isEditing: function(){ |
|
// summary: |
|
// Indicates editing state of the grid. |
|
// returns: Boolean |
|
// True if grid is actively editing |
|
return this.info.rowIndex !== undefined; |
|
}, |
|
|
|
isEditCell: function(inRowIndex, inCellIndex){ |
|
// summary: |
|
// Indicates if the given cell is being edited. |
|
// inRowIndex: Integer |
|
// Grid row index |
|
// inCellIndex: Integer |
|
// Grid cell index |
|
// returns: Boolean |
|
// True if given cell is being edited |
|
return (this.info.rowIndex === inRowIndex) && (this.info.cell.index == inCellIndex); |
|
}, |
|
|
|
isEditRow: function(inRowIndex){ |
|
// summary: |
|
// Indicates if the given row is being edited. |
|
// inRowIndex: Integer |
|
// Grid row index |
|
// returns: Boolean |
|
// True if given row is being edited |
|
return this.info.rowIndex === inRowIndex; |
|
}, |
|
|
|
setEditCell: function(inCell, inRowIndex){ |
|
// summary: |
|
// Set the given cell to be edited |
|
// inRowIndex: Integer |
|
// Grid row index |
|
// inCell: Object |
|
// Grid cell object |
|
if(!this.isEditCell(inRowIndex, inCell.index) && this.grid.canEdit && this.grid.canEdit(inCell, inRowIndex)){ |
|
this.start(inCell, inRowIndex, this.isEditRow(inRowIndex) || inCell.editable); |
|
} |
|
}, |
|
|
|
_focusEditor: function(inCell, inRowIndex){ |
|
util.fire(inCell, "focus", [inRowIndex]); |
|
}, |
|
|
|
focusEditor: function(){ |
|
if(this.isEditing()){ |
|
this._focusEditor(this.info.cell, this.info.rowIndex); |
|
} |
|
}, |
|
|
|
// implement fix for focus boomerang effect on IE |
|
_boomerangWindow: 500, |
|
_shouldCatchBoomerang: function(){ |
|
return this._catchBoomerang > new Date().getTime(); |
|
}, |
|
_boomerangFocus: function(){ |
|
//console.log("_boomerangFocus"); |
|
if(this._shouldCatchBoomerang()){ |
|
// make sure we don't utterly lose focus |
|
this.grid.focus.focusGrid(); |
|
// let the editor focus itself as needed |
|
this.focusEditor(); |
|
// only catch once |
|
this._catchBoomerang = 0; |
|
} |
|
}, |
|
_doCatchBoomerang: function(){ |
|
// give ourselves a few ms to boomerang IE focus effects |
|
if(has('ie')){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;} |
|
}, |
|
// end boomerang fix API |
|
|
|
start: function(inCell, inRowIndex, inEditing){ |
|
if(!this._isValidInput()){ |
|
return; |
|
} |
|
this.grid.beginUpdate(); |
|
this.editorApply(); |
|
if(this.isEditing() && !this.isEditRow(inRowIndex)){ |
|
this.applyRowEdit(); |
|
this.grid.updateRow(inRowIndex); |
|
} |
|
if(inEditing){ |
|
this.info = { cell: inCell, rowIndex: inRowIndex }; |
|
this.grid.doStartEdit(inCell, inRowIndex); |
|
this.grid.updateRow(inRowIndex); |
|
}else{ |
|
this.info = {}; |
|
} |
|
this.grid.endUpdate(); |
|
// make sure we don't utterly lose focus |
|
this.grid.focus.focusGrid(); |
|
// let the editor focus itself as needed |
|
this._focusEditor(inCell, inRowIndex); |
|
// give ourselves a few ms to boomerang IE focus effects |
|
this._doCatchBoomerang(); |
|
}, |
|
|
|
_editorDo: function(inMethod){ |
|
var c = this.info.cell; |
|
//c && c.editor && c.editor[inMethod](c, this.info.rowIndex); |
|
if(c && c.editable){ |
|
c[inMethod](this.info.rowIndex); |
|
} |
|
}, |
|
|
|
editorApply: function(){ |
|
this._editorDo("apply"); |
|
}, |
|
|
|
editorCancel: function(){ |
|
this._editorDo("cancel"); |
|
}, |
|
|
|
applyCellEdit: function(inValue, inCell, inRowIndex){ |
|
if(this.grid.canEdit(inCell, inRowIndex)){ |
|
this.grid.doApplyCellEdit(inValue, inRowIndex, inCell.field); |
|
} |
|
}, |
|
|
|
applyRowEdit: function(){ |
|
this.grid.doApplyEdit(this.info.rowIndex, this.info.cell.field); |
|
}, |
|
|
|
apply: function(){ |
|
// summary: |
|
// Apply a grid edit |
|
if(this.isEditing() && this._isValidInput()){ |
|
this.grid.beginUpdate(); |
|
this.editorApply(); |
|
this.applyRowEdit(); |
|
this.info = {}; |
|
this.grid.endUpdate(); |
|
this.grid.focus.focusGrid(); |
|
this._doCatchBoomerang(); |
|
} |
|
}, |
|
|
|
cancel: function(){ |
|
// summary: |
|
// Cancel a grid edit |
|
if(this.isEditing()){ |
|
this.grid.beginUpdate(); |
|
this.editorCancel(); |
|
this.info = {}; |
|
this.grid.endUpdate(); |
|
this.grid.focus.focusGrid(); |
|
this._doCatchBoomerang(); |
|
} |
|
}, |
|
|
|
save: function(inRowIndex, inView){ |
|
// summary: |
|
// Save the grid editing state |
|
// inRowIndex: Integer |
|
// Grid row index |
|
// inView: Object |
|
// Grid view |
|
var c = this.info.cell; |
|
if(this.isEditRow(inRowIndex) && (!inView || c.view==inView) && c.editable){ |
|
c.save(c, this.info.rowIndex); |
|
} |
|
}, |
|
|
|
restore: function(inView, inRowIndex){ |
|
// summary: |
|
// Restores the grid editing state |
|
// inRowIndex: Integer |
|
// Grid row index |
|
// inView: Object |
|
// Grid view |
|
var c = this.info.cell; |
|
if(this.isEditRow(inRowIndex) && c.view == inView && c.editable){ |
|
c.restore(this.info.rowIndex); |
|
} |
|
}, |
|
|
|
_isValidInput: function(){ |
|
var w = (this.info.cell || {}).widget; |
|
if(!w || !w.isValid){ |
|
//no validation needed |
|
return true; |
|
} |
|
w.focused = true; |
|
return w.isValid(true); |
|
}, |
|
|
|
_onPreRender: function(){ |
|
if(this.isEditing()){ |
|
//cache the current editing value before render |
|
this.info.value = this.info.cell.getValue(); |
|
} |
|
} |
|
}); |
|
}); |