source: trunk/web/addons/job_monarch/lib/extjs/source/widgets/grid/PropertyGrid.js @ 619

Last change on this file since 619 was 619, checked in by ramonb, 15 years ago

lib/:

  • added new AJAX dependancies: ExtJS, pChart, Lightbox2
File size: 13.3 KB
Line 
1/*
2 * Ext JS Library 2.2.1
3 * Copyright(c) 2006-2009, Ext JS, LLC.
4 * licensing@extjs.com
5 *
6 * http://extjs.com/license
7 */
8
9/**
10 * @class Ext.grid.PropertyRecord
11 * A specific {@link Ext.data.Record} type that represents a name/value pair and is made to work with the
12 * {@link Ext.grid.PropertyGrid}.  Typically, PropertyRecords do not need to be created directly as they can be
13 * created implicitly by simply using the appropriate data configs either via the {@link Ext.grid.PropertyGrid#source}
14 * config property or by calling {@link Ext.grid.PropertyGrid#setSource}.  However, if the need arises, these records
15 * can also be created explicitly as shwon below.  Example usage:
16 * <pre><code>
17var rec = new Ext.grid.PropertyRecord({
18    name: 'Birthday',
19    value: new Date(Date.parse('05/26/1972'))
20});
21// Add record to an already populated grid
22grid.store.addSorted(rec);
23</code></pre>
24 * @constructor
25 * @param {Object} config A data object in the format: {name: [name], value: [value]}.  The specified value's type
26 * will be read automatically by the grid to determine the type of editor to use when displaying it.
27 */
28Ext.grid.PropertyRecord = Ext.data.Record.create([
29    {name:'name',type:'string'}, 'value'
30]);
31
32/**
33 * @class Ext.grid.PropertyStore
34 * @extends Ext.util.Observable
35 * A custom wrapper for the {@link Ext.grid.PropertyGrid}'s {@link Ext.data.Store}. This class handles the mapping
36 * between the custom data source objects supported by the grid and the {@link Ext.grid.PropertyRecord} format
37 * required for compatibility with the underlying store. Generally this class should not need to be used directly --
38 * the grid's data should be accessed from the underlying store via the {@link #store} property.
39 * @constructor
40 * @param {Ext.grid.Grid} grid The grid this store will be bound to
41 * @param {Object} source The source data config object
42 */
43Ext.grid.PropertyStore = function(grid, source){
44    this.grid = grid;
45    this.store = new Ext.data.Store({
46        recordType : Ext.grid.PropertyRecord
47    });
48    this.store.on('update', this.onUpdate,  this);
49    if(source){
50        this.setSource(source);
51    }
52    Ext.grid.PropertyStore.superclass.constructor.call(this);
53};
54Ext.extend(Ext.grid.PropertyStore, Ext.util.Observable, {
55    // protected - should only be called by the grid.  Use grid.setSource instead.
56    setSource : function(o){
57        this.source = o;
58        this.store.removeAll();
59        var data = [];
60        for(var k in o){
61            if(this.isEditableValue(o[k])){
62                data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k));
63            }
64        }
65        this.store.loadRecords({records: data}, {}, true);
66    },
67
68    // private
69    onUpdate : function(ds, record, type){
70        if(type == Ext.data.Record.EDIT){
71            var v = record.data['value'];
72            var oldValue = record.modified['value'];
73            if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
74                this.source[record.id] = v;
75                record.commit();
76                this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
77            }else{
78                record.reject();
79            }
80        }
81    },
82
83    // private
84    getProperty : function(row){
85       return this.store.getAt(row);
86    },
87
88    // private
89    isEditableValue: function(val){
90        if(Ext.isDate(val)){
91            return true;
92        }else if(typeof val == 'object' || typeof val == 'function'){
93            return false;
94        }
95        return true;
96    },
97
98    // private
99    setValue : function(prop, value){
100        this.source[prop] = value;
101        this.store.getById(prop).set('value', value);
102    },
103
104    // protected - should only be called by the grid.  Use grid.getSource instead.
105    getSource : function(){
106        return this.source;
107    }
108});
109
110/**
111 * @class Ext.grid.PropertyColumnModel
112 * @extends Ext.grid.ColumnModel
113 * A custom column model for the {@link Ext.grid.PropertyGrid}.  Generally it should not need to be used directly.
114 * @constructor
115 * @param {Ext.grid.Grid} grid The grid this store will be bound to
116 * @param {Object} source The source data config object
117 */
118Ext.grid.PropertyColumnModel = function(grid, store){
119    this.grid = grid;
120    var g = Ext.grid;
121    g.PropertyColumnModel.superclass.constructor.call(this, [
122        {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true},
123        {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
124    ]);
125    this.store = store;
126    this.bselect = Ext.DomHelper.append(document.body, {
127        tag: 'select', cls: 'x-grid-editor x-hide-display', children: [
128            {tag: 'option', value: 'true', html: 'true'},
129            {tag: 'option', value: 'false', html: 'false'}
130        ]
131    });
132    var f = Ext.form;
133
134    var bfield = new f.Field({
135        el:this.bselect,
136        bselect : this.bselect,
137        autoShow: true,
138        getValue : function(){
139            return this.bselect.value == 'true';
140        }
141    });
142    this.editors = {
143        'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
144        'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
145        'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
146        'boolean' : new g.GridEditor(bfield)
147    };
148    this.renderCellDelegate = this.renderCell.createDelegate(this);
149    this.renderPropDelegate = this.renderProp.createDelegate(this);
150};
151
152Ext.extend(Ext.grid.PropertyColumnModel, Ext.grid.ColumnModel, {
153    // private - strings used for locale support
154    nameText : 'Name',
155    valueText : 'Value',
156    dateFormat : 'm/j/Y',
157
158    // private
159    renderDate : function(dateVal){
160        return dateVal.dateFormat(this.dateFormat);
161    },
162
163    // private
164    renderBool : function(bVal){
165        return bVal ? 'true' : 'false';
166    },
167
168    // private
169    isCellEditable : function(colIndex, rowIndex){
170        return colIndex == 1;
171    },
172
173    // private
174    getRenderer : function(col){
175        return col == 1 ?
176            this.renderCellDelegate : this.renderPropDelegate;
177    },
178
179    // private
180    renderProp : function(v){
181        return this.getPropertyName(v);
182    },
183
184    // private
185    renderCell : function(val){
186        var rv = val;
187        if(Ext.isDate(val)){
188            rv = this.renderDate(val);
189        }else if(typeof val == 'boolean'){
190            rv = this.renderBool(val);
191        }
192        return Ext.util.Format.htmlEncode(rv);
193    },
194
195    // private
196    getPropertyName : function(name){
197        var pn = this.grid.propertyNames;
198        return pn && pn[name] ? pn[name] : name;
199    },
200
201    // private
202    getCellEditor : function(colIndex, rowIndex){
203        var p = this.store.getProperty(rowIndex);
204        var n = p.data['name'], val = p.data['value'];
205        if(this.grid.customEditors[n]){
206            return this.grid.customEditors[n];
207        }
208        if(Ext.isDate(val)){
209            return this.editors['date'];
210        }else if(typeof val == 'number'){
211            return this.editors['number'];
212        }else if(typeof val == 'boolean'){
213            return this.editors['boolean'];
214        }else{
215            return this.editors['string'];
216        }
217    }
218});
219
220/**
221 * @class Ext.grid.PropertyGrid
222 * @extends Ext.grid.EditorGridPanel
223 * A specialized grid implementation intended to mimic the traditional property grid as typically seen in
224 * development IDEs.  Each row in the grid represents a property of some object, and the data is stored
225 * as a set of name/value pairs in {@link Ext.grid.PropertyRecord}s.  Example usage:
226 * <pre><code>
227var grid = new Ext.grid.PropertyGrid({
228    title: 'Properties Grid',
229    autoHeight: true,
230    width: 300,
231    renderTo: 'grid-ct',
232    source: {
233        "(name)": "My Object",
234        "Created": new Date(Date.parse('10/15/2006')),
235        "Available": false,
236        "Version": .01,
237        "Description": "A test object"
238    }
239});
240</pre></code>
241 * @constructor
242 * @param {Object} config The grid config object
243 */
244Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
245    /**
246    * @cfg {Object} propertyNames An object containing property name/display name pairs.
247    * If specified, the display name will be shown in the name column instead of the property name.
248    */
249    /**
250    * @cfg {Object} source A data object to use as the data source of the grid (see {@link #setSource} for details).
251    */
252    /**
253    * @cfg {Object} customEditors An object containing name/value pairs of custom editor type definitions that allow
254    * the grid to support additional types of editable fields.  By default, the grid supports strongly-typed editing
255    * of strings, dates, numbers and booleans using built-in form editors, but any custom type can be supported and
256    * associated with a custom input control by specifying a custom editor.  The name of the editor
257    * type should correspond with the name of the property that will use the editor.  Example usage:
258    * <pre><code>
259var grid = new Ext.grid.PropertyGrid({
260    ...
261    customEditors: {
262        'Start Time': new Ext.grid.GridEditor(new Ext.form.TimeField({selectOnFocus:true}))
263    },
264    source: {
265        'Start Time': '10:00 AM'
266    }
267});
268</code></pre>
269    */
270
271    // private config overrides
272    enableColumnMove:false,
273    stripeRows:false,
274    trackMouseOver: false,
275    clicksToEdit:1,
276    enableHdMenu : false,
277    viewConfig : {
278        forceFit:true
279    },
280
281    // private
282    initComponent : function(){
283        this.customEditors = this.customEditors || {};
284        this.lastEditRow = null;
285        var store = new Ext.grid.PropertyStore(this);
286        this.propStore = store;
287        var cm = new Ext.grid.PropertyColumnModel(this, store);
288        store.store.sort('name', 'ASC');
289        this.addEvents(
290            /**
291             * @event beforepropertychange
292             * Fires before a property value changes.  Handlers can return false to cancel the property change
293             * (this will internally call {@link Ext.data.Record#reject} on the property's record).
294             * @param {Object} source The source data object for the grid (corresponds to the same object passed in
295             * as the {@link #source} config property).
296             * @param {String} recordId The record's id in the data store
297             * @param {Mixed} value The current edited property value
298             * @param {Mixed} oldValue The original property value prior to editing
299             */
300            'beforepropertychange',
301            /**
302             * @event propertychange
303             * Fires after a property value has changed.
304             * @param {Object} source The source data object for the grid (corresponds to the same object passed in
305             * as the {@link #source} config property).
306             * @param {String} recordId The record's id in the data store
307             * @param {Mixed} value The current edited property value
308             * @param {Mixed} oldValue The original property value prior to editing
309             */
310            'propertychange'
311        );
312        this.cm = cm;
313        this.ds = store.store;
314        Ext.grid.PropertyGrid.superclass.initComponent.call(this);
315
316        this.selModel.on('beforecellselect', function(sm, rowIndex, colIndex){
317            if(colIndex === 0){
318                this.startEditing.defer(200, this, [rowIndex, 1]);
319                return false;
320            }
321        }, this);
322    },
323
324    // private
325    onRender : function(){
326        Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
327
328        this.getGridEl().addClass('x-props-grid');
329    },
330
331    // private
332    afterRender: function(){
333        Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
334        if(this.source){
335            this.setSource(this.source);
336        }
337    },
338
339    /**
340     * Sets the source data object containing the property data.  The data object can contain one or more name/value
341     * pairs representing all of the properties of an object to display in the grid, and this data will automatically
342     * be loaded into the grid's {@link #store}.  The values should be supplied in the proper data type if needed,
343     * otherwise string type will be assumed.  If the grid already contains data, this method will replace any
344     * existing data.  See also the {@link #source} config value.  Example usage:
345     * <pre><code>
346grid.setSource({
347    "(name)": "My Object",
348    "Created": new Date(Date.parse('10/15/2006')),  // date type
349    "Available": false,  // boolean type
350    "Version": .01,      // decimal type
351    "Description": "A test object"
352});
353</code></pre>
354     * @param {Object} source The data object
355     */
356    setSource : function(source){
357        this.propStore.setSource(source);
358    },
359
360    /**
361     * Gets the source data object containing the property data.  See {@link #setSource} for details regarding the
362     * format of the data object.
363     * @return {Object} The data object
364     */
365    getSource : function(){
366        return this.propStore.getSource();
367    }
368});
369Ext.reg("propertygrid", Ext.grid.PropertyGrid);
Note: See TracBrowser for help on using the repository browser.