Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / Grid.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-grid-property-Grid'>/**
19 </span> * @class Ext.grid.property.Grid
20  * @extends Ext.grid.Panel
21  *
22  * A specialized grid implementation intended to mimic the traditional property grid as typically seen in
23  * development IDEs.  Each row in the grid represents a property of some object, and the data is stored
24  * as a set of name/value pairs in {@link Ext.grid.property.Property Properties}.  Example usage:
25  *
26  *     @example
27  *     Ext.create('Ext.grid.property.Grid', {
28  *         title: 'Properties Grid',
29  *         width: 300,
30  *         renderTo: Ext.getBody(),
31  *         source: {
32  *             &quot;(name)&quot;: &quot;My Object&quot;,
33  *             &quot;Created&quot;: Ext.Date.parse('10/15/2006', 'm/d/Y'),
34  *             &quot;Available&quot;: false,
35  *             &quot;Version&quot;: .01,
36  *             &quot;Description&quot;: &quot;A test object&quot;
37  *         }
38  *     });
39  */
40 Ext.define('Ext.grid.property.Grid', {
41
42     extend: 'Ext.grid.Panel',
43
44     alias: 'widget.propertygrid',
45
46     alternateClassName: 'Ext.grid.PropertyGrid',
47
48     uses: [
49        'Ext.grid.plugin.CellEditing',
50        'Ext.grid.property.Store',
51        'Ext.grid.property.HeaderContainer',
52        'Ext.XTemplate',
53        'Ext.grid.CellEditor',
54        'Ext.form.field.Date',
55        'Ext.form.field.Text',
56        'Ext.form.field.Number'
57     ],
58
59 <span id='Ext-grid-property-Grid-cfg-propertyNames'>   /**
60 </span>    * @cfg {Object} propertyNames An object containing custom property name/display name pairs.
61     * If specified, the display name will be shown in the name column instead of the property name.
62     */
63
64 <span id='Ext-grid-property-Grid-cfg-source'>    /**
65 </span>    * @cfg {Object} source A data object to use as the data source of the grid (see {@link #setSource} for details).
66     */
67
68 <span id='Ext-grid-property-Grid-cfg-customEditors'>    /**
69 </span>    * @cfg {Object} customEditors An object containing name/value pairs of custom editor type definitions that allow
70     * the grid to support additional types of editable fields.  By default, the grid supports strongly-typed editing
71     * of strings, dates, numbers and booleans using built-in form editors, but any custom type can be supported and
72     * associated with a custom input control by specifying a custom editor.  The name of the editor
73     * type should correspond with the name of the property that will use the editor.  Example usage:
74     * &lt;pre&gt;&lt;code&gt;
75 var grid = new Ext.grid.property.Grid({
76
77     // Custom editors for certain property names
78     customEditors: {
79         evtStart: Ext.create('Ext.form.TimeField' {selectOnFocus:true})
80     },
81
82     // Displayed name for property names in the source
83     propertyNames: {
84         evtStart: 'Start Time'
85     },
86
87     // Data object containing properties to edit
88     source: {
89         evtStart: '10:00 AM'
90     }
91 });
92 &lt;/code&gt;&lt;/pre&gt;
93     */
94
95 <span id='Ext-grid-property-Grid-cfg-source'>    /**
96 </span>    * @cfg {Object} source A data object to use as the data source of the grid (see {@link #setSource} for details).
97     */
98
99 <span id='Ext-grid-property-Grid-cfg-customRenderers'>    /**
100 </span>    * @cfg {Object} customRenderers An object containing name/value pairs of custom renderer type definitions that allow
101     * the grid to support custom rendering of fields.  By default, the grid supports strongly-typed rendering
102     * of strings, dates, numbers and booleans using built-in form editors, but any custom type can be supported and
103     * associated with the type of the value.  The name of the renderer type should correspond with the name of the property
104     * that it will render.  Example usage:
105     * &lt;pre&gt;&lt;code&gt;
106 var grid = Ext.create('Ext.grid.property.Grid', {
107     customRenderers: {
108         Available: function(v){
109             if (v) {
110                 return '&lt;span style=&quot;color: green;&quot;&gt;Yes&lt;/span&gt;';
111             } else {
112                 return '&lt;span style=&quot;color: red;&quot;&gt;No&lt;/span&gt;';
113             }
114         }
115     },
116     source: {
117         Available: true
118     }
119 });
120 &lt;/code&gt;&lt;/pre&gt;
121     */
122
123 <span id='Ext-grid-property-Grid-cfg-valueField'>    /**
124 </span>     * @cfg {String} valueField
125      * Optional. The name of the field from the property store to use as the value field name. Defaults to &lt;code&gt;'value'&lt;/code&gt;
126      * This may be useful if you do not configure the property Grid from an object, but use your own store configuration.
127      */
128     valueField: 'value',
129
130 <span id='Ext-grid-property-Grid-cfg-nameField'>    /**
131 </span>     * @cfg {String} nameField
132      * Optional. The name of the field from the property store to use as the property field name. Defaults to &lt;code&gt;'name'&lt;/code&gt;
133      * This may be useful if you do not configure the property Grid from an object, but use your own store configuration.
134      */
135     nameField: 'name',
136
137 <span id='Ext-grid-property-Grid-cfg-nameColumnWidth'>    /**
138 </span>     * @cfg {Number} nameColumnWidth
139      * Optional. Specify the width for the name column. The value column will take any remaining space. Defaults to &lt;tt&gt;115&lt;/tt&gt;.
140      */
141
142     // private config overrides
143     enableColumnMove: false,
144     columnLines: true,
145     stripeRows: false,
146     trackMouseOver: false,
147     clicksToEdit: 1,
148     enableHdMenu: false,
149
150     // private
151     initComponent : function(){
152         var me = this;
153
154         me.addCls(Ext.baseCSSPrefix + 'property-grid');
155         me.plugins = me.plugins || [];
156
157         // Enable cell editing. Inject a custom startEdit which always edits column 1 regardless of which column was clicked.
158         me.plugins.push(Ext.create('Ext.grid.plugin.CellEditing', {
159             clicksToEdit: me.clicksToEdit,
160
161             // Inject a startEdit which always edits the value column
162             startEdit: function(record, column) {
163                 // Maintainer: Do not change this 'this' to 'me'! It is the CellEditing object's own scope.
164                 return this.self.prototype.startEdit.call(this, record, me.headerCt.child('#' + me.valueField));
165             }
166         }));
167
168         me.selModel = {
169             selType: 'cellmodel',
170             onCellSelect: function(position) {
171                 if (position.column != 1) {
172                     position.column = 1;
173                 }
174                 return this.self.prototype.onCellSelect.call(this, position);
175             }
176         };
177         me.customRenderers = me.customRenderers || {};
178         me.customEditors = me.customEditors || {};
179
180         // Create a property.Store from the source object unless configured with a store
181         if (!me.store) {
182             me.propStore = me.store = Ext.create('Ext.grid.property.Store', me, me.source);
183         }
184
185         me.store.sort('name', 'ASC');
186         me.columns = Ext.create('Ext.grid.property.HeaderContainer', me, me.store);
187
188         me.addEvents(
189 <span id='Ext-grid-property-Grid-event-beforepropertychange'>            /**
190 </span>             * @event beforepropertychange
191              * Fires before a property value changes.  Handlers can return false to cancel the property change
192              * (this will internally call {@link Ext.data.Model#reject} on the property's record).
193              * @param {Object} source The source data object for the grid (corresponds to the same object passed in
194              * as the {@link #source} config property).
195              * @param {String} recordId The record's id in the data store
196              * @param {Object} value The current edited property value
197              * @param {Object} oldValue The original property value prior to editing
198              */
199             'beforepropertychange',
200 <span id='Ext-grid-property-Grid-event-propertychange'>            /**
201 </span>             * @event propertychange
202              * Fires after a property value has changed.
203              * @param {Object} source The source data object for the grid (corresponds to the same object passed in
204              * as the {@link #source} config property).
205              * @param {String} recordId The record's id in the data store
206              * @param {Object} value The current edited property value
207              * @param {Object} oldValue The original property value prior to editing
208              */
209             'propertychange'
210         );
211         me.callParent();
212
213         // Inject a custom implementation of walkCells which only goes up or down
214         me.getView().walkCells = this.walkCells;
215
216         // Set up our default editor set for the 4 atomic data types
217         me.editors = {
218             'date'    : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Date',   {selectOnFocus: true})}),
219             'string'  : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Text',   {selectOnFocus: true})}),
220             'number'  : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.Number', {selectOnFocus: true})}),
221             'boolean' : Ext.create('Ext.grid.CellEditor', { field: Ext.create('Ext.form.field.ComboBox', {
222                 editable: false,
223                 store: [[ true, me.headerCt.trueText ], [false, me.headerCt.falseText ]]
224             })})
225         };
226
227         // Track changes to the data so we can fire our events.
228         me.store.on('update', me.onUpdate, me);
229     },
230
231     // private
232     onUpdate : function(store, record, operation) {
233         var me = this,
234             v, oldValue;
235
236         if (operation == Ext.data.Model.EDIT) {
237             v = record.get(me.valueField);
238             oldValue = record.modified.value;
239             if (me.fireEvent('beforepropertychange', me.source, record.getId(), v, oldValue) !== false) {
240                 if (me.source) {
241                     me.source[record.getId()] = v;
242                 }
243                 record.commit();
244                 me.fireEvent('propertychange', me.source, record.getId(), v, oldValue);
245             } else {
246                 record.reject();
247             }
248         }
249     },
250
251     // Custom implementation of walkCells which only goes up and down.
252     walkCells: function(pos, direction, e, preventWrap, verifierFn, scope) {
253         if (direction == 'left') {
254             direction = 'up';
255         } else if (direction == 'right') {
256             direction = 'down';
257         }
258         pos = Ext.view.Table.prototype.walkCells.call(this, pos, direction, e, preventWrap, verifierFn, scope);
259         if (!pos.column) {
260             pos.column = 1;
261         }
262         return pos;
263     },
264
265     // private
266     // returns the correct editor type for the property type, or a custom one keyed by the property name
267     getCellEditor : function(record, column) {
268         var me = this,
269             propName = record.get(me.nameField),
270             val = record.get(me.valueField),
271             editor = me.customEditors[propName];
272
273         // A custom editor was found. If not already wrapped with a CellEditor, wrap it, and stash it back
274         // If it's not even a Field, just a config object, instantiate it before wrapping it.
275         if (editor) {
276             if (!(editor instanceof Ext.grid.CellEditor)) {
277                 if (!(editor instanceof Ext.form.field.Base)) {
278                     editor = Ext.ComponentManager.create(editor, 'textfield');
279                 }
280                 editor = me.customEditors[propName] = Ext.create('Ext.grid.CellEditor', { field: editor });
281             }
282         } else if (Ext.isDate(val)) {
283             editor = me.editors.date;
284         } else if (Ext.isNumber(val)) {
285             editor = me.editors.number;
286         } else if (Ext.isBoolean(val)) {
287             editor = me.editors['boolean'];
288         } else {
289             editor = me.editors.string;
290         }
291
292         // Give the editor a unique ID because the CellEditing plugin caches them
293         editor.editorId = propName;
294         return editor;
295     },
296
297     beforeDestroy: function() {
298         var me = this;
299         me.callParent();
300         me.destroyEditors(me.editors);
301         me.destroyEditors(me.customEditors);
302         delete me.source;
303     },
304
305     destroyEditors: function (editors) {
306         for (var ed in editors) {
307             if (editors.hasOwnProperty(ed)) {
308                 Ext.destroy(editors[ed]);
309             }
310         }
311     },
312
313 <span id='Ext-grid-property-Grid-method-setSource'>    /**
314 </span>     * Sets the source data object containing the property data.  The data object can contain one or more name/value
315      * pairs representing all of the properties of an object to display in the grid, and this data will automatically
316      * be loaded into the grid's {@link #store}.  The values should be supplied in the proper data type if needed,
317      * otherwise string type will be assumed.  If the grid already contains data, this method will replace any
318      * existing data.  See also the {@link #source} config value.  Example usage:
319      * &lt;pre&gt;&lt;code&gt;
320 grid.setSource({
321     &quot;(name)&quot;: &quot;My Object&quot;,
322     &quot;Created&quot;: Ext.Date.parse('10/15/2006', 'm/d/Y'),  // date type
323     &quot;Available&quot;: false,  // boolean type
324     &quot;Version&quot;: .01,      // decimal type
325     &quot;Description&quot;: &quot;A test object&quot;
326 });
327 &lt;/code&gt;&lt;/pre&gt;
328      * @param {Object} source The data object
329      */
330     setSource: function(source) {
331         this.source = source;
332         this.propStore.setSource(source);
333     },
334
335 <span id='Ext-grid-property-Grid-method-getSource'>    /**
336 </span>     * Gets the source data object containing the property data.  See {@link #setSource} for details regarding the
337      * format of the data object.
338      * @return {Object} The data object
339      */
340     getSource: function() {
341         return this.propStore.getSource();
342     },
343
344 <span id='Ext-grid-property-Grid-method-setProperty'>    /**
345 </span>     * Sets the value of a property.
346      * @param {String} prop The name of the property to set
347      * @param {Object} value The value to test
348      * @param {Boolean} create (Optional) True to create the property if it doesn't already exist. Defaults to &lt;tt&gt;false&lt;/tt&gt;.
349      */
350     setProperty: function(prop, value, create) {
351         this.propStore.setValue(prop, value, create);
352     },
353
354 <span id='Ext-grid-property-Grid-method-removeProperty'>    /**
355 </span>     * Removes a property from the grid.
356      * @param {String} prop The name of the property to remove
357      */
358     removeProperty: function(prop) {
359         this.propStore.remove(prop);
360     }
361
362 <span id='Ext-grid-property-Grid-cfg-store'>    /**
363 </span>     * @cfg store
364      * @hide
365      */
366 <span id='Ext-grid-property-Grid-cfg-colModel'>    /**
367 </span>     * @cfg colModel
368      * @hide
369      */
370 <span id='Ext-grid-property-Grid-cfg-cm'>    /**
371 </span>     * @cfg cm
372      * @hide
373      */
374 <span id='Ext-grid-property-Grid-cfg-columns'>    /**
375 </span>     * @cfg columns
376      * @hide
377      */
378 });</pre>
379 </body>
380 </html>