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

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.ColumnModel
  9.  * @extends Ext.util.Observable
  10.  * <p>After the data has been read into the client side cache (<b>{@link Ext.data.Store Store}</b>),
  11.  * the ColumnModel is used to configure how and what parts of that data will be displayed in the
  12.  * vertical slices (columns) of the grid. The Ext.grid.ColumnModel Class is the default implementation
  13.  * of a ColumnModel used by implentations of {@link Ext.grid.GridPanel GridPanel}.</p>
  14.  * <p>Data is mapped into the store's records and then indexed into the ColumnModel using the
  15.  * <tt>{@link Ext.grid.Column#dataIndex dataIndex}</tt>:</p>
  16.  * <pre><code>
  17. {data source} == mapping ==> {data store} == <b><tt>{@link Ext.grid.Column#dataIndex dataIndex}</tt></b> ==> {ColumnModel}
  18.  * </code></pre>
  19.  * <p>Each {@link Ext.grid.Column Column} in the grid's ColumnModel is configured with a
  20.  * <tt>{@link Ext.grid.Column#dataIndex dataIndex}</tt> to specify how the data within
  21.  * each record in the store is indexed into the ColumnModel.</p>
  22.  * <p>There are two ways to initialize the ColumnModel class:</p>
  23.  * <p><u>Initialization Method 1: an Array</u></p>
  24. <pre><code>
  25.  var colModel = new Ext.grid.ColumnModel([
  26.     { header: "Ticker", width: 60, sortable: true},
  27.     { header: "Company Name", width: 150, sortable: true, id: 'company'},
  28.     { header: "Market Cap.", width: 100, sortable: true},
  29.     { header: "$ Sales", width: 100, sortable: true, renderer: money},
  30.     { header: "Employees", width: 100, sortable: true, resizable: false}
  31.  ]);
  32.  </code></pre>
  33.  * <p>The ColumnModel may be initialized with an Array of {@link Ext.grid.Column} column configuration
  34.  * objects to define the initial layout / display of the columns in the Grid. The order of each
  35.  * {@link Ext.grid.Column} column configuration object within the specified Array defines the initial
  36.  * order of the column display.  A Column's display may be initially hidden using the
  37.  * <tt>{@link Ext.grid.Column#hidden hidden}</tt></b> config property (and then shown using the column
  38.  * header menu).  Fields that are not included in the ColumnModel will not be displayable at all.</p>
  39.  * <p>How each column in the grid correlates (maps) to the {@link Ext.data.Record} field in the
  40.  * {@link Ext.data.Store Store} the column draws its data from is configured through the
  41.  * <b><tt>{@link Ext.grid.Column#dataIndex dataIndex}</tt></b>.  If the
  42.  * <b><tt>{@link Ext.grid.Column#dataIndex dataIndex}</tt></b> is not explicitly defined (as shown in the
  43.  * example above) it will use the column configuration's index in the Array as the index.</p>
  44.  * <p>See <b><tt>{@link Ext.grid.Column}</tt></b> for additional configuration options for each column.</p>
  45.  * <p><u>Initialization Method 2: an Object</u></p>
  46.  * <p>In order to use configuration options from <tt>Ext.grid.ColumnModel</tt>, an Object may be used to
  47.  * initialize the ColumnModel.  The column configuration Array will be specified in the <tt><b>{@link #columns}</b></tt>
  48.  * config property. The <tt><b>{@link #defaults}</b></tt> config property can be used to apply defaults
  49.  * for all columns, e.g.:</p><pre><code>
  50.  var colModel = new Ext.grid.ColumnModel({
  51.     columns: [
  52.         { header: "Ticker", width: 60, menuDisabled: false},
  53.         { header: "Company Name", width: 150, id: 'company'},
  54.         { header: "Market Cap."},
  55.         { header: "$ Sales", renderer: money},
  56.         { header: "Employees", resizable: false}
  57.     ],
  58.     defaults: {
  59.         sortable: true,
  60.         menuDisabled: true,
  61.         width: 100
  62.     },
  63.     listeners: {
  64.         {@link #hiddenchange}: function(cm, colIndex, hidden) {
  65.             saveConfig(colIndex, hidden);
  66.         }
  67.     }
  68. });
  69.  </code></pre>
  70.  * <p>In both examples above, the ability to apply a CSS class to all cells in a column (including the
  71.  * header) is demonstrated through the use of the <b><tt>{@link Ext.grid.Column#id id}</tt></b> config
  72.  * option. This column could be styled by including the following css:</p><pre><code>
  73.  //add this css *after* the core css is loaded
  74. .x-grid3-td-company {
  75.     color: red; // entire column will have red font
  76. }
  77. // modify the header row only, adding an icon to the column header
  78. .x-grid3-hd-company {
  79.     background: transparent
  80.         url(../../resources/images/icons/silk/building.png)
  81.         no-repeat 3px 3px ! important;
  82.         padding-left:20px;
  83. }
  84.  </code></pre>
  85.  * Note that the "Company Name" column could be specified as the
  86.  * <b><tt>{@link Ext.grid.GridPanel}.{@link Ext.grid.GridPanel#autoExpandColumn autoExpandColumn}</tt></b>.
  87.  * @constructor
  88.  * @param {Mixed} config Specify either an Array of {@link Ext.grid.Column} configuration objects or specify
  89.  * a configuration Object (see introductory section discussion utilizing Initialization Method 2 above).
  90.  */
  91. Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
  92.     /**
  93.      * @cfg {Number} defaultWidth (optional) The width of columns which have no <tt>{@link #width}</tt>
  94.      * specified (defaults to <tt>100</tt>).  This property shall preferably be configured through the
  95.      * <tt><b>{@link #defaults}</b></tt> config property.
  96.      */
  97.     defaultWidth: 100,
  98.     /**
  99.      * @cfg {Boolean} defaultSortable (optional) Default sortable of columns which have no
  100.      * sortable specified (defaults to <tt>false</tt>).  This property shall preferably be configured
  101.      * through the <tt><b>{@link #defaults}</b></tt> config property.
  102.      */
  103.     defaultSortable: false,
  104.     /**
  105.      * @cfg {Array} columns An Array of object literals.  The config options defined by
  106.      * <b>{@link Ext.grid.Column}</b> are the options which may appear in the object literal for each
  107.      * individual column definition.
  108.      */
  109.     /**
  110.      * @cfg {Object} defaults Object literal which will be used to apply {@link Ext.grid.Column}
  111.      * configuration options to all <tt><b>{@link #columns}</b></tt>.  Configuration options specified with
  112.      * individual {@link Ext.grid.Column column} configs will supersede these <tt><b>{@link #defaults}</b></tt>.
  113.      */
  114.     
  115.     constructor : function(config){
  116.         /**
  117.      * An Array of {@link Ext.grid.Column Column definition} objects representing the configuration
  118.      * of this ColumnModel.  See {@link Ext.grid.Column} for the configuration properties that may
  119.      * be specified.
  120.      * @property config
  121.      * @type Array
  122.      */
  123.     if(config.columns){
  124.         Ext.apply(this, config);
  125.         this.setConfig(config.columns, true);
  126.     }else{
  127.         this.setConfig(config, true);
  128.     }
  129.     this.addEvents(
  130.         /**
  131.          * @event widthchange
  132.          * Fires when the width of a column is programmaticially changed using
  133.          * <code>{@link #setColumnWidth}</code>.
  134.          * Note internal resizing suppresses the event from firing. See also
  135.          * {@link Ext.grid.GridPanel}.<code>{@link #columnresize}</code>.
  136.          * @param {ColumnModel} this
  137.          * @param {Number} columnIndex The column index
  138.          * @param {Number} newWidth The new width
  139.          */
  140.         "widthchange",
  141.         /**
  142.          * @event headerchange
  143.          * Fires when the text of a header changes.
  144.          * @param {ColumnModel} this
  145.          * @param {Number} columnIndex The column index
  146.          * @param {String} newText The new header text
  147.          */
  148.         "headerchange",
  149.         /**
  150.          * @event hiddenchange
  151.          * Fires when a column is hidden or "unhidden".
  152.          * @param {ColumnModel} this
  153.          * @param {Number} columnIndex The column index
  154.          * @param {Boolean} hidden true if hidden, false otherwise
  155.          */
  156.         "hiddenchange",
  157.         /**
  158.          * @event columnmoved
  159.          * Fires when a column is moved.
  160.          * @param {ColumnModel} this
  161.          * @param {Number} oldIndex
  162.          * @param {Number} newIndex
  163.          */
  164.         "columnmoved",
  165.         /**
  166.          * @event configchange
  167.          * Fires when the configuration is changed
  168.          * @param {ColumnModel} this
  169.          */
  170.         "configchange"
  171.     );
  172.     Ext.grid.ColumnModel.superclass.constructor.call(this);
  173.     },
  174.     /**
  175.      * Returns the id of the column at the specified index.
  176.      * @param {Number} index The column index
  177.      * @return {String} the id
  178.      */
  179.     getColumnId : function(index){
  180.         return this.config[index].id;
  181.     },
  182.     getColumnAt : function(index){
  183.         return this.config[index];
  184.     },
  185.     /**
  186.      * <p>Reconfigures this column model according to the passed Array of column definition objects.
  187.      * For a description of the individual properties of a column definition object, see the
  188.      * <a href="#Ext.grid.ColumnModel-configs">Config Options</a>.</p>
  189.      * <p>Causes the {@link #configchange} event to be fired. A {@link Ext.grid.GridPanel GridPanel}
  190.      * using this ColumnModel will listen for this event and refresh its UI automatically.</p>
  191.      * @param {Array} config Array of Column definition objects.
  192.      * @param {Boolean} initial Specify <tt>true</tt> to bypass cleanup which deletes the <tt>totalWidth</tt>
  193.      * and destroys existing editors.
  194.      */
  195.     setConfig : function(config, initial){
  196.         var i, c, len;
  197.         if(!initial){ // cleanup
  198.             delete this.totalWidth;
  199.             for(i = 0, len = this.config.length; i < len; i++){
  200.                 c = this.config[i];
  201.                 if(c.editor){
  202.                     c.editor.destroy();
  203.                 }
  204.             }
  205.         }
  206.         // backward compatibility
  207.         this.defaults = Ext.apply({
  208.             width: this.defaultWidth,
  209.             sortable: this.defaultSortable
  210.         }, this.defaults);
  211.         this.config = config;
  212.         this.lookup = {};
  213.         for(i = 0, len = config.length; i < len; i++){
  214.             c = Ext.applyIf(config[i], this.defaults);
  215.             // if no id, create one using column's ordinal position
  216.             if(typeof c.id == 'undefined'){
  217.                 c.id = i;
  218.             }
  219.             if(!c.isColumn){
  220.                 var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
  221.                 c = new Cls(c);
  222.                 config[i] = c;
  223.             }
  224.             this.lookup[c.id] = c;
  225.         }
  226.         if(!initial){
  227.             this.fireEvent('configchange', this);
  228.         }
  229.     },
  230.     /**
  231.      * Returns the column for a specified id.
  232.      * @param {String} id The column id
  233.      * @return {Object} the column
  234.      */
  235.     getColumnById : function(id){
  236.         return this.lookup[id];
  237.     },
  238.     /**
  239.      * Returns the index for a specified column id.
  240.      * @param {String} id The column id
  241.      * @return {Number} the index, or -1 if not found
  242.      */
  243.     getIndexById : function(id){
  244.         for(var i = 0, len = this.config.length; i < len; i++){
  245.             if(this.config[i].id == id){
  246.                 return i;
  247.             }
  248.         }
  249.         return -1;
  250.     },
  251.     /**
  252.      * Moves a column from one position to another.
  253.      * @param {Number} oldIndex The index of the column to move.
  254.      * @param {Number} newIndex The position at which to reinsert the coolumn.
  255.      */
  256.     moveColumn : function(oldIndex, newIndex){
  257.         var c = this.config[oldIndex];
  258.         this.config.splice(oldIndex, 1);
  259.         this.config.splice(newIndex, 0, c);
  260.         this.dataMap = null;
  261.         this.fireEvent("columnmoved", this, oldIndex, newIndex);
  262.     },
  263.     /**
  264.      * Returns the number of columns.
  265.      * @param {Boolean} visibleOnly Optional. Pass as true to only include visible columns.
  266.      * @return {Number}
  267.      */
  268.     getColumnCount : function(visibleOnly){
  269.         if(visibleOnly === true){
  270.             var c = 0;
  271.             for(var i = 0, len = this.config.length; i < len; i++){
  272.                 if(!this.isHidden(i)){
  273.                     c++;
  274.                 }
  275.             }
  276.             return c;
  277.         }
  278.         return this.config.length;
  279.     },
  280.     /**
  281.      * Returns the column configs that return true by the passed function that is called
  282.      * with (columnConfig, index)
  283. <pre><code>
  284. // returns an array of column config objects for all hidden columns
  285. var columns = grid.getColumnModel().getColumnsBy(function(c){
  286.   return c.hidden;
  287. });
  288. </code></pre>
  289.      * @param {Function} fn A function which, when passed a {@link Ext.grid.Column Column} object, must
  290.      * return <code>true</code> if the column is to be included in the returned Array.
  291.      * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function
  292.      * is executed. Defaults to this ColumnModel.
  293.      * @return {Array} result
  294.      */
  295.     getColumnsBy : function(fn, scope){
  296.         var r = [];
  297.         for(var i = 0, len = this.config.length; i < len; i++){
  298.             var c = this.config[i];
  299.             if(fn.call(scope||this, c, i) === true){
  300.                 r[r.length] = c;
  301.             }
  302.         }
  303.         return r;
  304.     },
  305.     /**
  306.      * Returns true if the specified column is sortable.
  307.      * @param {Number} col The column index
  308.      * @return {Boolean}
  309.      */
  310.     isSortable : function(col){
  311.         return !!this.config[col].sortable;
  312.     },
  313.     /**
  314.      * Returns true if the specified column menu is disabled.
  315.      * @param {Number} col The column index
  316.      * @return {Boolean}
  317.      */
  318.     isMenuDisabled : function(col){
  319.         return !!this.config[col].menuDisabled;
  320.     },
  321.     /**
  322.      * Returns the rendering (formatting) function defined for the column.
  323.      * @param {Number} col The column index.
  324.      * @return {Function} The function used to render the cell. See {@link #setRenderer}.
  325.      */
  326.     getRenderer : function(col){
  327.         if(!this.config[col].renderer){
  328.             return Ext.grid.ColumnModel.defaultRenderer;
  329.         }
  330.         return this.config[col].renderer;
  331.     },
  332.     
  333.     getRendererScope : function(col){
  334.         return this.config[col].scope;
  335.     },
  336.     /**
  337.      * Sets the rendering (formatting) function for a column.  See {@link Ext.util.Format} for some
  338.      * default formatting functions.
  339.      * @param {Number} col The column index
  340.      * @param {Function} fn The function to use to process the cell's raw data
  341.      * to return HTML markup for the grid view. The render function is called with
  342.      * the following parameters:<ul>
  343.      * <li><b>value</b> : Object<p class="sub-desc">The data value for the cell.</p></li>
  344.      * <li><b>metadata</b> : Object<p class="sub-desc">An object in which you may set the following attributes:<ul>
  345.      * <li><b>css</b> : String<p class="sub-desc">A CSS class name to add to the cell's TD element.</p></li>
  346.      * <li><b>attr</b> : String<p class="sub-desc">An HTML attribute definition string to apply to the data container element <i>within</i> the table cell
  347.      * (e.g. 'style="color:red;"').</p></li></ul></p></li>
  348.      * <li><b>record</b> : Ext.data.record<p class="sub-desc">The {@link Ext.data.Record} from which the data was extracted.</p></li>
  349.      * <li><b>rowIndex</b> : Number<p class="sub-desc">Row index</p></li>
  350.      * <li><b>colIndex</b> : Number<p class="sub-desc">Column index</p></li>
  351.      * <li><b>store</b> : Ext.data.Store<p class="sub-desc">The {@link Ext.data.Store} object from which the Record was extracted.</p></li></ul>
  352.      */
  353.     setRenderer : function(col, fn){
  354.         this.config[col].renderer = fn;
  355.     },
  356.     /**
  357.      * Returns the width for the specified column.
  358.      * @param {Number} col The column index
  359.      * @return {Number}
  360.      */
  361.     getColumnWidth : function(col){
  362.         return this.config[col].width;
  363.     },
  364.     /**
  365.      * Sets the width for a column.
  366.      * @param {Number} col The column index
  367.      * @param {Number} width The new width
  368.      * @param {Boolean} suppressEvent True to suppress firing the <code>{@link #widthchange}</code>
  369.      * event. Defaults to false.
  370.      */
  371.     setColumnWidth : function(col, width, suppressEvent){
  372.         this.config[col].width = width;
  373.         this.totalWidth = null;
  374.         if(!suppressEvent){
  375.              this.fireEvent("widthchange", this, col, width);
  376.         }
  377.     },
  378.     /**
  379.      * Returns the total width of all columns.
  380.      * @param {Boolean} includeHidden True to include hidden column widths
  381.      * @return {Number}
  382.      */
  383.     getTotalWidth : function(includeHidden){
  384.         if(!this.totalWidth){
  385.             this.totalWidth = 0;
  386.             for(var i = 0, len = this.config.length; i < len; i++){
  387.                 if(includeHidden || !this.isHidden(i)){
  388.                     this.totalWidth += this.getColumnWidth(i);
  389.                 }
  390.             }
  391.         }
  392.         return this.totalWidth;
  393.     },
  394.     /**
  395.      * Returns the header for the specified column.
  396.      * @param {Number} col The column index
  397.      * @return {String}
  398.      */
  399.     getColumnHeader : function(col){
  400.         return this.config[col].header;
  401.     },
  402.     /**
  403.      * Sets the header for a column.
  404.      * @param {Number} col The column index
  405.      * @param {String} header The new header
  406.      */
  407.     setColumnHeader : function(col, header){
  408.         this.config[col].header = header;
  409.         this.fireEvent("headerchange", this, col, header);
  410.     },
  411.     /**
  412.      * Returns the tooltip for the specified column.
  413.      * @param {Number} col The column index
  414.      * @return {String}
  415.      */
  416.     getColumnTooltip : function(col){
  417.             return this.config[col].tooltip;
  418.     },
  419.     /**
  420.      * Sets the tooltip for a column.
  421.      * @param {Number} col The column index
  422.      * @param {String} tooltip The new tooltip
  423.      */
  424.     setColumnTooltip : function(col, tooltip){
  425.             this.config[col].tooltip = tooltip;
  426.     },
  427.     /**
  428.      * Returns the dataIndex for the specified column.
  429. <pre><code>
  430. // Get field name for the column
  431. var fieldName = grid.getColumnModel().getDataIndex(columnIndex);
  432. </code></pre>
  433.      * @param {Number} col The column index
  434.      * @return {String} The column's dataIndex
  435.      */
  436.     getDataIndex : function(col){
  437.         return this.config[col].dataIndex;
  438.     },
  439.     /**
  440.      * Sets the dataIndex for a column.
  441.      * @param {Number} col The column index
  442.      * @param {String} dataIndex The new dataIndex
  443.      */
  444.     setDataIndex : function(col, dataIndex){
  445.         this.config[col].dataIndex = dataIndex;
  446.     },
  447.     /**
  448.      * Finds the index of the first matching column for the given dataIndex.
  449.      * @param {String} col The dataIndex to find
  450.      * @return {Number} The column index, or -1 if no match was found
  451.      */
  452.     findColumnIndex : function(dataIndex){
  453.         var c = this.config;
  454.         for(var i = 0, len = c.length; i < len; i++){
  455.             if(c[i].dataIndex == dataIndex){
  456.                 return i;
  457.             }
  458.         }
  459.         return -1;
  460.     },
  461.     /**
  462.      * Returns true if the cell is editable.
  463. <pre><code>
  464. var store = new Ext.data.Store({...});
  465. var colModel = new Ext.grid.ColumnModel({
  466.   columns: [...],
  467.   isCellEditable: function(col, row) {
  468.     var record = store.getAt(row);
  469.     if (record.get('readonly')) { // replace with your condition
  470.       return false;
  471.     }
  472.     return Ext.grid.ColumnModel.prototype.isCellEditable.call(this, col, row);
  473.   }
  474. });
  475. var grid = new Ext.grid.GridPanel({
  476.   store: store,
  477.   colModel: colModel,
  478.   ...
  479. });
  480. </code></pre>
  481.      * @param {Number} colIndex The column index
  482.      * @param {Number} rowIndex The row index
  483.      * @return {Boolean}
  484.      */
  485.     isCellEditable : function(colIndex, rowIndex){
  486.         return (this.config[colIndex].editable || (typeof this.config[colIndex].editable == "undefined" && this.config[colIndex].editor)) ? true : false;
  487.     },
  488.     /**
  489.      * Returns the editor defined for the cell/column.
  490.      * @param {Number} colIndex The column index
  491.      * @param {Number} rowIndex The row index
  492.      * @return {Ext.Editor} The {@link Ext.Editor Editor} that was created to wrap
  493.      * the {@link Ext.form.Field Field} used to edit the cell.
  494.      */
  495.     getCellEditor : function(colIndex, rowIndex){
  496.         return this.config[colIndex].getCellEditor(rowIndex);
  497.     },
  498.     /**
  499.      * Sets if a column is editable.
  500.      * @param {Number} col The column index
  501.      * @param {Boolean} editable True if the column is editable
  502.      */
  503.     setEditable : function(col, editable){
  504.         this.config[col].editable = editable;
  505.     },
  506.     /**
  507.      * Returns <tt>true</tt> if the column is <code>{@link Ext.grid.Column#hidden hidden}</code>,
  508.      * <tt>false</tt> otherwise.
  509.      * @param {Number} colIndex The column index
  510.      * @return {Boolean}
  511.      */
  512.     isHidden : function(colIndex){
  513.         return !!this.config[colIndex].hidden; // ensure returns boolean
  514.     },
  515.     /**
  516.      * Returns <tt>true</tt> if the column is <code>{@link Ext.grid.Column#fixed fixed}</code>,
  517.      * <tt>false</tt> otherwise.
  518.      * @param {Number} colIndex The column index
  519.      * @return {Boolean}
  520.      */
  521.     isFixed : function(colIndex){
  522.         return !!this.config[colIndex].fixed;
  523.     },
  524.     /**
  525.      * Returns true if the column can be resized
  526.      * @return {Boolean}
  527.      */
  528.     isResizable : function(colIndex){
  529.         return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
  530.     },
  531.     /**
  532.      * Sets if a column is hidden.
  533. <pre><code>
  534. myGrid.getColumnModel().setHidden(0, true); // hide column 0 (0 = the first column).
  535. </code></pre>
  536.      * @param {Number} colIndex The column index
  537.      * @param {Boolean} hidden True if the column is hidden
  538.      */
  539.     setHidden : function(colIndex, hidden){
  540.         var c = this.config[colIndex];
  541.         if(c.hidden !== hidden){
  542.             c.hidden = hidden;
  543.             this.totalWidth = null;
  544.             this.fireEvent("hiddenchange", this, colIndex, hidden);
  545.         }
  546.     },
  547.     /**
  548.      * Sets the editor for a column and destroys the prior editor.
  549.      * @param {Number} col The column index
  550.      * @param {Object} editor The editor object
  551.      */
  552.     setEditor : function(col, editor){
  553.         Ext.destroy(this.config[col].editor);
  554.         this.config[col].editor = editor;
  555.     },
  556.     /**
  557.      * Destroys this column model by purging any event listeners, and removing any editors.
  558.      */
  559.     destroy : function(){
  560.         for(var i = 0, c = this.config, len = c.length; i < len; i++){
  561.             Ext.destroy(c[i].editor);
  562.         }
  563.         this.purgeListeners();
  564.     }
  565. });
  566. // private
  567. Ext.grid.ColumnModel.defaultRenderer = function(value){
  568.     if(typeof value == "string" && value.length < 1){
  569.         return "&#160;";
  570.     }
  571.     return value;
  572. };