Tips and tricks for LAMP (Linux Apache MySQL PHP) developers.

When I cant find a suitable solution to a problem and have to work it out for myself I'll post the result here so hopefully others will find it useful. (All code is offered in good faith. It may not be the best solution, just a solution).

Wednesday, 9 April 2008

Creating a basic select box in ExtJS


I'm currently working on a project that involves generating an entirely ExtJS-based interface from PHP code.

I needed to be able to produce in ExtJS the equivelent of a standard HTML <select> box. This can be achieved with a ComboBox, however, it seems that ComboBoxes are heavily geared towards doing lots of clever things like loading in options over AJAX, allowing the user to type in their own options, auto-completing typed in options, etc. That's all great but if all you want is a standard drop-down with a predefined set of options it takes a bit of work.

I incorrectly assumed that something like the following would work:

obj_combo = new Ext.form.ComboBox({
 name: 'countries',
 items: [
  {value: '1', text: 'UK'},
  {value: '2', text: 'US'},
// ...
]
});

Unfortunaltey, it's not that simple.

Here's an example of the actual code required:
obj_combo = new Ext.form.ComboBox({
 name: 'countries',
// Stop users being able to type in the combobox
 editable: false,
// Even though the user cant type any more
// once they select one option it'll remove any
// others that don't start with the same letters
// unless we turn off filtering

 disableKeyFilter: true,
// Only allow users to pick an option that exists
// in the list of options (not one of their own)

 forceSelection: true,
// This isn't entirely necessary but the combox
// will start off blank otherwise

 emptyText: '--select one--',
// This one's vital: when the user clicks on the
// drop-down show ALL options

 triggerAction: 'all',
// By default it retrieves remote data,
// we're using local data

 mode: 'local',
// ComboBox will only accept data from a Store
// so we have to create a basic one

 store: new Ext.data.SimpleStore({
  id: 0,
  fields: ['value', 'text'],
  data : [['1', 'UK'], ['2', 'US']]
 }),
// Specify which fields in the store hold
// the value and the display text

 valueField: 'value',
 displayField: 'text',
// Important: by default the POST/GET data
// for this item will contain the display text
// not the value. This option creates a hidden field
// with the same name as the dropdown containing the
// selected value so it is that which gets returned

 hiddenName: 'countries'
});

With all those set (plus any of your own) you should have the equivalent of an HTML select box in ExtJS.

For good examples of different ComboBoxes (but unfortunately little explanation of them) check this link:
http://extjs.com/deploy/ext/examples/form/combos.html

7 comments:

dreas said...

Thanks a lot for sharing your solution, this did help me a ton. ;)

Chris said...

Thank you very much. I was trying to accomplish this and every time some other thing bit me in the ass. Should be a standard class, maybe with default settings? Ether way thanks a lot for your invaluable help.

Stephen Liberty said...

I could almost kiss you for the 'triggerAction' part. I've been working on this freaking drop down for almost four hours now.. you just saved my computer from being thrown out the window! One quick comment - the store can just be set to:

store: [['1', 'UK'], ['2', 'US']] and extjs will figure out that the first element in the array is the hidden value and the second one is the display value.

brenda said...

But I could not use the keyboard to navigate. Type a letter to jump to and select the first matching result. Press that same key to find the next match..etc does not work

Lilchef said...

Thanks everyone!
@Brenda: good point. If you turn 'disableKeyFilter' off that can be used to reduce the options down to ones that match what you type.

Anonymous said...

Thanks a bundle,
this is exactly why I love to hate ExtJs,..

Anonymous said...

The devil is in the detail.

Many thanks for telling me about

triggerAction: 'all'