ColumnModel.js
上传用户:shuoshiled
上传日期:2018-01-28
资源大小:10124k
文件大小:21k
源码类别:

中间件编程

开发平台:

JavaScript

  1. /*!
  2.  * Ext JS Library 3.0.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).  Field's 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 = function(config){
  92.     /**
  93.      * An Array of {@link Ext.grid.Column Column definition} objects representing the configuration
  94.      * of this ColumnModel.  See {@link Ext.grid.Column} for the configuration properties that may
  95.      * be specified.
  96.      * @property config
  97.      * @type Array
  98.      */
  99.     if(config.columns){
  100.         Ext.apply(this, config);
  101.         this.setConfig(config.columns, true);
  102.     }else{
  103.         this.setConfig(config, true);
  104.     }
  105.     this.addEvents(
  106.         /**
  107.          * @event widthchange
  108.          * Fires when the width of a column is programmaticially changed using
  109.          * <code>{@link #setColumnWidth}</code>.
  110.          * Note internal resizing suppresses the event from firing. See also
  111.          * {@link Ext.grid.GridPanel}.<code>{@link #columnresize}</code>.
  112.          * @param {ColumnModel} this
  113.          * @param {Number} columnIndex The column index
  114.          * @param {Number} newWidth The new width
  115.          */
  116.         "widthchange",
  117.         /**
  118.          * @event headerchange
  119.          * Fires when the text of a header changes.
  120.          * @param {ColumnModel} this
  121.          * @param {Number} columnIndex The column index
  122.          * @param {String} newText The new header text
  123.          */
  124.         "headerchange",
  125.         /**
  126.          * @event hiddenchange
  127.          * Fires when a column is hidden or "unhidden".
  128.          * @param {ColumnModel} this
  129.          * @param {Number} columnIndex The column index
  130.          * @param {Boolean} hidden true if hidden, false otherwise
  131.          */
  132.         "hiddenchange",
  133.         /**
  134.          * @event columnmoved
  135.          * Fires when a column is moved.
  136.          * @param {ColumnModel} this
  137.          * @param {Number} oldIndex
  138.          * @param {Number} newIndex
  139.          */
  140.         "columnmoved",
  141.         /**
  142.          * @event configchange
  143.          * Fires when the configuration is changed
  144.          * @param {ColumnModel} this
  145.          */
  146.         "configchange"
  147.     );
  148.     Ext.grid.ColumnModel.superclass.constructor.call(this);
  149. };
  150. Ext.extend(Ext.grid.ColumnModel, Ext.util.Observable, {
  151.     /**
  152.      * @cfg {Number} defaultWidth (optional) The width of columns which have no <tt>{@link #width}</tt>
  153.      * specified (defaults to <tt>100</tt>).  This property shall preferably be configured through the
  154.      * <tt><b>{@link #defaults}</b></tt> config property.
  155.      */
  156.     defaultWidth: 100,
  157.     /**
  158.      * @cfg {Boolean} defaultSortable (optional) Default sortable of columns which have no
  159.      * sortable specified (defaults to <tt>false</tt>).  This property shall preferably be configured
  160.      * through the <tt><b>{@link #defaults}</b></tt> config property.
  161.      */
  162.     defaultSortable: false,
  163.     /**
  164.      * @cfg {Array} columns An Array of object literals.  The config options defined by
  165.      * <b>{@link Ext.grid.Column}</b> are the options which may appear in the object literal for each
  166.      * individual column definition.
  167.      */
  168.     /**
  169.      * @cfg {Object} defaults Object literal which will be used to apply {@link Ext.grid.Column}
  170.      * configuration options to all <tt><b>{@link #columns}</b></tt>.  Configuration options specified with
  171.      * individual {@link Ext.grid.Column column} configs will supersede these <tt><b>{@link #defaults}</b></tt>.
  172.      */
  173.     /**
  174.      * Returns the id of the column at the specified index.
  175.      * @param {Number} index The column index
  176.      * @return {String} the id
  177.      */
  178.     getColumnId : function(index){
  179.         return this.config[index].id;
  180.     },
  181.     getColumnAt : function(index){
  182.         return this.config[index];
  183.     },
  184.     /**
  185.      * <p>Reconfigures this column model according to the passed Array of column definition objects.
  186.      * For a description of the individual properties of a column definition object, see the
  187.      * <a href="#Ext.grid.ColumnModel-configs">Config Options</a>.</p>
  188.      * <p>Causes the {@link #configchange} event to be fired. A {@link Ext.grid.GridPanel GridPanel}
  189.      * using this ColumnModel will listen for this event and refresh its UI automatically.</p>
  190.      * @param {Array} config Array of Column definition objects.
  191.      * @param {Boolean} initial Specify <tt>true</tt> to bypass cleanup which deletes the <tt>totalWidth</tt>
  192.      * and destroys existing editors.
  193.      */
  194.     setConfig : function(config, initial){
  195.         var i, c, len;
  196.         if(!initial){ // cleanup
  197.             delete this.totalWidth;
  198.             for(i = 0, len = this.config.length; i < len; i++){
  199.                 c = this.config[i];
  200.                 if(c.editor){
  201.                     c.editor.destroy();
  202.                 }
  203.             }
  204.         }
  205.         // backward compatibility
  206.         this.defaults = Ext.apply({
  207.             width: this.defaultWidth,
  208.             sortable: this.defaultSortable
  209.         }, this.defaults);
  210.         this.config = config;
  211.         this.lookup = {};
  212.         // if no id, create one
  213.         for(i = 0, len = config.length; i < len; i++){
  214.             c = Ext.applyIf(config[i], this.defaults);
  215.             if(!c.isColumn){
  216.                 var cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
  217.                 c = new cls(c);
  218.                 config[i] = c;
  219.             }
  220.             this.lookup[c.id] = c;
  221.         }
  222.         if(!initial){
  223.             this.fireEvent('configchange', this);
  224.         }
  225.     },
  226.     /**
  227.      * Returns the column for a specified id.
  228.      * @param {String} id The column id
  229.      * @return {Object} the column
  230.      */
  231.     getColumnById : function(id){
  232.         return this.lookup[id];
  233.     },
  234.     /**
  235.      * Returns the index for a specified column id.
  236.      * @param {String} id The column id
  237.      * @return {Number} the index, or -1 if not found
  238.      */
  239.     getIndexById : function(id){
  240.         for(var i = 0, len = this.config.length; i < len; i++){
  241.             if(this.config[i].id == id){
  242.                 return i;
  243.             }
  244.         }
  245.         return -1;
  246.     },
  247.     /**
  248.      * Moves a column from one position to another.
  249.      * @param {Number} oldIndex The index of the column to move.
  250.      * @param {Number} newIndex The position at which to reinsert the coolumn.
  251.      */
  252.     moveColumn : function(oldIndex, newIndex){
  253.         var c = this.config[oldIndex];
  254.         this.config.splice(oldIndex, 1);
  255.         this.config.splice(newIndex, 0, c);
  256.         this.dataMap = null;
  257.         this.fireEvent("columnmoved", this, oldIndex, newIndex);
  258.     },
  259.     /**
  260.      * Returns the number of columns.
  261.      * @param {Boolean} visibleOnly Optional. Pass as true to only include visible columns.
  262.      * @return {Number}
  263.      */
  264.     getColumnCount : function(visibleOnly){
  265.         if(visibleOnly === true){
  266.             var c = 0;
  267.             for(var i = 0, len = this.config.length; i < len; i++){
  268.                 if(!this.isHidden(i)){
  269.                     c++;
  270.                 }
  271.             }
  272.             return c;
  273.         }
  274.         return this.config.length;
  275.     },
  276.     /**
  277.      * Returns the column configs that return true by the passed function that is called
  278.      * with (columnConfig, index)
  279. <pre><code>
  280. // returns an array of column config objects for all hidden columns
  281. var columns = grid.getColumnModel().getColumnsBy(function(c){
  282.   return c.hidden;
  283. });
  284. </code></pre>
  285.      * @param {Function} fn
  286.      * @param {Object} scope (optional)
  287.      * @return {Array} result
  288.      */
  289.     getColumnsBy : function(fn, scope){
  290.         var r = [];
  291.         for(var i = 0, len = this.config.length; i < len; i++){
  292.             var c = this.config[i];
  293.             if(fn.call(scope||this, c, i) === true){
  294.                 r[r.length] = c;
  295.             }
  296.         }
  297.         return r;
  298.     },
  299.     /**
  300.      * Returns true if the specified column is sortable.
  301.      * @param {Number} col The column index
  302.      * @return {Boolean}
  303.      */
  304.     isSortable : function(col){
  305.         return this.config[col].sortable;
  306.     },
  307.     /**
  308.      * Returns true if the specified column menu is disabled.
  309.      * @param {Number} col The column index
  310.      * @return {Boolean}
  311.      */
  312.     isMenuDisabled : function(col){
  313.         return !!this.config[col].menuDisabled;
  314.     },
  315.     /**
  316.      * Returns the rendering (formatting) function defined for the column.
  317.      * @param {Number} col The column index.
  318.      * @return {Function} The function used to render the cell. See {@link #setRenderer}.
  319.      */
  320.     getRenderer : function(col){
  321.         if(!this.config[col].renderer){
  322.             return Ext.grid.ColumnModel.defaultRenderer;
  323.         }
  324.         return this.config[col].renderer;
  325.     },
  326.     /**
  327.      * Sets the rendering (formatting) function for a column.  See {@link Ext.util.Format} for some
  328.      * default formatting functions.
  329.      * @param {Number} col The column index
  330.      * @param {Function} fn The function to use to process the cell's raw data
  331.      * to return HTML markup for the grid view. The render function is called with
  332.      * the following parameters:<ul>
  333.      * <li><b>value</b> : Object<p class="sub-desc">The data value for the cell.</p></li>
  334.      * <li><b>metadata</b> : Object<p class="sub-desc">An object in which you may set the following attributes:<ul>
  335.      * <li><b>css</b> : String<p class="sub-desc">A CSS class name to add to the cell's TD element.</p></li>
  336.      * <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
  337.      * (e.g. 'style="color:red;"').</p></li></ul></p></li>
  338.      * <li><b>record</b> : Ext.data.record<p class="sub-desc">The {@link Ext.data.Record} from which the data was extracted.</p></li>
  339.      * <li><b>rowIndex</b> : Number<p class="sub-desc">Row index</p></li>
  340.      * <li><b>colIndex</b> : Number<p class="sub-desc">Column index</p></li>
  341.      * <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>
  342.      */
  343.     setRenderer : function(col, fn){
  344.         this.config[col].renderer = fn;
  345.     },
  346.     /**
  347.      * Returns the width for the specified column.
  348.      * @param {Number} col The column index
  349.      * @return {Number}
  350.      */
  351.     getColumnWidth : function(col){
  352.         return this.config[col].width;
  353.     },
  354.     /**
  355.      * Sets the width for a column.
  356.      * @param {Number} col The column index
  357.      * @param {Number} width The new width
  358.      * @param {Boolean} suppressEvent True to suppress firing the <code>{@link #widthchange}</code>
  359.      * event. Defaults to false.
  360.      */
  361.     setColumnWidth : function(col, width, suppressEvent){
  362.         this.config[col].width = width;
  363.         this.totalWidth = null;
  364.         if(!suppressEvent){
  365.              this.fireEvent("widthchange", this, col, width);
  366.         }
  367.     },
  368.     /**
  369.      * Returns the total width of all columns.
  370.      * @param {Boolean} includeHidden True to include hidden column widths
  371.      * @return {Number}
  372.      */
  373.     getTotalWidth : function(includeHidden){
  374.         if(!this.totalWidth){
  375.             this.totalWidth = 0;
  376.             for(var i = 0, len = this.config.length; i < len; i++){
  377.                 if(includeHidden || !this.isHidden(i)){
  378.                     this.totalWidth += this.getColumnWidth(i);
  379.                 }
  380.             }
  381.         }
  382.         return this.totalWidth;
  383.     },
  384.     /**
  385.      * Returns the header for the specified column.
  386.      * @param {Number} col The column index
  387.      * @return {String}
  388.      */
  389.     getColumnHeader : function(col){
  390.         return this.config[col].header;
  391.     },
  392.     /**
  393.      * Sets the header for a column.
  394.      * @param {Number} col The column index
  395.      * @param {String} header The new header
  396.      */
  397.     setColumnHeader : function(col, header){
  398.         this.config[col].header = header;
  399.         this.fireEvent("headerchange", this, col, header);
  400.     },
  401.     /**
  402.      * Returns the tooltip for the specified column.
  403.      * @param {Number} col The column index
  404.      * @return {String}
  405.      */
  406.     getColumnTooltip : function(col){
  407.             return this.config[col].tooltip;
  408.     },
  409.     /**
  410.      * Sets the tooltip for a column.
  411.      * @param {Number} col The column index
  412.      * @param {String} tooltip The new tooltip
  413.      */
  414.     setColumnTooltip : function(col, tooltip){
  415.             this.config[col].tooltip = tooltip;
  416.     },
  417.     /**
  418.      * Returns the dataIndex for the specified column.
  419. <pre><code>
  420. // Get field name for the column
  421. var fieldName = grid.getColumnModel().getDataIndex(columnIndex);
  422. </code></pre>
  423.      * @param {Number} col The column index
  424.      * @return {String} The column's dataIndex
  425.      */
  426.     getDataIndex : function(col){
  427.         return this.config[col].dataIndex;
  428.     },
  429.     /**
  430.      * Sets the dataIndex for a column.
  431.      * @param {Number} col The column index
  432.      * @param {String} dataIndex The new dataIndex
  433.      */
  434.     setDataIndex : function(col, dataIndex){
  435.         this.config[col].dataIndex = dataIndex;
  436.     },
  437.     /**
  438.      * Finds the index of the first matching column for the given dataIndex.
  439.      * @param {String} col The dataIndex to find
  440.      * @return {Number} The column index, or -1 if no match was found
  441.      */
  442.     findColumnIndex : function(dataIndex){
  443.         var c = this.config;
  444.         for(var i = 0, len = c.length; i < len; i++){
  445.             if(c[i].dataIndex == dataIndex){
  446.                 return i;
  447.             }
  448.         }
  449.         return -1;
  450.     },
  451.     /**
  452.      * Returns true if the cell is editable.
  453. <pre><code>
  454. var store = new Ext.data.Store({...});
  455. var colModel = new Ext.grid.ColumnModel({
  456.   columns: [...],
  457.   isCellEditable: function(col, row) {
  458.     var record = store.getAt(row);
  459.     if (record.get('readonly')) { // replace with your condition
  460.       return false;
  461.     }
  462.     return Ext.grid.ColumnModel.prototype.isCellEditable.call(this, col, row);
  463.   }
  464. });
  465. var grid = new Ext.grid.GridPanel({
  466.   store: store,
  467.   colModel: colModel,
  468.   ...
  469. });
  470. </code></pre>
  471.      * @param {Number} colIndex The column index
  472.      * @param {Number} rowIndex The row index
  473.      * @return {Boolean}
  474.      */
  475.     isCellEditable : function(colIndex, rowIndex){
  476.         return (this.config[colIndex].editable || (typeof this.config[colIndex].editable == "undefined" && this.config[colIndex].editor)) ? true : false;
  477.     },
  478.     /**
  479.      * Returns the editor defined for the cell/column.
  480.      * @param {Number} colIndex The column index
  481.      * @param {Number} rowIndex The row index
  482.      * @return {Ext.Editor} The {@link Ext.Editor Editor} that was created to wrap
  483.      * the {@link Ext.form.Field Field} used to edit the cell.
  484.      */
  485.     getCellEditor : function(colIndex, rowIndex){
  486.         return this.config[colIndex].getCellEditor(rowIndex);
  487.     },
  488.     /**
  489.      * Sets if a column is editable.
  490.      * @param {Number} col The column index
  491.      * @param {Boolean} editable True if the column is editable
  492.      */
  493.     setEditable : function(col, editable){
  494.         this.config[col].editable = editable;
  495.     },
  496.     /**
  497.      * Returns true if the column is hidden.
  498.      * @param {Number} colIndex The column index
  499.      * @return {Boolean}
  500.      */
  501.     isHidden : function(colIndex){
  502.         return this.config[colIndex].hidden;
  503.     },
  504.     /**
  505.      * Returns true if the column width cannot be changed
  506.      */
  507.     isFixed : function(colIndex){
  508.         return this.config[colIndex].fixed;
  509.     },
  510.     /**
  511.      * Returns true if the column can be resized
  512.      * @return {Boolean}
  513.      */
  514.     isResizable : function(colIndex){
  515.         return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
  516.     },
  517.     /**
  518.      * Sets if a column is hidden.
  519. <pre><code>
  520. myGrid.getColumnModel().setHidden(0, true); // hide column 0 (0 = the first column).
  521. </code></pre>
  522.      * @param {Number} colIndex The column index
  523.      * @param {Boolean} hidden True if the column is hidden
  524.      */
  525.     setHidden : function(colIndex, hidden){
  526.         var c = this.config[colIndex];
  527.         if(c.hidden !== hidden){
  528.             c.hidden = hidden;
  529.             this.totalWidth = null;
  530.             this.fireEvent("hiddenchange", this, colIndex, hidden);
  531.         }
  532.     },
  533.     /**
  534.      * Sets the editor for a column and destroys the prior editor.
  535.      * @param {Number} col The column index
  536.      * @param {Object} editor The editor object
  537.      */
  538.     setEditor : function(col, editor){
  539.         Ext.destroy(this.config[col].editor);
  540.         this.config[col].editor = editor;
  541.     },
  542.     /**
  543.      * Destroys this column model by purging any event listeners, and removing any editors.
  544.      */
  545.     destroy : function(){
  546.         for(var i = 0, c = this.config, len = c.length; i < len; i++){
  547.             Ext.destroy(c[i].editor);
  548.         }
  549.         this.purgeListeners();
  550.     }
  551. });
  552. // private
  553. Ext.grid.ColumnModel.defaultRenderer = function(value){
  554.     if(typeof value == "string" && value.length < 1){
  555.         return "&#160;";
  556.     }
  557.     return value;
  558. };