EditorGrid.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:12k
源码类别:

JavaScript

开发平台:

JavaScript

  1. /*!
  2.  * Ext JS Library 3.1.0
  3.  * Copyright(c) 2006-2009 Ext JS, LLC
  4.  * licensing@extjs.com
  5.  * http://www.extjs.com/license
  6.  */
  7. /**
  8.  * @class Ext.grid.EditorGridPanel
  9.  * @extends Ext.grid.GridPanel
  10.  * <p>This class extends the {@link Ext.grid.GridPanel GridPanel Class} to provide cell editing
  11.  * on selected {@link Ext.grid.Column columns}. The editable columns are specified by providing
  12.  * an {@link Ext.grid.ColumnModel#editor editor} in the {@link Ext.grid.Column column configuration}.</p>
  13.  * <p>Editability of columns may be controlled programatically by inserting an implementation
  14.  * of {@link Ext.grid.ColumnModel#isCellEditable isCellEditable} into the
  15.  * {@link Ext.grid.ColumnModel ColumnModel}.</p>
  16.  * <p>Editing is performed on the value of the <i>field</i> specified by the column's
  17.  * <tt>{@link Ext.grid.ColumnModel#dataIndex dataIndex}</tt> in the backing {@link Ext.data.Store Store}
  18.  * (so if you are using a {@link Ext.grid.ColumnModel#setRenderer renderer} in order to display
  19.  * transformed data, this must be accounted for).</p>
  20.  * <p>If a value-to-description mapping is used to render a column, then a {@link Ext.form.Field#ComboBox ComboBox}
  21.  * which uses the same {@link Ext.form.Field#valueField value}-to-{@link Ext.form.Field#displayFieldField description}
  22.  * mapping would be an appropriate editor.</p>
  23.  * If there is a more complex mismatch between the visible data in the grid, and the editable data in
  24.  * the {@link Edt.data.Store Store}, then code to transform the data both before and after editing can be
  25.  * injected using the {@link #beforeedit} and {@link #afteredit} events.
  26.  * @constructor
  27.  * @param {Object} config The config object
  28.  * @xtype editorgrid
  29.  */
  30. Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
  31.     /**
  32.      * @cfg {Number} clicksToEdit
  33.      * <p>The number of clicks on a cell required to display the cell's editor (defaults to 2).</p>
  34.      * <p>Setting this option to 'auto' means that mousedown <i>on the selected cell</i> starts
  35.      * editing that cell.</p>
  36.      */
  37.     clicksToEdit: 2,
  38.     
  39.     /**
  40.     * @cfg {Boolean} forceValidation
  41.     * True to force validation even if the value is unmodified (defaults to false)
  42.     */
  43.     forceValidation: false,
  44.     // private
  45.     isEditor : true,
  46.     // private
  47.     detectEdit: false,
  48. /**
  49.  * @cfg {Boolean} autoEncode
  50.  * True to automatically HTML encode and decode values pre and post edit (defaults to false)
  51.  */
  52. autoEncode : false,
  53. /**
  54.  * @cfg {Boolean} trackMouseOver @hide
  55.  */
  56.     // private
  57.     trackMouseOver: false, // causes very odd FF errors
  58.     // private
  59.     initComponent : function(){
  60.         Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
  61.         if(!this.selModel){
  62.             /**
  63.              * @cfg {Object} selModel Any subclass of AbstractSelectionModel that will provide the selection model for
  64.              * the grid (defaults to {@link Ext.grid.CellSelectionModel} if not specified).
  65.              */
  66.             this.selModel = new Ext.grid.CellSelectionModel();
  67.         }
  68.         this.activeEditor = null;
  69.     this.addEvents(
  70.             /**
  71.              * @event beforeedit
  72.              * Fires before cell editing is triggered. The edit event object has the following properties <br />
  73.              * <ul style="padding:5px;padding-left:16px;">
  74.              * <li>grid - This grid</li>
  75.              * <li>record - The record being edited</li>
  76.              * <li>field - The field name being edited</li>
  77.              * <li>value - The value for the field being edited.</li>
  78.              * <li>row - The grid row index</li>
  79.              * <li>column - The grid column index</li>
  80.              * <li>cancel - Set this to true to cancel the edit or return false from your handler.</li>
  81.              * </ul>
  82.              * @param {Object} e An edit event (see above for description)
  83.              */
  84.             "beforeedit",
  85.             /**
  86.              * @event afteredit
  87.              * Fires after a cell is edited. The edit event object has the following properties <br />
  88.              * <ul style="padding:5px;padding-left:16px;">
  89.              * <li>grid - This grid</li>
  90.              * <li>record - The record being edited</li>
  91.              * <li>field - The field name being edited</li>
  92.              * <li>value - The value being set</li>
  93.              * <li>originalValue - The original value for the field, before the edit.</li>
  94.              * <li>row - The grid row index</li>
  95.              * <li>column - The grid column index</li>
  96.              * </ul>
  97.              *
  98.              * <pre><code> 
  99. grid.on('afteredit', afterEdit, this );
  100. function afterEdit(e) {
  101.     // execute an XHR to send/commit data to the server, in callback do (if successful):
  102.     e.record.commit();
  103. }; 
  104.              * </code></pre>
  105.              * @param {Object} e An edit event (see above for description)
  106.              */
  107.             "afteredit",
  108.             /**
  109.              * @event validateedit
  110.              * Fires after a cell is edited, but before the value is set in the record. Return false
  111.              * to cancel the change. The edit event object has the following properties <br />
  112.              * <ul style="padding:5px;padding-left:16px;">
  113.              * <li>grid - This grid</li>
  114.              * <li>record - The record being edited</li>
  115.              * <li>field - The field name being edited</li>
  116.              * <li>value - The value being set</li>
  117.              * <li>originalValue - The original value for the field, before the edit.</li>
  118.              * <li>row - The grid row index</li>
  119.              * <li>column - The grid column index</li>
  120.              * <li>cancel - Set this to true to cancel the edit or return false from your handler.</li>
  121.              * </ul>
  122.              * Usage example showing how to remove the red triangle (dirty record indicator) from some
  123.              * records (not all).  By observing the grid's validateedit event, it can be cancelled if
  124.              * the edit occurs on a targeted row (for example) and then setting the field's new value
  125.              * in the Record directly:
  126.              * <pre><code> 
  127. grid.on('validateedit', function(e) {
  128.   var myTargetRow = 6;
  129.  
  130.   if (e.row == myTargetRow) {
  131.     e.cancel = true;
  132.     e.record.data[e.field] = e.value;
  133.   }
  134. });
  135.              * </code></pre>
  136.              * @param {Object} e An edit event (see above for description)
  137.              */
  138.             "validateedit"
  139.         );
  140.     },
  141.     // private
  142.     initEvents : function(){
  143.         Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
  144.         this.getGridEl().on('mousewheel', this.stopEditing.createDelegate(this, [true]), this);
  145.         this.on('columnresize', this.stopEditing, this, [true]);
  146.         if(this.clicksToEdit == 1){
  147.             this.on("cellclick", this.onCellDblClick, this);
  148.         }else {
  149.             var view = this.getView();
  150.             if(this.clicksToEdit == 'auto' && view.mainBody){
  151.                 view.mainBody.on('mousedown', this.onAutoEditClick, this);
  152.             }
  153.             this.on('celldblclick', this.onCellDblClick, this);
  154.         }
  155.     },
  156.     
  157.     onResize : function(){
  158.         Ext.grid.EditorGridPanel.superclass.onResize.apply(this, arguments);
  159.         var ae = this.activeEditor;
  160.         if(this.editing && ae){
  161.             ae.realign(true);
  162.         }
  163.     },
  164.     // private
  165.     onCellDblClick : function(g, row, col){
  166.         this.startEditing(row, col);
  167.     },
  168.     // private
  169.     onAutoEditClick : function(e, t){
  170.         if(e.button !== 0){
  171.             return;
  172.         }
  173.         var row = this.view.findRowIndex(t),
  174.             col = this.view.findCellIndex(t);
  175.         if(row !== false && col !== false){
  176.             this.stopEditing();
  177.             if(this.selModel.getSelectedCell){ // cell sm
  178.                 var sc = this.selModel.getSelectedCell();
  179.                 if(sc && sc[0] === row && sc[1] === col){
  180.                     this.startEditing(row, col);
  181.                 }
  182.             }else{
  183.                 if(this.selModel.isSelected(row)){
  184.                     this.startEditing(row, col);
  185.                 }
  186.             }
  187.         }
  188.     },
  189.     // private
  190.     onEditComplete : function(ed, value, startValue){
  191.         this.editing = false;
  192.         this.activeEditor = null;
  193.         
  194. var r = ed.record,
  195.             field = this.colModel.getDataIndex(ed.col);
  196.         value = this.postEditValue(value, startValue, r, field);
  197.         if(this.forceValidation === true || String(value) !== String(startValue)){
  198.             var e = {
  199.                 grid: this,
  200.                 record: r,
  201.                 field: field,
  202.                 originalValue: startValue,
  203.                 value: value,
  204.                 row: ed.row,
  205.                 column: ed.col,
  206.                 cancel:false
  207.             };
  208.             if(this.fireEvent("validateedit", e) !== false && !e.cancel && String(value) !== String(startValue)){
  209.                 r.set(field, e.value);
  210.                 delete e.cancel;
  211.                 this.fireEvent("afteredit", e);
  212.             }
  213.         }
  214.         this.view.focusCell(ed.row, ed.col);
  215.     },
  216.     /**
  217.      * Starts editing the specified for the specified row/column
  218.      * @param {Number} rowIndex
  219.      * @param {Number} colIndex
  220.      */
  221.     startEditing : function(row, col){
  222.         this.stopEditing();
  223.         if(this.colModel.isCellEditable(col, row)){
  224.             this.view.ensureVisible(row, col, true);
  225.             var r = this.store.getAt(row),
  226.                 field = this.colModel.getDataIndex(col),
  227.                 e = {
  228.                     grid: this,
  229.                     record: r,
  230.                     field: field,
  231.                     value: r.data[field],
  232.                     row: row,
  233.                     column: col,
  234.                     cancel:false
  235.                 };
  236.             if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
  237.                 this.editing = true;
  238.                 var ed = this.colModel.getCellEditor(col, row);
  239.                 if(!ed){
  240.                     return;
  241.                 }
  242.                 if(!ed.rendered){
  243.                     ed.parentEl = this.view.getEditorParent(ed);
  244.                     ed.on({
  245.                         scope: this,
  246.                         render: {
  247.                             fn: function(c){
  248.                                 c.field.focus(false, true);
  249.                             },
  250.                             single: true,
  251.                             scope: this
  252.                         },
  253.                         specialkey: function(field, e){
  254.                             this.getSelectionModel().onEditorKey(field, e);
  255.                         },
  256.                         complete: this.onEditComplete,
  257.                         canceledit: this.stopEditing.createDelegate(this, [true])
  258.                     });
  259.                 }
  260.                 Ext.apply(ed, {
  261.                     row     : row,
  262.                     col     : col,
  263.                     record  : r
  264.                 });
  265.                 this.lastEdit = {
  266.                     row: row,
  267.                     col: col
  268.                 };
  269.                 this.activeEditor = ed;
  270.                 var v = this.preEditValue(r, field);
  271.                 ed.startEdit(this.view.getCell(row, col).firstChild, Ext.isDefined(v) ? v : '');
  272.             }
  273.         }
  274.     },
  275.     // private
  276.     preEditValue : function(r, field){
  277.         var value = r.data[field];
  278.         return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlDecode(value) : value;
  279.     },
  280.     // private
  281. postEditValue : function(value, originalValue, r, field){
  282. return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value;
  283. },
  284.     /**
  285.      * Stops any active editing
  286.      * @param {Boolean} cancel (optional) True to cancel any changes
  287.      */
  288.     stopEditing : function(cancel){
  289.         if(this.editing){
  290.             var ae = this.activeEditor;
  291.             if(ae){
  292.                 ae[cancel === true ? 'cancelEdit' : 'completeEdit']();
  293.                 this.view.focusCell(ae.row, ae.col);
  294.             }
  295.             this.activeEditor = null;
  296.         }
  297.         this.editing = false;
  298.     }
  299. });
  300. Ext.reg('editorgrid', Ext.grid.EditorGridPanel);