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

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.CellSelectionModel
  9.  * @extends Ext.grid.AbstractSelectionModel
  10.  * This class provides the basic implementation for <i>single</i> <b>cell</b> selection in a grid.
  11.  * The object stored as the selection contains the following properties:
  12.  * <div class="mdetail-params"><ul>
  13.  * <li><b>cell</b> : see {@link #getSelectedCell} 
  14.  * <li><b>record</b> : Ext.data.record The {@link Ext.data.Record Record}
  15.  * which provides the data for the row containing the selection</li>
  16.  * </ul></div>
  17.  * @constructor
  18.  * @param {Object} config The object containing the configuration of this model.
  19.  */
  20. Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel,  {
  21.     
  22.     constructor : function(config){
  23.         Ext.apply(this, config);
  24.     this.selection = null;
  25.     this.addEvents(
  26.         /**
  27.          * @event beforecellselect
  28.          * Fires before a cell is selected, return false to cancel the selection.
  29.          * @param {SelectionModel} this
  30.          * @param {Number} rowIndex The selected row index
  31.          * @param {Number} colIndex The selected cell index
  32.          */
  33.         "beforecellselect",
  34.         /**
  35.          * @event cellselect
  36.          * Fires when a cell is selected.
  37.          * @param {SelectionModel} this
  38.          * @param {Number} rowIndex The selected row index
  39.          * @param {Number} colIndex The selected cell index
  40.          */
  41.         "cellselect",
  42.         /**
  43.          * @event selectionchange
  44.          * Fires when the active selection changes.
  45.          * @param {SelectionModel} this
  46.          * @param {Object} selection null for no selection or an object with two properties
  47.          * <div class="mdetail-params"><ul>
  48.          * <li><b>cell</b> : see {@link #getSelectedCell} 
  49.          * <li><b>record</b> : Ext.data.record<p class="sub-desc">The {@link Ext.data.Record Record}
  50.          * which provides the data for the row containing the selection</p></li>
  51.          * </ul></div>
  52.          */
  53.         "selectionchange"
  54.     );
  55.     Ext.grid.CellSelectionModel.superclass.constructor.call(this);
  56.     },
  57.     /** @ignore */
  58.     initEvents : function(){
  59.         this.grid.on('cellmousedown', this.handleMouseDown, this);
  60.         this.grid.on(Ext.EventManager.useKeydown ? 'keydown' : 'keypress', this.handleKeyDown, this);
  61.         this.grid.getView().on({
  62.             scope: this,
  63.             refresh: this.onViewChange,
  64.             rowupdated: this.onRowUpdated,
  65.             beforerowremoved: this.clearSelections,
  66.             beforerowsinserted: this.clearSelections
  67.         });
  68.         if(this.grid.isEditor){
  69.             this.grid.on('beforeedit', this.beforeEdit,  this);
  70.         }
  71.     },
  72. //private
  73.     beforeEdit : function(e){
  74.         this.select(e.row, e.column, false, true, e.record);
  75.     },
  76. //private
  77.     onRowUpdated : function(v, index, r){
  78.         if(this.selection && this.selection.record == r){
  79.             v.onCellSelect(index, this.selection.cell[1]);
  80.         }
  81.     },
  82. //private
  83.     onViewChange : function(){
  84.         this.clearSelections(true);
  85.     },
  86. /**
  87.      * Returns an array containing the row and column indexes of the currently selected cell
  88.      * (e.g., [0, 0]), or null if none selected. The array has elements:
  89.      * <div class="mdetail-params"><ul>
  90.      * <li><b>rowIndex</b> : Number<p class="sub-desc">The index of the selected row</p></li>
  91.      * <li><b>cellIndex</b> : Number<p class="sub-desc">The index of the selected cell. 
  92.      * Due to possible column reordering, the cellIndex should <b>not</b> be used as an
  93.      * index into the Record's data. Instead, use the cellIndex to determine the <i>name</i>
  94.      * of the selected cell and use the field name to retrieve the data value from the record:<pre><code>
  95. // get name
  96. var fieldName = grid.getColumnModel().getDataIndex(cellIndex);
  97. // get data value based on name
  98. var data = record.get(fieldName);
  99.      * </code></pre></p></li>
  100.      * </ul></div>
  101.      * @return {Array} An array containing the row and column indexes of the selected cell, or null if none selected.
  102.  */
  103.     getSelectedCell : function(){
  104.         return this.selection ? this.selection.cell : null;
  105.     },
  106.     /**
  107.      * If anything is selected, clears all selections and fires the selectionchange event.
  108.      * @param {Boolean} preventNotify <tt>true</tt> to prevent the gridview from
  109.      * being notified about the change.
  110.      */
  111.     clearSelections : function(preventNotify){
  112.         var s = this.selection;
  113.         if(s){
  114.             if(preventNotify !== true){
  115.                 this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
  116.             }
  117.             this.selection = null;
  118.             this.fireEvent("selectionchange", this, null);
  119.         }
  120.     },
  121.     /**
  122.      * Returns <tt>true</tt> if there is a selection.
  123.      * @return {Boolean}
  124.      */
  125.     hasSelection : function(){
  126.         return this.selection ? true : false;
  127.     },
  128.     /** @ignore */
  129.     handleMouseDown : function(g, row, cell, e){
  130.         if(e.button !== 0 || this.isLocked()){
  131.             return;
  132.         }
  133.         this.select(row, cell);
  134.     },
  135.     /**
  136.      * Selects a cell.  Before selecting a cell, fires the
  137.      * {@link #beforecellselect} event.  If this check is satisfied the cell
  138.      * will be selected and followed up by  firing the {@link #cellselect} and
  139.      * {@link #selectionchange} events.
  140.      * @param {Number} rowIndex The index of the row to select
  141.      * @param {Number} colIndex The index of the column to select
  142.      * @param {Boolean} preventViewNotify (optional) Specify <tt>true</tt> to
  143.      * prevent notifying the view (disables updating the selected appearance)
  144.      * @param {Boolean} preventFocus (optional) Whether to prevent the cell at
  145.      * the specified rowIndex / colIndex from being focused.
  146.      * @param {Ext.data.Record} r (optional) The record to select
  147.      */
  148.     select : function(rowIndex, colIndex, preventViewNotify, preventFocus, /*internal*/ r){
  149.         if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
  150.             this.clearSelections();
  151.             r = r || this.grid.store.getAt(rowIndex);
  152.             this.selection = {
  153.                 record : r,
  154.                 cell : [rowIndex, colIndex]
  155.             };
  156.             if(!preventViewNotify){
  157.                 var v = this.grid.getView();
  158.                 v.onCellSelect(rowIndex, colIndex);
  159.                 if(preventFocus !== true){
  160.                     v.focusCell(rowIndex, colIndex);
  161.                 }
  162.             }
  163.             this.fireEvent("cellselect", this, rowIndex, colIndex);
  164.             this.fireEvent("selectionchange", this, this.selection);
  165.         }
  166.     },
  167. //private
  168.     isSelectable : function(rowIndex, colIndex, cm){
  169.         return !cm.isHidden(colIndex);
  170.     },
  171.     
  172.     // private
  173.     onEditorKey: function(field, e){
  174.         if(e.getKey() == e.TAB){
  175.             this.handleKeyDown(e);
  176.         }
  177.     },
  178.     /** @ignore */
  179.     handleKeyDown : function(e){
  180.         if(!e.isNavKeyPress()){
  181.             return;
  182.         }
  183.         
  184.         var k = e.getKey(),
  185.             g = this.grid,
  186.             s = this.selection,
  187.             sm = this,
  188.             walk = function(row, col, step){
  189.                 return g.walkCells(
  190.                     row,
  191.                     col,
  192.                     step,
  193.                     g.isEditor && g.editing ? sm.acceptsNav : sm.isSelectable, // *** handle tabbing while editorgrid is in edit mode
  194.                     sm
  195.                 );
  196.             },
  197.             cell, newCell, r, c, ae;
  198.         switch(k){
  199.             case e.ESC:
  200.             case e.PAGE_UP:
  201.             case e.PAGE_DOWN:
  202.                 // do nothing
  203.                 break;
  204.             default:
  205.                 // *** call e.stopEvent() only for non ESC, PAGE UP/DOWN KEYS
  206.                 e.stopEvent();
  207.                 break;
  208.         }
  209.         if(!s){
  210.             cell = walk(0, 0, 1); // *** use private walk() function defined above
  211.             if(cell){
  212.                 this.select(cell[0], cell[1]);
  213.             }
  214.             return;
  215.         }
  216.         cell = s.cell;  // currently selected cell
  217.         r = cell[0];    // current row
  218.         c = cell[1];    // current column
  219.         
  220.         switch(k){
  221.             case e.TAB:
  222.                 if(e.shiftKey){
  223.                     newCell = walk(r, c - 1, -1);
  224.                 }else{
  225.                     newCell = walk(r, c + 1, 1);
  226.                 }
  227.                 break;
  228.             case e.DOWN:
  229.                 newCell = walk(r + 1, c, 1);
  230.                 break;
  231.             case e.UP:
  232.                 newCell = walk(r - 1, c, -1);
  233.                 break;
  234.             case e.RIGHT:
  235.                 newCell = walk(r, c + 1, 1);
  236.                 break;
  237.             case e.LEFT:
  238.                 newCell = walk(r, c - 1, -1);
  239.                 break;
  240.             case e.ENTER:
  241.                 if (g.isEditor && !g.editing) {
  242.                     g.startEditing(r, c);
  243.                     return;
  244.                 }
  245.                 break;
  246.         }
  247.         if(newCell){
  248.             // *** reassign r & c variables to newly-selected cell's row and column
  249.             r = newCell[0];
  250.             c = newCell[1];
  251.             this.select(r, c); // *** highlight newly-selected cell and update selection
  252.             if(g.isEditor && g.editing){ // *** handle tabbing while editorgrid is in edit mode
  253.                 ae = g.activeEditor;
  254.                 if(ae && ae.field.triggerBlur){
  255.                     // *** if activeEditor is a TriggerField, explicitly call its triggerBlur() method
  256.                     ae.field.triggerBlur();
  257.                 }
  258.                 g.startEditing(r, c);
  259.             }
  260.         }
  261.     },
  262.     acceptsNav : function(row, col, cm){
  263.         return !cm.isHidden(col) && cm.isCellEditable(col, row);
  264.     }
  265. });