-
15 Jul 2008 3:03 PM #1
Improved PropertyGrid
Improved PropertyGrid
I recently worked with the PropertyGrid on a project and found it rather... lacking. It is in it's shipped state very hard to use, not intuitive at all, and has limited documentation. With all of this, I assumed the PropertyGrid could be used almost as a drop-in replacement for a normal GridPanel. This is of course incorrect, but many other people seem to make the same mistake, so it seemed worthwhile to modify it to act more like a normal grid.
It actually works more like a formPanel though really, but just because it can only work with one record at a time. I use several of them in a portal layout to "section" a record into related panels, with a 'beforepropertychange' listener that commits changes back to the original record.
I gave it an xtype of 'propertygrid2' for lack of any better ideas, but that is easy enough to change for anyone that cares.
New config properties:
fields
An array of property definitions, one per each 'row' to appear in the Grid. This is meant to emulate the 'columns' config of a normal Grid. If this is upplied, only fields defined within this property will ever be displayed, regardless of what is supplied in the source.
Valid member options:
id: id of the property. not really used right now, but should be supplied.
dataIndex: name of the field in the source to use as this property's value component.
header: text to display as this property's name.
editor: custom Ext.grid.GridEditor to use for this property.
renderer: renderer function for this property's value. supplies the same arguments as a normal grid renderer. keep in mind that the record supplied is a PropertyRecord, which contains only data related to this property.
editable: editable status of this property. defaults to true.
ex:
nameWidthCode:[{ id: 'fname', dataIndex: 'fname', header: 'First Name', editable: false }, { id: 'lname', dataIndex: 'lname', header: 'Last Name', editable: false }, { id: 'id', dataIndex: 'id', header: 'Employee ID', editor: new Ext.grid.GridEditor(new Ext.form.NumberField({selectOnFocus:true, style:'text-align:left;'})), renderer: function(val, metadata, record, rowIndex, colIndex, store) { metaData.attr += ' style="color:red"'; } }
Width of the 'name' column. default 50.
valueWidth
Width of the 'value' column. default 50.
autoExpandColumn
Column to auto expand to use available space. default 'value'.
editable
Boolean to enable editing of all properties in this grid. default true.
Also added a couple new methods:
load()
Loads a simple object into the grid. Identical to setSource().
loadRecord()
Loads an Ext.Record into the grid.
Source:
PHP Code:/*
* Ext JS Library 2.1
* Copyright(c) 2006-2008, Ext JS, LLC.
* licensing@extjs.com
*
* http://extjs.com/license
*/
Ext.namespace('Ext.ux.grid');
/**
* @class Ext.grid.PropertyRecord
* A specific {@link Ext.data.Record} type that represents a name/value pair and is made to work with the
* {@link Ext.grid.PropertyGrid}. Typically, PropertyRecords do not need to be created directly as they can be
* created implicitly by simply using the appropriate data configs either via the {@link Ext.grid.PropertyGrid#source}
* config property or by calling {@link Ext.grid.PropertyGrid#setSource}. However, if the need arises, these records
* can also be created explicitly as shwon below. Example usage:
* <pre><code>
var rec = new Ext.grid.PropertyRecord({
name: 'Birthday',
value: new Date(Date.parse('05/26/1972'))
});
// Add record to an already populated grid
grid.store.addSorted(rec);
</code></pre>
* @constructor
* @param {Object} config A data object in the format: {name: [name], value: [value]}. The specified value's type
* will be read automatically by the grid to determine the type of editor to use when displaying it.
*/
Ext.ux.grid.PropertyRecord = Ext.data.Record.create([
{name:'name',type:'string'}, 'value', 'header', 'field'
]);
/**
* @class Ext.grid.PropertyStore
* @extends Ext.util.Observable
* A custom wrapper for the {@link Ext.grid.PropertyGrid}'s {@link Ext.data.Store}. This class handles the mapping
* between the custom data source objects supported by the grid and the {@link Ext.grid.PropertyRecord} format
* required for compatibility with the underlying store. Generally this class should not need to be used directly --
* the grid's data should be accessed from the underlying store via the {@link #store} property.
* @constructor
* @param {Ext.grid.Grid} grid The grid this store will be bound to
* @param {Object} source The source data config object
*/
Ext.ux.grid.PropertyStore = function(grid, source){
this.grid = grid;
this.store = new Ext.data.Store({
recordType : Ext.grid.PropertyRecord
});
this.store.loadRecords = function(o, options, success){
if(!o || success === false){
if(success !== false){
this.fireEvent("load", this, [], options);
}
if(options.callback){
options.callback.call(options.scope || this, [], options, false);
}
return;
}
var r = o.records, t = o.totalRecords || r.length;
if(!options || options.add !== true){
if(this.pruneModifiedRecords){
this.modified = [];
}
for(var i = 0, len = r.length; i < len; i++){
r[i].join(this);
}
if(this.snapshot){
this.data = this.snapshot;
delete this.snapshot;
}
this.data.clear();
this.data.addAll(r);
this.totalLength = t;
//this.applySort();
this.fireEvent("datachanged", this);
}else{
this.totalLength = Math.max(t, this.data.length+r.length);
this.add(r);
}
this.fireEvent("load", this, r, options);
if(options.callback){
options.callback.call(options.scope || this, r, options, true);
}
}
this.store.on('update', this.onUpdate, this);
if(source){
this.setSource(source);
}
Ext.ux.grid.PropertyStore.superclass.constructor.call(this);
};
Ext.extend(Ext.ux.grid.PropertyStore, Ext.util.Observable, {
// protected - should only be called by the grid. Use grid.setSource instead.
setSource : function(o,fields){
this.source = o;
this.store.removeAll();
var data = [];
if (fields) {
for (var k in fields) {
k=fields[k];
if (typeof(k) == 'object'){
//if (k.id && this.isEditableValue(o[k.dataIndex])) {
data.push(new Ext.grid.PropertyRecord({
name: k.dataIndex,
value: o[k.dataIndex],
header: k.header,
field: k
}, k.id));
}
}
} else {
for (var k in o) {
if (this.isEditableValue(o[k])) {
data.push(new Ext.grid.PropertyRecord({
name: k,
value: o[k],
header: k
}, k));
}
}
}
this.store.loadRecords({records: data}, {}, true);
},
// private
onUpdate : function(ds, record, type){
if(type == Ext.data.Record.EDIT){
var v = record.data['value'];
var oldValue = record.modified['value'];
if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
this.source[record.id] = v;
record.commit();
this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
}else{
record.reject();
}
}
},
// private
getProperty : function(row){
return this.store.getAt(row);
},
// private
isEditableValue: function(val){
if(Ext.isDate(val)){
return true;
}else if(typeof val == 'object' || typeof val == 'function'){
return false;
}
return true;
},
// private
setValue : function(prop, value){
this.source[prop] = value;
this.store.getById(prop).set('value', value);
},
// protected - should only be called by the grid. Use grid.getSource instead.
getSource : function(){
return this.source;
}
});
/**
* @class Ext.grid.PropertyColumnModel
* @extends Ext.grid.ColumnModel
* A custom column model for the {@link Ext.grid.PropertyGrid}. Generally it should not need to be used directly.
* @constructor
* @param {Ext.grid.Grid} grid The grid this store will be bound to
* @param {Object} source The source data config object
*/
Ext.ux.grid.PropertyColumnModel = function(grid, store){
this.grid = grid;
var g = Ext.grid;
Ext.ux.grid.PropertyColumnModel.superclass.constructor.call(this, [
{header: this.nameText, width:grid.nameWidth, sortable: true, dataIndex:'header', id: 'name', menuDisabled:true},
{header: this.valueText, width:grid.valueWidth, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
]);
this.store = store;
this.bselect = Ext.DomHelper.append(document.body, {
tag: 'select', cls: 'x-grid-editor x-hide-display', children: [
{tag: 'option', value: 'true', html: 'true'},
{tag: 'option', value: 'false', html: 'false'}
]
});
var f = Ext.form;
var bfield = new f.Field({
el:this.bselect,
bselect : this.bselect,
autoShow: true,
getValue : function(){
return this.bselect.value == 'true';
}
});
this.editors = {
'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
'boolean' : new g.GridEditor(bfield)
};
this.renderCellDelegate = this.renderCell.createDelegate(this);
this.renderPropDelegate = this.renderProp.createDelegate(this);
};
Ext.extend(Ext.ux.grid.PropertyColumnModel, Ext.grid.ColumnModel, {
// private - strings used for locale support
nameText : 'Name',
valueText : 'Value',
dateFormat : 'm/j/Y',
// private
renderDate : function(dateVal){
return dateVal.dateFormat(this.dateFormat);
},
// private
renderBool : function(bVal){
return bVal ? 'true' : 'false';
},
// private
isCellEditable : function(colIndex, rowIndex){
var p = this.store.getProperty(rowIndex);
if (p.data.field && p.data.field.editable == false) {
return false;
}
return colIndex == 1;
},
// private
getRenderer : function(col){
return col == 1 ?
this.renderCellDelegate : this.renderPropDelegate;
},
// private
renderProp : function(v){
return this.getPropertyName(v);
},
// private
renderCell : function(val, metadata, record, rowIndex, colIndex, store){
if (record.data.field && typeof(record.data.field.renderer) == 'function'){
return record.data.field.renderer.call(this, val, metadata, record, rowIndex, colIndex, store);
}
var rv = val;
if(Ext.isDate(val)){
rv = this.renderDate(val);
}else if(typeof val == 'boolean'){
rv = this.renderBool(val);
}
return Ext.util.Format.htmlEncode(rv);
},
// private
getPropertyName : function(name){
var pn = this.grid.propertyNames;
return pn && pn[name] ? pn[name] : name;
},
// private
getCellEditor : function(colIndex, rowIndex){
var p = this.store.getProperty(rowIndex);
var n = p.data['name'], val = p.data['value'];
if(p.data.field && typeof(p.data.field.editor) == 'object'){
return p.data.field.editor;
}
if(typeof(this.grid.customEditors) == 'function'){
return this.grid.customEditors(n);
}
if(Ext.isDate(val)){
return this.editors['date'];
}else if(typeof val == 'number'){
return this.editors['number'];
}else if(typeof val == 'boolean'){
return this.editors['boolean'];
}else{
return this.editors['string'];
}
}
});
/**
* @class Ext.grid.PropertyGrid
* @extends Ext.grid.EditorGridPanel
* A specialized grid implementation intended to mimic the traditional property grid as typically seen in
* development IDEs. Each row in the grid represents a property of some object, and the data is stored
* as a set of name/value pairs in {@link Ext.grid.PropertyRecord}s. Example usage:
* <pre><code>
var grid = new Ext.grid.PropertyGrid({
title: 'Properties Grid',
autoHeight: true,
width: 300,
renderTo: 'grid-ct',
source: {
"(name)": "My Object",
"Created": new Date(Date.parse('10/15/2006')),
"Available": false,
"Version": .01,
"Description": "A test object"
}
});
</pre></code>
* @constructor
* @param {Object} config The grid config object
*/
Ext.ux.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
/**
* @cfg {Object} source A data object to use as the data source of the grid (see {@link #setSource} for details).
*/
/**
* @cfg {Object} customEditors An object containing name/value pairs of custom editor type definitions that allow
* the grid to support additional types of editable fields. By default, the grid supports strongly-typed editing
* of strings, dates, numbers and booleans using built-in form editors, but any custom type can be supported and
* associated with a custom input control by specifying a custom editor. The name of the editor
* type should correspond with the name of the property that will use the editor. Example usage:
* <pre><code>
var grid = new Ext.grid.PropertyGrid({
...
customEditors: {
'Start Time': new Ext.grid.GridEditor(new Ext.form.TimeField({selectOnFocus:true}))
},
source: {
'Start Time': '10:00 AM'
}
});
</code></pre>
*/
// private config overrides
enableColumnMove:false,
stripeRows:false,
trackMouseOver: false,
clicksToEdit:1,
enableHdMenu : false,
editable: true,
nameWidth: 50,
valueWidth: 50,
source: {},
autoExpandColumn: 'value',
// private
initComponent : function(){
this.customEditors = this.customEditors || {};
this.lastEditRow = null;
var store = new Ext.ux.grid.PropertyStore(this);
this.propStore = store;
var cm = new Ext.ux.grid.PropertyColumnModel(this, store);
store.store.sort('name', 'ASC');
this.addEvents(
/**
* @event beforepropertychange
* Fires before a property value changes. Handlers can return false to cancel the property change
* (this will internally call {@link Ext.data.Record#reject} on the property's record).
* @param {Object} source The source data object for the grid (corresponds to the same object passed in
* as the {@link #source} config property).
* @param {String} recordId The record's id in the data store
* @param {Mixed} value The current edited property value
* @param {Mixed} oldValue The original property value prior to editing
*/
'beforepropertychange',
/**
* @event propertychange
* Fires after a property value has changed.
* @param {Object} source The source data object for the grid (corresponds to the same object passed in
* as the {@link #source} config property).
* @param {String} recordId The record's id in the data store
* @param {Mixed} value The current edited property value
* @param {Mixed} oldValue The original property value prior to editing
*/
'propertychange'
);
this.cm = cm;
this.ds = store.store;
Ext.ux.grid.PropertyGrid.superclass.initComponent.call(this);
this.selModel.on('beforecellselect', function(sm, rowIndex, colIndex){
if(colIndex === 0){
this.startEditing.defer(200, this, [rowIndex, 1]);
return false;
}
}, this);
if (!this.editable){
this.on('beforeedit', function(){return false})
}
},
// private
onRender : function(){
Ext.ux.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
this.getGridEl().addClass('x-props-grid');
},
// private
afterRender: function(){
Ext.ux.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
if(this.source){
this.setSource(this.source);
}
},
/**
* Sets the source data object containing the property data. The data object can contain one or more name/value
* pairs representing all of the properties of an object to display in the grid, and this data will automatically
* be loaded into the grid's {@link #store}. The values should be supplied in the proper data type if needed,
* otherwise string type will be assumed. If the grid already contains data, this method will replace any
* existing data. See also the {@link #source} config value. Example usage:
* <pre><code>
grid.setSource({
"(name)": "My Object",
"Created": new Date(Date.parse('10/15/2006')), // date type
"Available": false, // boolean type
"Version": .01, // decimal type
"Description": "A test object"
});
</code></pre>
* @param {Object} source The data object
*/
setSource : function(source){
this.propStore.setSource(source,this.fields);
},
/**
* Loads a data object. Equivalent to setSource()
*/
load : function(source){
this.setSource(source);
},
/**
* Loads an Ext.Record as the source data object
*/
loadRecord : function(record) {
record.data && this.setSource(record.data);
},
/**
* Gets the source data object containing the property data. See {@link #setSource} for details regarding the
* format of the data object.
* @return {Object} The data object
*/
getSource : function(){
return this.propStore.getSource();
}
});
Ext.reg("propertygrid2", Ext.ux.grid.PropertyGrid);
-
16 Jul 2008 8:27 AM #2
Great Job on Improved Property Grid!
Great Job on Improved Property Grid!
This appears to be exactly what I need. I'm integrating it now into my application. This is much more intuitive!
I have a master detail scenario. The property grid is the detail for the primary grid. Select a row in the primary grid and the content of the property grid changes. Sometimes the property grid has to show read only values. In this case, I'm individually setting the editability of the rows like this:
I found that I had to add the following to your PropertyGrid:Code:cm.setEditable(1, false);
Setting a grid to disabled results in an ugly gray panel. It would be nice if there was a method on the propertyGrid setReadOnly(boolean) which would set the whole grid to readonly and when you set it back to editable, the grid remembers the rows that are never editable. But that's just a nicety that isn't found in the original either.Code:/** * Sets the second column's (value column) editable property. */ setEditable: function(rowIndex, editable) { var p = this.store.getProperty(rowIndex); if(p.data.field) p.data.field.editable = editable; },
So thanks for the contribution!
-
16 Jul 2008 9:25 AM #3
Good idea with all of that.
As I hinted at in the original post, I started borrowing things from formPanel as well, and it may make sense to bring even more over. In the end it seems even more intuitive to think of a propertyGrid as just a form that has been rendered differently.
My grid does already have an 'editable' config option, it really wouldnt take much to add methods to control this after render. This property is already implemented differently than the field 'editable' config, so changing its status would not affect the individual field statuses.
-
11 Sep 2008 3:05 PM #4
I came across this older thread and am just passing the reference along:
http://extjs.com/forum/showthread.ph...818#post136818
I don't know what your version or the linked one does or does not do. Hopefully more people will add to the repository so it's easier to find all these resources.
MJ
API Search || Ext 3: docs-demo-upgrade guide || User Extension Repository
Frequently Asked Questions: FAQs
Tutorial: Grid (php/mysql/json) , Application Design and Structure || Extensions: MetaGrid, MessageWindow
-
12 Sep 2008 9:41 AM #5
Quite simply mine is just an attempt to make it behave more like a normal grid due to confusion on my part when I first started using it. Hopefully this allows people that are familiar with normal grids to use that experience when it comes to the property grid.
And yeah, was kinda waiting for the repository thing to mature, and I think it is at that point now so I should get my stuff put in there
-
28 Oct 2008 4:09 AM #6
To make the entire grid read only :-
To make the entire grid read only :-
Nice...
I know this is an old posting, however, I have found that to make the entire 'out of the box' PropertyGrid read only all you need to do is just cancel the onClick event :-
This works with 2.1 and 2.2 versionCode:onClick:function(e){ e.cancel = true; return false; },
-
4 Nov 2008 7:02 AM #7
Just want to say that this is a pretty nice extension.
-
5 Nov 2008 1:10 AM #8
I had to make a little change in the setSource method, without that change the TextFields are initialized with
Code:data.push(new Ext.grid.PropertyRecord({ name: k.dataIndex, value: o[k.dataIndex]||"", header: k.header, field: k }, k.id));
-
24 Nov 2008 12:37 PM #9
Anyone managed to use a checkboxgroup in this improved propertyGrid or the vanilla one? Can't think of the best way to present it? Maybe a multi-select combo would be the best approach as it wouldn't interfere with the UI? I have various bitwise fields in my DB for storing options but this single field needs to be rendered/edited as a multi-field list of sorts. Anyone have any experience in this area or ideas?
Just realised Saki's LOVCombo would fit nicely with this. Would still welcome other suggestions/thoughts.Last edited by Remy; 24 Nov 2008 at 12:42 PM. Reason: Update on Saki's UX
-
25 Nov 2008 11:50 AM #10
I'm trying to integrate Saki's LOVCombo with this and am hitting a wall, I have dropped down to a standard combo to see if I can resolve it.
I have the editor set to combo and the store retrieves the records and properly highlights the selected item when the combo is selected but I can't figure out how to get the displayField working properly. The field itself always displays the value that is selected. Is this because the combo is the 'editor' but I need something else as the renderer?
I am using the remoteComponent plugin to retrieve the following JSON which instantiates my propertyGrid:
Any help is appreciated.Code:[ { xtype: 'propertygrid2', id: 'propGrid', autoHeight: true, autoWidth: true, fields : [ { id: 'dd_id', dataIndex: 'dd_id', header: 'ID', editable: true, editor: new Ext.grid.GridEditor(new Ext.form.NumberField({ selectOnFocus: true, style: 'text-align: left;' })) }, { id: 'dd_table', dataIndex: 'dd_table', header: 'Table', editable: true }, { id: 'dd_field_id', dataIndex: 'dd_field_id', header: 'Field ID', editable: true }, { id: 'dd_Desc', dataIndex: 'dd_Desc', header: 'Description', editable: true }, { id: 'dd_Width', dataIndex: 'dd_Width', header: 'Field width', editable: true }, { id: 'dd_lookup_field', dataIndex: 'dd_lookup_field', header: 'Lookup ID', editable: true }, { id: 'dd_lookup_display', dataIndex: 'dd_lookup_display', header: 'Lookup Display', editable: true }, { id: 'combodd_password', dataIndex: 'dd_password', header: 'Password', editable: true, editor: new Ext.grid.GridEditor(new Ext.form.NumberField({ selectOnFocus: true, style: 'text-align: left;' })) }, { id: 'dd_default_value', dataIndex: 'dd_default_value', header: 'Default Value', editable: true }, { id: 'dd_validation', dataIndex: 'dd_validation', header: 'Validation Code', editable: true }, { id: 'dd_ValDesc', dataIndex: 'dd_ValDesc', header: 'Validation Desc.', editable: true }, { id: 'combodd_method', dataIndex: 'dd_method', header: 'Method', editable: true, editor: new Ext.grid.GridEditor(new Ext.form.NumberField({ selectOnFocus: true, style: 'text-align: left;' })) }, { id: 'combodd_view', dataIndex: 'dd_view', header: 'View Perm', editable: true, editor: new Ext.grid.GridEditor(new Ext.form.ComboBox({ id: 'lovdd_view', store: new Ext.data.JsonStore({ id: 'lovdd_view', autoLoad: true, mode: 'remote', baseParams: { table: 'DataPermissions', primaryKey: 'dd_field_id', lookupSourceField: 'dd_view', lookupSourceFieldValue: '63', lookupField: 'dp_id', lookupValue: 'dp_desc', readOnly: 'false' }, url: 'ajax/FieldLookupList.asp', root: 'rows', fields: [ { name: 'dp_id', mapping: 'dp_id' }, { name: 'LookupDisplay' } ] }), listeners: { render: { single: true, fn: function(combo) { combo.store.on('load', function() { combo.setValue(63) }, { single: true });combo.store.load(); } } }, displayField: 'LookupDisplay', valueField: 'dp_id', hideOnSelect: false, triggerAction: 'all', hiddenName: 'dd_view' })) }, { id: 'combodd_add', dataIndex: 'dd_add', header: 'Add Perm', editable: true, editor: new Ext.grid.GridEditor(new Ext.form.ComboBox({ id: 'lovdd_add', store: new Ext.data.JsonStore({ id: 'lovdd_add', autoLoad: true, mode: 'remote', baseParams: { table: 'DataPermissions', primaryKey: 'dd_field_id', lookupSourceField: 'dd_add', lookupSourceFieldValue: '63', lookupField: 'dp_id', lookupValue: 'dp_desc', readOnly: 'false' }, url: 'ajax/FieldLookupList.asp', root: 'rows', fields: [ { name: 'dp_id', mapping: 'dp_id' }, { name: 'LookupDisplay' } ] }), listeners: { render: { single: true, fn: function(combo) { combo.store.on('load', function() { combo.setValue(63) }, { single: true });combo.store.load(); } } }, displayField: 'LookupDisplay', valueField: 'dp_id', hideOnSelect: false, triggerAction: 'all', hiddenName: 'dd_add' })) }, { id: 'combodd_mod', dataIndex: 'dd_mod', header: 'Mod Perm', editable: true, editor: new Ext.grid.GridEditor(new Ext.form.ComboBox({ id: 'lovdd_mod', store: new Ext.data.JsonStore({ id: 'lovdd_mod', autoLoad: true, mode: 'remote', baseParams: { table: 'DataPermissions', primaryKey: 'dd_field_id', lookupSourceField: 'dd_mod', lookupSourceFieldValue: '63', lookupField: 'dp_id', lookupValue: 'dp_desc', readOnly: 'false' }, url: 'ajax/FieldLookupList.asp', root: 'rows', fields: [ { name: 'dp_id', mapping: 'dp_id' }, { name: 'LookupDisplay' } ] }), listeners: { render: { single: true, fn: function(combo) { combo.store.on('load', function() { combo.setValue(63) }, { single: true });combo.store.load(); } } }, displayField: 'LookupDisplay', valueField: 'dp_id', hideOnSelect: false, triggerAction: 'all', hiddenName: 'dd_mod' })) }, { id: 'combodd_del', dataIndex: 'dd_del', header: 'Del Perm', editable: true, editor: new Ext.grid.GridEditor(new Ext.form.ComboBox({ id: 'lovdd_del', store: new Ext.data.JsonStore({ id: 'lovdd_del', autoLoad: true, mode: 'remote', baseParams: { table: 'DataPermissions', primaryKey: 'dd_field_id', lookupSourceField: 'dd_del', lookupSourceFieldValue: '63', lookupField: 'dp_id', lookupValue: 'dp_desc', readOnly: 'false' }, url: 'ajax/FieldLookupList.asp', root: 'rows', fields: [ { name: 'dp_id', mapping: 'dp_id' }, { name: 'LookupDisplay' } ] }), listeners: { render: { single: true, fn: function(combo) { combo.store.on('load', function() { combo.setValue(63) }, { single: true });combo.store.load(); } } }, displayField: 'LookupDisplay', valueField: 'dp_id', hideOnSelect: false, triggerAction: 'all', hiddenName: 'dd_del' })) }, { id: 'combodd_Report', dataIndex: 'dd_Report', header: 'Report', editable: true, editor: new Ext.grid.GridEditor(new Ext.form.ComboBox({ id: 'lovdd_Report', store: new Ext.data.JsonStore({ id: 'lovdd_Report', autoLoad: true, mode: 'remote', baseParams: { table: 'DataPermissions', primaryKey: 'dd_field_id', lookupSourceField: 'dd_Report', lookupSourceFieldValue: '63', lookupField: 'dp_id', lookupValue: 'dp_desc', readOnly: 'false' }, url: 'ajax/FieldLookupList.asp', root: 'rows', fields: [ { name: 'dp_id', mapping: 'dp_id' }, { name: 'LookupDisplay' } ] }), listeners: { render: { single: true, fn: function(combo) { combo.store.on('load', function() { combo.setValue(63) }, { single: true });combo.store.load(); } } }, displayField: 'LookupDisplay', valueField: 'dp_id', hideOnSelect: false, triggerAction: 'all', hiddenName: 'dd_Report' })) }, { id: 'dd_Report_XRef', dataIndex: 'dd_Report_XRef', header: 'Report Xref', editable: true }, { id: 'dd_Lookup_XRef', dataIndex: 'dd_Lookup_XRef', header: 'Lookup XRef', editable: true }, { id: 'combodd_Xref_Join', dataIndex: 'dd_Xref_Join', header: 'Xref Data Join', editable: true, editor: new Ext.grid.GridEditor(new Ext.form.NumberField({ selectOnFocus: true, style: 'text-align: left;' })) }, { id: 'dd_Xref2', dataIndex: 'dd_Xref2', header: 'Xref2', editable: true }, { id: 'dd_Linked_Field', dataIndex: 'dd_Linked_Field', header: 'Linked Field', editable: true } ], source: { } } ]


Reply With Quote