X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/f5240829880f87e0cf581c6a296e436fdef0ef80..f562e4c6e5fac7bcb445985b99acbea4d706e6f0:/docs/source/Column.html diff --git a/docs/source/Column.html b/docs/source/Column.html index 9392c70b..909501c6 100644 --- a/docs/source/Column.html +++ b/docs/source/Column.html @@ -1,684 +1,861 @@ + - + The source code - - + + + + - -
/*!
- * Ext JS Library 3.3.0
- * Copyright(c) 2006-2010 Ext JS, Inc.
- * licensing@extjs.com
- * http://www.extjs.com/license
- */
-
/** - * @class Ext.grid.Column - *

This class encapsulates column configuration data to be used in the initialization of a - * {@link Ext.grid.ColumnModel ColumnModel}.

- *

While subclasses are provided to render data in different ways, this class renders a passed - * data field unchanged and is usually used for textual columns.

+ +
/**
+ * This class specifies the definition for a column inside a {@link Ext.grid.Panel}. It encompasses
+ * both the grid header configuration as well as displaying data within the grid itself. If the
+ * {@link #columns} configuration is specified, this column will become a column group and can
+ * contain other columns inside. In general, this class will not be created directly, rather
+ * an array of column configurations will be passed to the grid:
+ *
+ *     @example
+ *     Ext.create('Ext.data.Store', {
+ *         storeId:'employeeStore',
+ *         fields:['firstname', 'lastname', 'senority', 'dep', 'hired'],
+ *         data:[
+ *             {firstname:"Michael", lastname:"Scott", senority:7, dep:"Manangement", hired:"01/10/2004"},
+ *             {firstname:"Dwight", lastname:"Schrute", senority:2, dep:"Sales", hired:"04/01/2004"},
+ *             {firstname:"Jim", lastname:"Halpert", senority:3, dep:"Sales", hired:"02/22/2006"},
+ *             {firstname:"Kevin", lastname:"Malone", senority:4, dep:"Accounting", hired:"06/10/2007"},
+ *             {firstname:"Angela", lastname:"Martin", senority:5, dep:"Accounting", hired:"10/21/2008"}
+ *         ]
+ *     });
+ *
+ *     Ext.create('Ext.grid.Panel', {
+ *         title: 'Column Demo',
+ *         store: Ext.data.StoreManager.lookup('employeeStore'),
+ *         columns: [
+ *             {text: 'First Name',  dataIndex:'firstname'},
+ *             {text: 'Last Name',  dataIndex:'lastname'},
+ *             {text: 'Hired Month',  dataIndex:'hired', xtype:'datecolumn', format:'M'},
+ *             {text: 'Department (Yrs)', xtype:'templatecolumn', tpl:'{dep} ({senority})'}
+ *         ],
+ *         width: 400,
+ *         renderTo: Ext.getBody()
+ *     });
+ *
+ * # Convenience Subclasses
+ *
+ * There are several column subclasses that provide default rendering for various data types
+ *
+ *  - {@link Ext.grid.column.Action}: Renders icons that can respond to click events inline
+ *  - {@link Ext.grid.column.Boolean}: Renders for boolean values
+ *  - {@link Ext.grid.column.Date}: Renders for date values
+ *  - {@link Ext.grid.column.Number}: Renders for numeric values
+ *  - {@link Ext.grid.column.Template}: Renders a value using an {@link Ext.XTemplate} using the record data
+ *
+ * # Setting Sizes
+ *
+ * The columns are laid out by a {@link Ext.layout.container.HBox} layout, so a column can either
+ * be given an explicit width value or a flex configuration. If no width is specified the grid will
+ * automatically the size the column to 100px. For column groups, the size is calculated by measuring
+ * the width of the child columns, so a width option should not be specified in that case.
+ *
+ * # Header Options
+ *
+ *  - {@link #text}: Sets the header text for the column
+ *  - {@link #sortable}: Specifies whether the column can be sorted by clicking the header or using the column menu
+ *  - {@link #hideable}: Specifies whether the column can be hidden using the column menu
+ *  - {@link #menuDisabled}: Disables the column header menu
+ *  - {@link #draggable}: Specifies whether the column header can be reordered by dragging
+ *  - {@link #groupable}: Specifies whether the grid can be grouped by the column dataIndex. See also {@link Ext.grid.feature.Grouping}
+ *
+ * # Data Options
+ *
+ *  - {@link #dataIndex}: The dataIndex is the field in the underlying {@link Ext.data.Store} to use as the value for the column.
+ *  - {@link #renderer}: Allows the underlying store value to be transformed before being displayed in the grid
  */
