EXT remote-loading forms with Combo boxes
April 16, 2008 6 Comments
Something that’s harder than it should be is populating an EXT edit form with form data, where one of the form fields is a select box. If there is a specific set of values that this select can take, then you can hard code that using a SimpleStore, like this:
var exampledata = [['AL', 'Alabama'], ['AK', 'Alaska'], ['AZ', 'Arizona'], ['AR', 'Arkansas'], ['CA', 'California']]; var store = new Ext.data.SimpleStore({ fields: ['abbr', 'state'], data : exampleData }); var combo = new Ext.form.ComboBox({ store: store, displayField: 'state', valueField: 'abbr', ... etc ... }); form = new Ext.form({ items: [combo], ... etc ... }); form.load(url_to_load_from);
So that will populate the select box with the static values you’ve defined (the 5 states above), then when the form loads it will select the appropriate option automatically.
So far so good, but what if you need to load what goes into the select box dynamically? Well, first you’ll need to set up your remote data store (my server is sending back JSON data, hence the JsonReader):
store = new Ext.data.Store({ url: 'url_to_load_combo_data_from', reader: new Ext.data.JsonReader( {root: 'states',totalProperty: 'results'}, [ {name: 'name', type: 'string', mapping: 'state.name'}, {name: 'abbr', type: 'string', mapping: 'state.abbr'} ] ) });
This will consume data like this:
{ "states": [ {"state": {"name": "Alabama", "abbr": "AL"}}, {"state": {"name": "Alaska", "abbr": "AK"}} ], "results": "2" }
And populate the store with a collection of state records which can then be loaded into the combobox.
Then all you need to do is load the store before loading the form data, and your comboboxes will be correctly populated, displaying the correct option. Here’s the full example:
store = new Ext.data.Store({ url: 'url_to_load_combo_data_from', reader: new Ext.data.JsonReader( {root: 'states',totalProperty: 'results'}, [ {name: 'name', type: 'string', mapping: 'state.name'}, {name: 'abbr', type: 'string', mapping: 'state.abbr'} ] ) }); var combo = new Ext.form.ComboBox({ store: store, displayField: 'state', valueField: 'abbr' ... etc ... }); form = new Ext.formPanel({ items: [combo] }); store.load(); form.load(your_form_data_url);
Be wary using the pagination options on the combobox here (see http://extjs.com/deploy/dev/docs/?class=Ext.form.ComboBox) – the reason being if your state’s ‘abbr’ features on the second page of the results it won’t populate the correct options into the combo box.
Thank you, it was help me a lot!
It’s worthwhile to note that the Rails 2 (mis)feature of including the model name in each instance of the collection is enabled in this example.With the feature disabled, which was the default before Rails 2 for newly created applications, the mapping would not need the “state.” portion.
Aren’t you going to run into a race condition with this? The load() methods of these are async requests which means the form’s values may have loaded before the combobox’s store does.I’m facing the same problem right now. 🙂
Bad example!
You can’t be sure if the combo will be async’ loaded BEFORE the async load of the form!
Please present us a better solution! 🙂
try using the callback argument on store.load
to call form.load after finish load the store
it’ll solve
That does appear to be a poor solution due to the race condition.
To work around this issue, I’ve added a ‘load’ event to my combo’s store, that forces the value to be updated;
this.store = new Ext.data.JsonStore({
…
listeners: {
load: function(){
this.setValue(this.value);
}
}
}