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