259 lines
6.4 KiB
JavaScript
259 lines
6.4 KiB
JavaScript
|
//>>built
|
||
|
define("dojox/grid/_EditManager", [
|
||
|
"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;
|
||
|
if(has("ie")){
|
||
|
this.connections = [connect.connect(document.body, "onfocus", lang.hitch(this, "_boomerangFocus"))];
|
||
|
}else{
|
||
|
this.connections = [connect.connect(this.grid, 'onBlur', this, 'apply')];
|
||
|
}
|
||
|
},
|
||
|
|
||
|
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);
|
||
|
}
|
||
|
});
|
||
|
});
|