123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- /*
- Copyright (c) 2004-2012, 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._EditManager"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
- dojo._hasResource["dojox.grid._EditManager"] = true;
- dojo.provide("dojox.grid._EditManager");
- dojo.require("dojox.grid.util");
- dojo.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(dojo.isIE){
- this.connections = [dojo.connect(document.body, "onfocus", dojo.hitch(this, "_boomerangFocus"))];
- }else{
- this.connections = [dojo.connect(this.grid, 'onBlur', this, 'apply')];
- }
- },
-
- info: {},
- destroy: function(){
- dojo.forEach(this.connections,dojo.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){
- dojox.grid.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(dojo.isIE){this._catchBoomerang = new Date().getTime() + this._boomerangWindow;}
- },
- // end boomerang fix API
- start: function(inCell, inRowIndex, inEditing){
- if(!this._isValidInput()){
- return;
- }
- if(dojo.isIE && this.grid._autoHeight){
- this._avoidUpdate();//workaround for #11101
- }
- 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(c, 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);
- },
-
- _avoidUpdate: function(){
- // Use a flag to temporarily skip grid.update() so that dijit.form.Form.resize()
- // or similar containers will not result into a deadlock(see #11101)
- var self = this;
- self._noUpdate = true;
- if(self._avoidUpdateHandler){
- clearTimeout(self._avoidUpdateHandler);
- }
- self._avoidUpdateHandler = setTimeout(function(){
- self._noUpdate = false;
- }, 100);
- }
- });
- }
|