-Ext.grid.Column = Ext.extend(Ext.util.Observable, {
-    
/** - * @cfg {Boolean} editable Optional. Defaults to true, enabling the configured - * {@link #editor}. Set to false to initially disable editing on this column. - * The initial configuration may be dynamically altered using - * {@link Ext.grid.ColumnModel}.{@link Ext.grid.ColumnModel#setEditable setEditable()}. - */ -
/** - * @cfg {String} id Optional. A name which identifies this column (defaults to the column's initial - * ordinal position.) The id is used to create a CSS class name which is applied to all - * table cells (including headers) in that column (in this context the id does not need to be - * unique). The class name takes the form of
x-grid3-td-id
- * Header cells will also receive this class name, but will also have the class
x-grid3-hd
- * So, to target header cells, use CSS selectors such as:
.x-grid3-hd-row .x-grid3-td-id
- * The {@link Ext.grid.GridPanel#autoExpandColumn} grid config option references the column via this - * unique identifier. - */ -
/** - * @cfg {String} header Optional. The header text to be used as innerHTML - * (html tags are accepted) to display in the Grid view. Note: to - * have a clickable header with no text displayed use ' '. - */ -
/** - * @cfg {Boolean} groupable Optional. If the grid is being rendered by an {@link Ext.grid.GroupingView}, this option - * may be used to disable the header menu item to group by the column selected. Defaults to true, - * which enables the header menu group option. Set to false to disable (but still show) the - * group option in the header menu for the column. See also {@link #groupName}. - */ -
/** - * @cfg {String} groupName Optional. If the grid is being rendered by an {@link Ext.grid.GroupingView}, this option - * may be used to specify the text with which to prefix the group field value in the group header line. - * See also {@link #groupRenderer} and - * {@link Ext.grid.GroupingView}.{@link Ext.grid.GroupingView#showGroupName showGroupName}. - */ -
/** - * @cfg {Function} groupRenderer

Optional. If the grid is being rendered by an {@link Ext.grid.GroupingView}, this option - * may be used to specify the function used to format the grouping field value for display in the group - * {@link #groupName header}. If a groupRenderer is not specified, the configured - * {@link #renderer} will be called; if a {@link #renderer} is also not specified - * the new value of the group field will be used.

- *

The called function (either the groupRenderer or {@link #renderer}) will be - * passed the following parameters: - *

    - *
  • v : Object

    The new value of the group field.

  • - *
  • unused : undefined

    Unused parameter.

  • - *
  • r : Ext.data.Record

    The Record providing the data - * for the row which caused group change.

  • - *
  • rowIndex : Number

    The row index of the Record which caused group change.

  • - *
  • colIndex : Number

    The column index of the group field.

  • - *
  • ds : Ext.data.Store

    The Store which is providing the data Model.

  • - *

- *

The function should return a string value.

- */ -
/** - * @cfg {String} emptyGroupText Optional. If the grid is being rendered by an {@link Ext.grid.GroupingView}, this option - * may be used to specify the text to display when there is an empty group value. Defaults to the - * {@link Ext.grid.GroupingView}.{@link Ext.grid.GroupingView#emptyGroupText emptyGroupText}. - */ -
/** - * @cfg {String} dataIndex

Required. The name of the field in the - * grid's {@link Ext.data.Store}'s {@link Ext.data.Record} definition from - * which to draw the column's value.

+Ext.define('Ext.grid.column.Column', { + extend: 'Ext.grid.header.Container', + alias: 'widget.gridcolumn', + requires: ['Ext.util.KeyNav'], + alternateClassName: 'Ext.grid.Column', + + baseCls: Ext.baseCSSPrefix + 'column-header ' + Ext.baseCSSPrefix + 'unselectable', + + // Not the standard, automatically applied overCls because we must filter out overs of child headers. + hoverCls: Ext.baseCSSPrefix + 'column-header-over', + + handleWidth: 5, + + sortState: null, + + possibleSortStates: ['ASC', 'DESC'], + + renderTpl: + '<div id="{id}-titleContainer" class="' + Ext.baseCSSPrefix + 'column-header-inner">' + + '<span id="{id}-textEl" class="' + Ext.baseCSSPrefix + 'column-header-text">' + + '{text}' + + '</span>' + + '<tpl if="!values.menuDisabled">'+ + '<div id="{id}-triggerEl" class="' + Ext.baseCSSPrefix + 'column-header-trigger"></div>'+ + '</tpl>' + + '</div>', + + /** + * @cfg {Object[]} columns + * An optional array of sub-column definitions. This column becomes a group, and houses the columns defined in the + * `columns` config. + * + * Group columns may not be sortable. But they may be hideable and moveable. And you may move headers into and out + * of a group. Note that if all sub columns are dragged out of a group, the group is destroyed. */ -
/** - * @cfg {Number} width - * Optional. The initial width in pixels of the column. - * The width of each column can also be affected if any of the following are configured: - *
    - *
  • {@link Ext.grid.GridPanel}.{@link Ext.grid.GridPanel#autoExpandColumn autoExpandColumn}
  • - *
  • {@link Ext.grid.GridView}.{@link Ext.grid.GridView#forceFit forceFit} - *
    - *

    By specifying forceFit:true, {@link #fixed non-fixed width} columns will be - * re-proportioned (based on the relative initial widths) to fill the width of the grid so - * that no horizontal scrollbar is shown.

    - *
  • - *
  • {@link Ext.grid.GridView}.{@link Ext.grid.GridView#autoFill autoFill}
  • - *
  • {@link Ext.grid.GridPanel}.{@link Ext.grid.GridPanel#minColumnWidth minColumnWidth}
  • - *

    Note: when the width of each column is determined, a space on the right side - * is reserved for the vertical scrollbar. The - * {@link Ext.grid.GridView}.{@link Ext.grid.GridView#scrollOffset scrollOffset} - * can be modified to reduce or eliminate the reserved offset.

    + + /** + * @cfg {String} dataIndex + * The name of the field in the grid's {@link Ext.data.Store}'s {@link Ext.data.Model} definition from + * which to draw the column's value. **Required.** */ -
    /** - * @cfg {Boolean} sortable Optional. true if sorting is to be allowed on this column. - * Defaults to the value of the {@link Ext.grid.ColumnModel#defaultSortable} property. - * Whether local/remote sorting is used is specified in {@link Ext.data.Store#remoteSort}. + dataIndex: null, + + /** + * @cfg {String} text + * The header text to be used as innerHTML (html tags are accepted) to display in the Grid. + * **Note**: to have a clickable header with no text displayed you can use the default of `&#160;` aka `&nbsp;`. */ -
    /** - * @cfg {Boolean} fixed Optional. true if the column width cannot be changed. Defaults to false. + text: '&#160;', + + /** + * @cfg {Boolean} sortable + * False to disable sorting of this column. Whether local/remote sorting is used is specified in + * `{@link Ext.data.Store#remoteSort}`. Defaults to true. */ -
    /** - * @cfg {Boolean} resizable Optional. false to disable column resizing. Defaults to true. + sortable: true, + + /** + * @cfg {Boolean} groupable + * If the grid uses a {@link Ext.grid.feature.Grouping}, this option may be used to disable the header menu + * item to group by the column selected. By default, the header menu group option is enabled. Set to false to + * disable (but still show) the group option in the header menu for the column. */ -
    /** - * @cfg {Boolean} menuDisabled Optional. true to disable the column menu. Defaults to false. + + /** + * @cfg {Boolean} fixed + * @deprecated. + * True to prevent the column from being resizable. */ -
    /** - * @cfg {Boolean} hidden - * Optional. true to initially hide this column. Defaults to false. - * A hidden column {@link Ext.grid.GridPanel#enableColumnHide may be shown via the header row menu}. - * If a column is never to be shown, simply do not include this column in the Column Model at all. + + /** + * @cfg {Boolean} resizable + * Set to <code>false</code> to prevent the column from being resizable. Defaults to <code>true</code> */ -
    /** - * @cfg {String} tooltip Optional. A text string to use as the column header's tooltip. If Quicktips - * are enabled, this value will be used as the text of the quick tip, otherwise it will be set as the - * header's HTML title attribute. Defaults to ''. + + /** + * @cfg {Boolean} hideable + * False to prevent the user from hiding this column. Defaults to true. */ -
    /** - * @cfg {Mixed} renderer - *

    For an alternative to specifying a renderer see {@link #xtype}

    - *

    Optional. A renderer is an 'interceptor' method which can be used transform data (value, - * appearance, etc.) before it is rendered). This may be specified in either of three ways: - *

      - *
    • A renderer function used to return HTML markup for a cell given the cell's data value.
    • - *
    • A string which references a property name of the {@link Ext.util.Format} class which - * provides a renderer function.
    • - *
    • An object specifying both the renderer function, and its execution scope (this - * reference) e.g.:
      
      -{
      -    fn: this.gridRenderer,
      -    scope: this
      -}
      -
    - * If not specified, the default renderer uses the raw data value.

    - *

    For information about the renderer function (passed parameters, etc.), see - * {@link Ext.grid.ColumnModel#setRenderer}. An example of specifying renderer function inline:

    
    -var companyColumn = {
    -   header: 'Company Name',
    -   dataIndex: 'company',
    -   renderer: function(value, metaData, record, rowIndex, colIndex, store) {
    -      // provide the logic depending on business rules
    -      // name of your own choosing to manipulate the cell depending upon
    -      // the data in the underlying Record object.
    -      if (value == 'whatever') {
    -          //metaData.css : String : A CSS class name to add to the TD element of the cell.
    -          //metaData.attr : String : An html attribute definition string to apply to
    -          //                         the data container element within the table
    -          //                         cell (e.g. 'style="color:red;"').
    -          metaData.css = 'name-of-css-class-you-will-define';
    -      }
    -      return value;
    -   }
    -}
    -     * 
    - * See also {@link #scope}. + hideable: true, + + /** + * @cfg {Boolean} menuDisabled + * True to disable the column header menu containing sort/hide options. Defaults to false. */ -
    /** - * @cfg {String} xtype Optional. A String which references a predefined {@link Ext.grid.Column} subclass - * type which is preconfigured with an appropriate {@link #renderer} to be easily - * configured into a ColumnModel. The predefined {@link Ext.grid.Column} subclass types are: - *
      - *
    • gridcolumn : {@link Ext.grid.Column} (Default)

    • - *
    • booleancolumn : {@link Ext.grid.BooleanColumn}

    • - *
    • numbercolumn : {@link Ext.grid.NumberColumn}

    • - *
    • datecolumn : {@link Ext.grid.DateColumn}

    • - *
    • templatecolumn : {@link Ext.grid.TemplateColumn}

    • - *
    - *

    Configuration properties for the specified xtype may be specified with - * the Column configuration properties, for example:

    - *
    
    -var grid = new Ext.grid.GridPanel({
    -    ...
    -    columns: [{
    -        header: 'Last Updated',
    -        dataIndex: 'lastChange',
    -        width: 85,
    -        sortable: true,
    -        //renderer: Ext.util.Format.dateRenderer('m/d/Y'),
    -        xtype: 'datecolumn', // use xtype instead of renderer
    -        format: 'M/d/Y' // configuration property for {@link Ext.grid.DateColumn}
    -    }, {
    -        ...
    -    }]
    -});
    -     * 
    + menuDisabled: false, + + /** + * @cfg {Function} renderer + * A renderer is an 'interceptor' method which can be used transform data (value, appearance, etc.) + * before it is rendered. Example: + * + * { + * renderer: function(value){ + * if (value === 1) { + * return '1 person'; + * } + * return value + ' people'; + * } + * } + * + * @cfg {Object} renderer.value The data value for the current cell + * @cfg {Object} renderer.metaData A collection of metadata about the current cell; can be used or modified + * by the renderer. Recognized properties are: tdCls, tdAttr, and style. + * @cfg {Ext.data.Model} renderer.record The record for the current row + * @cfg {Number} renderer.rowIndex The index of the current row + * @cfg {Number} renderer.colIndex The index of the current column + * @cfg {Ext.data.Store} renderer.store The data store + * @cfg {Ext.view.View} renderer.view The current view + * @cfg {String} renderer.return The HTML string to be rendered. + */ + renderer: false, + + /** + * @cfg {String} align + * Sets the alignment of the header and rendered columns. Defaults to 'left'. */ -
    /** - * @cfg {Object} scope Optional. The scope (this reference) in which to execute the - * renderer. Defaults to the Column configuration object. + align: 'left', + + /** + * @cfg {Boolean} draggable + * False to disable drag-drop reordering of this column. Defaults to true. */ -
    /** - * @cfg {String} align Optional. Set the CSS text-align property of the column. Defaults to undefined. + draggable: true, + + // Header does not use the typical ComponentDraggable class and therefore we + // override this with an emptyFn. It is controlled at the HeaderDragZone. + initDraggable: Ext.emptyFn, + + /** + * @cfg {String} tdCls + * A CSS class names to apply to the table cells for this column. */ -
    /** - * @cfg {String} css Optional. An inline style definition string which is applied to all table cells in the column - * (excluding headers). Defaults to undefined. + + /** + * @cfg {Object/String} editor + * An optional xtype or config object for a {@link Ext.form.field.Field Field} to use for editing. + * Only applicable if the grid is using an {@link Ext.grid.plugin.Editing Editing} plugin. */ -
    /** - * @cfg {Boolean} hideable Optional. Specify as false to prevent the user from hiding this column - * (defaults to true). To disallow column hiding globally for all columns in the grid, use - * {@link Ext.grid.GridPanel#enableColumnHide} instead. + + /** + * @cfg {Object/String} field + * Alias for {@link #editor}. + * @deprecated 4.0.5 Use {@link #editor} instead. */ -
    /** - * @cfg {Ext.form.Field} editor Optional. The {@link Ext.form.Field} to use when editing values in this column - * if editing is supported by the grid. See {@link #editable} also. + + /** + * @property {Ext.Element} triggerEl + * Element that acts as button for column header dropdown menu. */ - /** - * @private - * @cfg {Boolean} isColumn - * Used by ColumnModel setConfig method to avoid reprocessing a Column - * if isColumn is not set ColumnModel will recreate a new Ext.grid.Column - * Defaults to true. + /** + * @property {Ext.Element} textEl + * Element that contains the text in column header. */ - isColumn : true, - - constructor : function(config){ - Ext.apply(this, config); - - if(Ext.isString(this.renderer)){ - this.renderer = Ext.util.Format[this.renderer]; - }else if(Ext.isObject(this.renderer)){ - this.scope = this.renderer.scope; - this.renderer = this.renderer.fn; - } - if(!this.scope){ - this.scope = this; - } - - var ed = this.editor; - delete this.editor; - this.setEditor(ed); - this.addEvents( -
    /** - * @event click - * Fires when this Column is clicked. - * @param {Column} this - * @param {Grid} The owning GridPanel - * @param {Number} rowIndex - * @param {Ext.EventObject} e - */ - 'click', -
    /** - * @event contextmenu - * Fires when this Column is right clicked. - * @param {Column} this - * @param {Grid} The owning GridPanel - * @param {Number} rowIndex - * @param {Ext.EventObject} e - */ - 'contextmenu', -
    /** - * @event dblclick - * Fires when this Column is double clicked. - * @param {Column} this - * @param {Grid} The owning GridPanel - * @param {Number} rowIndex - * @param {Ext.EventObject} e - */ - 'dblclick', -
    /** - * @event mousedown - * Fires when this Column receives a mousedown event. - * @param {Column} this - * @param {Grid} The owning GridPanel - * @param {Number} rowIndex - * @param {Ext.EventObject} e - */ - 'mousedown' - ); - Ext.grid.Column.superclass.constructor.call(this); - }, - - /** - * @private - * Process and refire events routed from the GridView's processEvent method. - * Returns the event handler's status to allow cancelling of GridView's bubbling process. + + /** + * @private + * Set in this class to identify, at runtime, instances which are not instances of the + * HeaderContainer base class, but are in fact, the subclass: Header. */ - processEvent : function(name, e, grid, rowIndex, colIndex){ - return this.fireEvent(name, this, grid, rowIndex, e); + isHeader: true, + + initComponent: function() { + var me = this, + i, + len, + item; + + if (Ext.isDefined(me.header)) { + me.text = me.header; + delete me.header; + } + + // Flexed Headers need to have a minWidth defined so that they can never be squeezed out of existence by the + // HeaderContainer's specialized Box layout, the ColumnLayout. The ColumnLayout's overridden calculateChildboxes + // method extends the available layout space to accommodate the "desiredWidth" of all the columns. + if (me.flex) { + me.minWidth = me.minWidth || Ext.grid.plugin.HeaderResizer.prototype.minColWidth; + } + // Non-flexed Headers may never be squeezed in the event of a shortfall so + // always set their minWidth to their current width. + else { + me.minWidth = me.width; + } + + if (!me.triStateSort) { + me.possibleSortStates.length = 2; + } + + // A group header; It contains items which are themselves Headers + if (Ext.isDefined(me.columns)) { + me.isGroupHeader = true; + + //<debug> + if (me.dataIndex) { + Ext.Error.raise('Ext.grid.column.Column: Group header may not accept a dataIndex'); + } + if ((me.width && me.width !== Ext.grid.header.Container.prototype.defaultWidth) || me.flex) { + Ext.Error.raise('Ext.grid.column.Column: Group header does not support setting explicit widths or flexs. The group header width is calculated by the sum of its children.'); + } + //</debug> + + // The headers become child items + me.items = me.columns; + delete me.columns; + delete me.flex; + me.width = 0; + + // Acquire initial width from sub headers + for (i = 0, len = me.items.length; i < len; i++) { + item = me.items[i]; + if (!item.hidden) { + me.width += item.width || Ext.grid.header.Container.prototype.defaultWidth; + } + //<debug> + if (item.flex) { + Ext.Error.raise('Ext.grid.column.Column: items of a grouped header do not support flexed values. Each item must explicitly define its width.'); + } + //</debug> + } + me.minWidth = me.width; + + me.cls = (me.cls||'') + ' ' + Ext.baseCSSPrefix + 'group-header'; + me.sortable = false; + me.resizable = false; + me.align = 'center'; + } + + me.addChildEls('titleContainer', 'triggerEl', 'textEl'); + + // Initialize as a HeaderContainer + me.callParent(arguments); }, - /** - * @private - * Clean up. Remove any Editor. Remove any listeners. - */ - destroy: function() { - if(this.setEditor){ - this.setEditor(null); - } - this.purgeListeners(); - }, - -
    /** - * Optional. A function which returns displayable data when passed the following parameters: - *
      - *
    • value : Object

      The data value for the cell.

    • - *
    • metadata : Object

      An object in which you may set the following attributes:

        - *
      • css : String

        A CSS class name to add to the cell's TD element.

      • - *
      • attr : String

        An HTML attribute definition string to apply to the data container - * element within the table cell (e.g. 'style="color:red;"').

    • - *
    • record : Ext.data.record

      The {@link Ext.data.Record} from which the data was - * extracted.

    • - *
    • rowIndex : Number

      Row index

    • - *
    • colIndex : Number

      Column index

    • - *
    • store : Ext.data.Store

      The {@link Ext.data.Store} object from which the Record - * was extracted.

    • - *
    - * @property renderer - * @type Function + onAdd: function(childHeader) { + childHeader.isSubHeader = true; + childHeader.addCls(Ext.baseCSSPrefix + 'group-sub-header'); + this.callParent(arguments); + }, + + onRemove: function(childHeader) { + childHeader.isSubHeader = false; + childHeader.removeCls(Ext.baseCSSPrefix + 'group-sub-header'); + this.callParent(arguments); + }, + + initRenderData: function() { + var me = this; + + Ext.applyIf(me.renderData, { + text: me.text, + menuDisabled: me.menuDisabled + }); + return me.callParent(arguments); + }, + + applyColumnState: function (state) { + var me = this, + defined = Ext.isDefined; + + // apply any columns + me.applyColumnsState(state.columns); + + // Only state properties which were saved should be restored. + // (Only user-changed properties were saved by getState) + if (defined(state.hidden)) { + me.hidden = state.hidden; + } + if (defined(state.locked)) { + me.locked = state.locked; + } + if (defined(state.sortable)) { + me.sortable = state.sortable; + } + if (defined(state.width)) { + delete me.flex; + me.width = state.width; + } else if (defined(state.flex)) { + delete me.width; + me.flex = state.flex; + } + }, + + getColumnState: function () { + var me = this, + columns = [], + state = { + id: me.headerId + }; + + me.savePropsToState(['hidden', 'sortable', 'locked', 'flex', 'width'], state); + + if (me.isGroupHeader) { + me.items.each(function(column){ + columns.push(column.getColumnState()); + }); + if (columns.length) { + state.columns = columns; + } + } else if (me.isSubHeader && me.ownerCt.hidden) { + // don't set hidden on the children so they can auto height + delete me.hidden; + } + + if ('width' in state) { + delete state.flex; // width wins + } + return state; + }, + + /** + * Sets the header text for this Column. + * @param {String} text The header to display on this Column. + */ + setText: function(text) { + this.text = text; + if (this.rendered) { + this.textEl.update(text); + } + }, + + // Find the topmost HeaderContainer: An ancestor which is NOT a Header. + // Group Headers are themselves HeaderContainers + getOwnerHeaderCt: function() { + return this.up(':not([isHeader])'); + }, + + /** + * Returns the true grid column index associated with this column only if this column is a base level Column. If it + * is a group column, it returns `false`. + * @return {Number} */ - renderer : function(value){ - return value; + getIndex: function() { + return this.isGroupColumn ? false : this.getOwnerHeaderCt().getHeaderIndex(this); }, - // private - getEditor: function(rowIndex){ - return this.editable !== false ? this.editor : null; + onRender: function() { + var me = this, + grid = me.up('tablepanel'); + + // Disable the menu if there's nothing to show in the menu, ie: + // Column cannot be sorted, grouped or locked, and there are no grid columns which may be hidden + if (grid && (!me.sortable || grid.sortableColumns === false) && !me.groupable && !me.lockable && (grid.enableColumnHide === false || !me.getOwnerHeaderCt().getHideableColumns().length)) { + me.menuDisabled = true; + } + me.callParent(arguments); }, -
    /** - * Sets a new editor for this column. - * @param {Ext.Editor/Ext.form.Field} editor The editor to set + afterRender: function() { + var me = this, + el = me.el; + + me.callParent(arguments); + + el.addCls(Ext.baseCSSPrefix + 'column-header-align-' + me.align).addClsOnOver(me.overCls); + + me.mon(el, { + click: me.onElClick, + dblclick: me.onElDblClick, + scope: me + }); + + // BrowserBug: Ie8 Strict Mode, this will break the focus for this browser, + // must be fixed when focus management will be implemented. + if (!Ext.isIE8 || !Ext.isStrict) { + me.mon(me.getFocusEl(), { + focus: me.onTitleMouseOver, + blur: me.onTitleMouseOut, + scope: me + }); + } + + me.mon(me.titleContainer, { + mouseenter: me.onTitleMouseOver, + mouseleave: me.onTitleMouseOut, + scope: me + }); + + me.keyNav = Ext.create('Ext.util.KeyNav', el, { + enter: me.onEnterKey, + down: me.onDownKey, + scope: me + }); + }, + + /** + * Sets the width of this Column. + * @param {Number} width New width. */ - setEditor : function(editor){ - var ed = this.editor; - if(ed){ - if(ed.gridEditor){ - ed.gridEditor.destroy(); - delete ed.gridEditor; - }else{ - ed.destroy(); + setWidth: function(width, /* private - used internally */ doLayout) { + var me = this, + headerCt = me.ownerCt, + siblings, + len, i, + oldWidth = me.getWidth(), + groupWidth = 0, + sibling; + + if (width !== oldWidth) { + me.oldWidth = oldWidth; + + // Non-flexed Headers may never be squeezed in the event of a shortfall so + // always set the minWidth to their current width. + me.minWidth = me.width = width; + + // Bubble size changes upwards to group headers + if (headerCt.isGroupHeader) { + siblings = headerCt.items.items; + len = siblings.length; + + for (i = 0; i < len; i++) { + sibling = siblings[i]; + if (!sibling.hidden) { + groupWidth += (sibling === me) ? width : sibling.getWidth(); + } + } + headerCt.setWidth(groupWidth, doLayout); + } else if (doLayout !== false) { + // Allow the owning Container to perform the sizing + headerCt.doLayout(); } } - this.editor = null; - if(editor){ - //not an instance, create it - if(!editor.isXType){ - editor = Ext.create(editor, 'textfield'); + }, + + afterComponentLayout: function(width, height) { + var me = this, + ownerHeaderCt = this.getOwnerHeaderCt(); + + me.callParent(arguments); + + // Only changes at the base level inform the grid's HeaderContainer which will update the View + // Skip this if the width is null or undefined which will be the Box layout's initial pass through the child Components + // Skip this if it's the initial size setting in which case there is no ownerheaderCt yet - that is set afterRender + if (width && !me.isGroupHeader && ownerHeaderCt) { + ownerHeaderCt.onHeaderResize(me, width, true); + } + if (me.oldWidth && (width !== me.oldWidth)) { + ownerHeaderCt.fireEvent('columnresize', ownerHeaderCt, this, width); + } + delete me.oldWidth; + }, + + // private + // After the container has laid out and stretched, it calls this to correctly pad the inner to center the text vertically + // Total available header height must be passed to enable padding for inner elements to be calculated. + setPadding: function(headerHeight) { + var me = this, + lineHeight = Ext.util.TextMetrics.measure(me.textEl.dom, me.text).height; + + // Top title containing element must stretch to match height of sibling group headers + if (!me.isGroupHeader) { + if (me.titleContainer.getHeight() < headerHeight) { + me.titleContainer.dom.style.height = headerHeight + 'px'; } - this.editor = editor; + } + headerHeight = me.titleContainer.getViewSize().height; + + // Vertically center the header text in potentially vertically stretched header + if (lineHeight) { + me.titleContainer.setStyle({ + paddingTop: Math.max(((headerHeight - lineHeight) / 2), 0) + 'px' + }); + } + + // Only IE needs this + if (Ext.isIE && me.triggerEl) { + me.triggerEl.setHeight(headerHeight); } }, -
    /** - * Returns the {@link Ext.Editor editor} defined for this column that was created to wrap the {@link Ext.form.Field Field} - * used to edit the cell. - * @param {Number} rowIndex The row index - * @return {Ext.Editor} + onDestroy: function() { + var me = this; + // force destroy on the textEl, IE reports a leak + Ext.destroy(me.textEl, me.keyNav); + delete me.keyNav; + me.callParent(arguments); + }, + + onTitleMouseOver: function() { + this.titleContainer.addCls(this.hoverCls); + }, + + onTitleMouseOut: function() { + this.titleContainer.removeCls(this.hoverCls); + }, + + onDownKey: function(e) { + if (this.triggerEl) { + this.onElClick(e, this.triggerEl.dom || this.el.dom); + } + }, + + onEnterKey: function(e) { + this.onElClick(e, this.el.dom); + }, + + /** + * @private + * Double click + * @param e + * @param t */ - getCellEditor: function(rowIndex){ - var ed = this.getEditor(rowIndex); - if(ed){ - if(!ed.startEdit){ - if(!ed.gridEditor){ - ed.gridEditor = new Ext.grid.GridEditor(ed); - } - ed = ed.gridEditor; + onElDblClick: function(e, t) { + var me = this, + ownerCt = me.ownerCt; + if (ownerCt && Ext.Array.indexOf(ownerCt.items, me) !== 0 && me.isOnLeftEdge(e) ) { + ownerCt.expandToFit(me.previousSibling('gridcolumn')); + } + }, + + onElClick: function(e, t) { + + // The grid's docked HeaderContainer. + var me = this, + ownerHeaderCt = me.getOwnerHeaderCt(); + + if (ownerHeaderCt && !ownerHeaderCt.ddLock) { + // Firefox doesn't check the current target in a within check. + // Therefore we check the target directly and then within (ancestors) + if (me.triggerEl && (e.target === me.triggerEl.dom || t === me.triggerEl.dom || e.within(me.triggerEl))) { + ownerHeaderCt.onHeaderTriggerClick(me, e, t); + // if its not on the left hand edge, sort + } else if (e.getKey() || (!me.isOnLeftEdge(e) && !me.isOnRightEdge(e))) { + me.toggleSortState(); + ownerHeaderCt.onHeaderClick(me, e, t); } } - return ed; - } -}); + }, -
    /** - * @class Ext.grid.BooleanColumn - * @extends Ext.grid.Column - *

    A Column definition class which renders boolean data fields. See the {@link Ext.grid.Column#xtype xtype} - * config option of {@link Ext.grid.Column} for more details.

    - */ -Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, { -
    /** - * @cfg {String} trueText - * The string returned by the renderer when the column value is not falsy (defaults to 'true'). - */ - trueText: 'true', -
    /** - * @cfg {String} falseText - * The string returned by the renderer when the column value is falsy (but not undefined) (defaults to - * 'false'). - */ - falseText: 'false', -
    /** - * @cfg {String} undefinedText - * The string returned by the renderer when the column value is undefined (defaults to '&#160;'). + /** + * @private + * Process UI events from the view. The owning TablePanel calls this method, relaying events from the TableView + * @param {String} type Event type, eg 'click' + * @param {Ext.view.Table} view TableView Component + * @param {HTMLElement} cell Cell HtmlElement the event took place within + * @param {Number} recordIndex Index of the associated Store Model (-1 if none) + * @param {Number} cellIndex Cell index within the row + * @param {Ext.EventObject} e Original event + */ + processEvent: function(type, view, cell, recordIndex, cellIndex, e) { + return this.fireEvent.apply(this, arguments); + }, + + toggleSortState: function() { + var me = this, + idx, + nextIdx; + + if (me.sortable) { + idx = Ext.Array.indexOf(me.possibleSortStates, me.sortState); + + nextIdx = (idx + 1) % me.possibleSortStates.length; + me.setSortState(me.possibleSortStates[nextIdx]); + } + }, + + doSort: function(state) { + var ds = this.up('tablepanel').store; + ds.sort({ + property: this.getSortParam(), + direction: state + }); + }, + + /** + * Returns the parameter to sort upon when sorting this header. By default this returns the dataIndex and will not + * need to be overriden in most cases. + * @return {String} */ - undefinedText: ' ', - - constructor: function(cfg){ - Ext.grid.BooleanColumn.superclass.constructor.call(this, cfg); - var t = this.trueText, f = this.falseText, u = this.undefinedText; - this.renderer = function(v){ - if(v === undefined){ - return u; + getSortParam: function() { + return this.dataIndex; + }, + + //setSortState: function(state, updateUI) { + //setSortState: function(state, doSort) { + setSortState: function(state, skipClear, initial) { + var me = this, + colSortClsPrefix = Ext.baseCSSPrefix + 'column-header-sort-', + ascCls = colSortClsPrefix + 'ASC', + descCls = colSortClsPrefix + 'DESC', + nullCls = colSortClsPrefix + 'null', + ownerHeaderCt = me.getOwnerHeaderCt(), + oldSortState = me.sortState; + + if (oldSortState !== state && me.getSortParam()) { + me.addCls(colSortClsPrefix + state); + // don't trigger a sort on the first time, we just want to update the UI + if (state && !initial) { + me.doSort(state); } - if(!v || v === 'false'){ - return f; + switch (state) { + case 'DESC': + me.removeCls([ascCls, nullCls]); + break; + case 'ASC': + me.removeCls([descCls, nullCls]); + break; + case null: + me.removeCls([ascCls, descCls]); + break; } - return t; - }; - } -}); + if (ownerHeaderCt && !me.triStateSort && !skipClear) { + ownerHeaderCt.clearOtherSortStates(me); + } + me.sortState = state; + ownerHeaderCt.fireEvent('sortchange', ownerHeaderCt, me, state); + } + }, -
    /** - * @class Ext.grid.NumberColumn - * @extends Ext.grid.Column - *

    A Column definition class which renders a numeric data field according to a {@link #format} string. See the - * {@link Ext.grid.Column#xtype xtype} config option of {@link Ext.grid.Column} for more details.

    - */ -Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, { -
    /** - * @cfg {String} format - * A formatting string as used by {@link Ext.util.Format#number} to format a numeric value for this Column - * (defaults to '0,000.00'). - */ - format : '0,000.00', - constructor: function(cfg){ - Ext.grid.NumberColumn.superclass.constructor.call(this, cfg); - this.renderer = Ext.util.Format.numberRenderer(this.format); - } -}); + hide: function() { + var me = this, + items, + len, i, + lb, + newWidth = 0, + ownerHeaderCt = me.getOwnerHeaderCt(); -
    /** - * @class Ext.grid.DateColumn - * @extends Ext.grid.Column - *

    A Column definition class which renders a passed date according to the default locale, or a configured - * {@link #format}. See the {@link Ext.grid.Column#xtype xtype} config option of {@link Ext.grid.Column} - * for more details.

    - */ -Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, { -
    /** - * @cfg {String} format - * A formatting string as used by {@link Date#format} to format a Date for this Column - * (defaults to 'm/d/Y'). - */ - format : 'm/d/Y', - constructor: function(cfg){ - Ext.grid.DateColumn.superclass.constructor.call(this, cfg); - this.renderer = Ext.util.Format.dateRenderer(this.format); - } -}); + // Hiding means setting to zero width, so cache the width + me.oldWidth = me.getWidth(); -
    /** - * @class Ext.grid.TemplateColumn - * @extends Ext.grid.Column - *

    A Column definition class which renders a value by processing a {@link Ext.data.Record Record}'s - * {@link Ext.data.Record#data data} using a {@link #tpl configured} {@link Ext.XTemplate XTemplate}. - * See the {@link Ext.grid.Column#xtype xtype} config option of {@link Ext.grid.Column} for more - * details.

    - */ -Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, { -
    /** - * @cfg {String/XTemplate} tpl - * An {@link Ext.XTemplate XTemplate}, or an XTemplate definition string to use to process a - * {@link Ext.data.Record Record}'s {@link Ext.data.Record#data data} to produce a column's rendered value. - */ - constructor: function(cfg){ - Ext.grid.TemplateColumn.superclass.constructor.call(this, cfg); - var tpl = (!Ext.isPrimitive(this.tpl) && this.tpl.compile) ? this.tpl : new Ext.XTemplate(this.tpl); - this.renderer = function(value, p, r){ - return tpl.apply(r.data); - }; - this.tpl = tpl; - } -}); + // Hiding a group header hides itself, and then informs the HeaderContainer about its sub headers (Suppressing header layout) + if (me.isGroupHeader) { + items = me.items.items; + me.callParent(arguments); + ownerHeaderCt.onHeaderHide(me); + for (i = 0, len = items.length; i < len; i++) { + items[i].hidden = true; + ownerHeaderCt.onHeaderHide(items[i], true); + } + return; + } -
    /** - * @class Ext.grid.ActionColumn - * @extends Ext.grid.Column - *

    A Grid column type which renders an icon, or a series of icons in a grid cell, and offers a scoped click - * handler for each icon. Example usage:

    -
    
    -new Ext.grid.GridPanel({
    -    store: myStore,
    -    columns: [
    -        {
    -            xtype: 'actioncolumn',
    -            width: 50,
    -            items: [
    -                {
    -                    icon   : 'sell.gif',                // Use a URL in the icon config
    -                    tooltip: 'Sell stock',
    -                    handler: function(grid, rowIndex, colIndex) {
    -                        var rec = store.getAt(rowIndex);
    -                        alert("Sell " + rec.get('company'));
    -                    }
    -                },
    -                {
    -                    getClass: function(v, meta, rec) {  // Or return a class from a function
    -                        if (rec.get('change') < 0) {
    -                            this.items[1].tooltip = 'Do not buy!';
    -                            return 'alert-col';
    -                        } else {
    -                            this.items[1].tooltip = 'Buy stock';
    -                            return 'buy-col';
    -                        }
    -                    },
    -                    handler: function(grid, rowIndex, colIndex) {
    -                        var rec = store.getAt(rowIndex);
    -                        alert("Buy " + rec.get('company'));
    -                    }
    +        // TODO: Work with Jamie to produce a scheme where we can show/hide/resize without triggering a layout cascade
    +        lb = me.ownerCt.componentLayout.layoutBusy;
    +        me.ownerCt.componentLayout.layoutBusy = true;
    +        me.callParent(arguments);
    +        me.ownerCt.componentLayout.layoutBusy = lb;
    +
    +        // Notify owning HeaderContainer
    +        ownerHeaderCt.onHeaderHide(me);
    +
    +        if (me.ownerCt.isGroupHeader) {
    +            // If we've just hidden the last header in a group, then hide the group
    +            items = me.ownerCt.query('>:not([hidden])');
    +            if (!items.length) {
    +                me.ownerCt.hide();
    +            }
    +            // Size the group down to accommodate fewer sub headers
    +            else {
    +                for (i = 0, len = items.length; i < len; i++) {
    +                    newWidth += items[i].getWidth();
                     }
    -            ]
    +                me.ownerCt.minWidth = newWidth;
    +                me.ownerCt.setWidth(newWidth);
    +            }
             }
    -        //any other columns here
    -    ]
    -});
    -
    - *

    The action column can be at any index in the columns array, and a grid can have any number of - * action columns.

    - */ -Ext.grid.ActionColumn = Ext.extend(Ext.grid.Column, { -
    /** - * @cfg {String} icon - * The URL of an image to display as the clickable element in the column. - * Optional - defaults to {@link Ext#BLANK_IMAGE_URL Ext.BLANK_IMAGE_URL}. - */ -
    /** - * @cfg {String} iconCls - * A CSS class to apply to the icon image. To determine the class dynamically, configure the Column with a {@link #getClass} function. - */ -
    /** - * @cfg {Function} handler A function called when the icon is clicked. - * The handler is passed the following parameters:
      - *
    • grid : GridPanel
      The owning GridPanel.
    • - *
    • rowIndex : Number
      The row index clicked on.
    • - *
    • colIndex : Number
      The column index clicked on.
    • - *
    • item : Object
      The clicked item (or this Column if multiple - * {@link #items} were not configured).
    • - *
    • e : Event
      The click event.
    • - *
    - */ -
    /** - * @cfg {Object} scope The scope (this reference) in which the {@link #handler} - * and {@link #getClass} fuctions are executed. Defaults to this Column. - */ -
    /** - * @cfg {String} tooltip A tooltip message to be displayed on hover. {@link Ext.QuickTips#init Ext.QuickTips} must have - * been initialized. - */ -
    /** - * @cfg {Boolean} stopSelection Defaults to true. Prevent grid row selection upon mousedown. - */ -
    /** - * @cfg {Function} getClass A function which returns the CSS class to apply to the icon image. - * The function is passed the following parameters:
      - *
    • v : Object

      The value of the column's configured field (if any).

    • - *
    • metadata : Object

      An object in which you may set the following attributes:

        - *
      • css : String

        A CSS class name to add to the cell's TD element.

      • - *
      • attr : String

        An HTML attribute definition string to apply to the data container element within the table cell - * (e.g. 'style="color:red;"').

      • - *

    • - *
    • r : Ext.data.Record

      The Record providing the data.

    • - *
    • rowIndex : Number

      The row index..

    • - *
    • colIndex : Number

      The column index.

    • - *
    • store : Ext.data.Store

      The Store which is providing the data Model.

    • - *
    - */ -
    /** - * @cfg {Array} items An Array which may contain multiple icon definitions, each element of which may contain: - *
      - *
    • icon : String
      The url of an image to display as the clickable element - * in the column.
    • - *
    • iconCls : String
      A CSS class to apply to the icon image. - * To determine the class dynamically, configure the item with a getClass function.
    • - *
    • getClass : Function
      A function which returns the CSS class to apply to the icon image. - * The function is passed the following parameters:
        - *
      • v : Object

        The value of the column's configured field (if any).

      • - *
      • metadata : Object

        An object in which you may set the following attributes:

          - *
        • css : String

          A CSS class name to add to the cell's TD element.

        • - *
        • attr : String

          An HTML attribute definition string to apply to the data container element within the table cell - * (e.g. 'style="color:red;"').

        • - *

      • - *
      • r : Ext.data.Record

        The Record providing the data.

      • - *
      • rowIndex : Number

        The row index..

      • - *
      • colIndex : Number

        The column index.

      • - *
      • store : Ext.data.Store

        The Store which is providing the data Model.

      • - *
    • - *
    • handler : Function
      A function called when the icon is clicked.
    • - *
    • scope : Scope
      The scope (this reference) in which the - * handler and getClass functions are executed. Fallback defaults are this Column's - * configured scope, then this Column.
    • - *
    • tooltip : String
      A tooltip message to be displayed on hover. - * {@link Ext.QuickTips#init Ext.QuickTips} must have been initialized.
    • - *
    - */ - header: ' ', - - actionIdRe: /x-action-col-(\d+)/, - -
    /** - * @cfg {String} altText The alt text to use for the image element. Defaults to ''. - */ - altText: '', + }, - constructor: function(cfg) { + show: function() { var me = this, - items = cfg.items || (me.items = [me]), - l = items.length, - i, - item; + ownerCt = me.ownerCt, + ownerCtCompLayout = ownerCt.componentLayout, + ownerCtCompLayoutBusy = ownerCtCompLayout.layoutBusy, + ownerCtLayout = ownerCt.layout, + ownerCtLayoutBusy = ownerCtLayout.layoutBusy, + items, + len, i, + item, + newWidth = 0; + + // TODO: Work with Jamie to produce a scheme where we can show/hide/resize without triggering a layout cascade + + // Suspend our owner's layouts (both component and container): + ownerCtCompLayout.layoutBusy = ownerCtLayout.layoutBusy = true; + + me.callParent(arguments); - Ext.grid.ActionColumn.superclass.constructor.call(me, cfg); + ownerCtCompLayout.layoutBusy = ownerCtCompLayoutBusy; + ownerCtLayout.layoutBusy = ownerCtLayoutBusy; -// Renderer closure iterates through items creating an element for each and tagging with an identifying -// class name x-action-col-{n} - me.renderer = function(v, meta) { -// Allow a configured renderer to create initial value (And set the other values in the "metadata" argument!) - v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : ''; + // If a sub header, ensure that the group header is visible + if (me.isSubHeader) { + if (!ownerCt.isVisible()) { + ownerCt.show(); + } + } - meta.css += ' x-action-col-cell'; - for (i = 0; i < l; i++) { + // If we've just shown a group with all its sub headers hidden, then show all its sub headers + if (me.isGroupHeader && !me.query(':not([hidden])').length) { + items = me.query('>*'); + for (i = 0, len = items.length; i < len; i++) { item = items[i]; - v += '' + me.altText + ''; + item.preventLayout = true; + item.show(); + newWidth += item.getWidth(); + delete item.preventLayout; } - return v; - }; - }, + me.setWidth(newWidth); + } - destroy: function() { - delete this.items; - delete this.renderer; - return Ext.grid.ActionColumn.superclass.destroy.apply(this, arguments); + // Resize the owning group to accommodate + if (ownerCt.isGroupHeader && me.preventLayout !== true) { + items = ownerCt.query('>:not([hidden])'); + for (i = 0, len = items.length; i < len; i++) { + newWidth += items[i].getWidth(); + } + ownerCt.minWidth = newWidth; + ownerCt.setWidth(newWidth); + } + + // Notify owning HeaderContainer + ownerCt = me.getOwnerHeaderCt(); + if (ownerCt) { + ownerCt.onHeaderShow(me, me.preventLayout); + } }, - /** - * @private - * Process and refire events routed from the GridView's processEvent method. - * Also fires any configured click handlers. By default, cancels the mousedown event to prevent selection. - * Returns the event handler's status to allow cancelling of GridView's bubbling process. - */ - processEvent : function(name, e, grid, rowIndex, colIndex){ - var m = e.getTarget().className.match(this.actionIdRe), - item, fn; - if (m && (item = this.items[parseInt(m[1], 10)])) { - if (name == 'click') { - (fn = item.handler || this.handler) && fn.call(item.scope||this.scope||this, grid, rowIndex, colIndex, item, e); - } else if ((name == 'mousedown') && (item.stopSelection !== false)) { - return false; - } + getDesiredWidth: function() { + var me = this; + if (me.rendered && me.componentLayout && me.componentLayout.lastComponentSize) { + // headers always have either a width or a flex + // because HeaderContainer sets a defaults width + // therefore we can ignore the natural width + // we use the componentLayout's tracked width so that + // we can calculate the desired width when rendered + // but not visible because its being obscured by a layout + return me.componentLayout.lastComponentSize.width; + // Flexed but yet to be rendered this could be the case + // where a HeaderContainer and Headers are simply used as data + // structures and not rendered. + } + else if (me.flex) { + // this is going to be wrong, the defaultWidth + return me.width; } - return Ext.grid.ActionColumn.superclass.processEvent.apply(this, arguments); + else { + return me.width; + } + }, + + getCellSelector: function() { + return '.' + Ext.baseCSSPrefix + 'grid-cell-' + this.getItemId(); + }, + + getCellInnerSelector: function() { + return this.getCellSelector() + ' .' + Ext.baseCSSPrefix + 'grid-cell-inner'; + }, + + isOnLeftEdge: function(e) { + return (e.getXY()[0] - this.el.getLeft() <= this.handleWidth); + }, + + isOnRightEdge: function(e) { + return (this.el.getRight() - e.getXY()[0] <= this.handleWidth); } -}); -/* - * @property types - * @type Object - * @member Ext.grid.Column - * @static - *

    An object containing predefined Column classes keyed by a mnemonic code which may be referenced - * by the {@link Ext.grid.ColumnModel#xtype xtype} config option of ColumnModel.

    - *

    This contains the following properties

      - *
    • gridcolumn : {@link Ext.grid.Column Column constructor}
    • - *
    • booleancolumn : {@link Ext.grid.BooleanColumn BooleanColumn constructor}
    • - *
    • numbercolumn : {@link Ext.grid.NumberColumn NumberColumn constructor}
    • - *
    • datecolumn : {@link Ext.grid.DateColumn DateColumn constructor}
    • - *
    • templatecolumn : {@link Ext.grid.TemplateColumn TemplateColumn constructor}
    • - *
    - */ -Ext.grid.Column.types = { - gridcolumn : Ext.grid.Column, - booleancolumn: Ext.grid.BooleanColumn, - numbercolumn: Ext.grid.NumberColumn, - datecolumn: Ext.grid.DateColumn, - templatecolumn: Ext.grid.TemplateColumn, - actioncolumn: Ext.grid.ActionColumn -};
+ // intentionally omit getEditor and setEditor definitions bc we applyIf into columns + // when the editing plugin is injected + + /** + * @method getEditor + * Retrieves the editing field for editing associated with this header. Returns false if there is no field + * associated with the Header the method will return false. If the field has not been instantiated it will be + * created. Note: These methods only has an implementation if a Editing plugin has been enabled on the grid. + * @param {Object} record The {@link Ext.data.Model Model} instance being edited. + * @param {Object} defaultField An object representing a default field to be created + * @return {Ext.form.field.Field} field + */ + /** + * @method setEditor + * Sets the form field to be used for editing. Note: This method only has an implementation if an Editing plugin has + * been enabled on the grid. + * @param {Object} field An object representing a field to be created. If no xtype is specified a 'textfield' is + * assumed. + */ +}); +
- \ No newline at end of file +