Wednesday, October 03, 2012

Using comboboxes in an ExtJS PropertyGrid

When viewing/editing a database record in a PropertyGrid, you often encounter integer-foreign-keys referring to other tables containing lookup-labels. In the propertygrid you would want to display the lookup-label in stead of the integer. You could get the label with a json-ajax-request, but since you might need these values multiple time It's probaly better to have them cache in an ArrayStore.

var store = new Ext.data.ArrayStore({
fields: ["id", "label"],
data :  {"lookup":[[1,"blue"],[2,"red"],[3,"green"],[4,"yellow"]]}
});
Now you can reference the correct label from the ArrayStore in the customRenderer configuration of the PropertyGrid (ExtJS 3.4 implementation http://dev.sencha.com/deploy/ext-3.4.0).
 new ext.grid.PropertyGrid({
                            customRenderers: {
                                  //get the lookup label
                                'color': function(v){ return getLookup(store,v) }
                            },
                            propertyNames: {
                                'color':'Couleur' //set a localised property header
                            },
                            source: aRecordStore.record[0].data
                        })
function getLookup(store,id){
           if (store.find('id',id)==-1) return "-";
           else return store.getAt(store.find('id',id)).get('label');
}

Using a store here to retrieve a single label is not very optimal, but the store will come in handy when you want to edit the propertygrid. In the case of the foreign key, you would want to present the user with a dropdown (combobox) of available values:

new ext.grid.PropertyGrid({
                            customRenderers: {
                                'color': function(v){ return getLookup(store,v) } //get the lookup label
                            },
                            customEditors: {
                                //you don't want people to edit the id-field
                                'id': new Ext.grid.GridEditor(new Ext.form.TextField ({disabled : true})),
                                //get a combobox editor filled with lookup values to edit the color field
                               'color': new Ext.grid.GridEditor(new Ext.form.ComboBox({
                        store: store,
                    mode: 'local',
                    forceSelection: true,
                    triggerAction: 'all',
                    editable: false,
                    valueField: 'id',
                    displayField: 'label',
                }
            )
        ),
                            propertyNames: {
                                'color':'Couleur' //set a localised property header
                            },
                            source: aRecordStore.record[0].data
                        })

In case you want people to only be able to edit the propertygrid when a certain condition is met (is authenticated/edit button has been activated), use the beforeedit event:

listeners: {"beforeedit": function() {
                if(!readOnly) {
                    return true;
                } else {
                    return false;
                }
            }
}

No comments: