PDA

View Full Version : How to set a default value for an Ext ComboBox



jon.whitcraft
4 Apr 2007, 11:49 AM
Currently i have this which loads the combo box when clicked.



var selReader = new Ext.data.JsonReader({
id: 'series_id'
}, [ 'series_id', 'series_name']);

var selDS = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: './ajax/getSeries.php'
}),
reader: selReader,
remoteSort: false
});

this.select = new Ext.form.ComboBox({
store: selDS,
value: 'Select Series',
displayField : 'series_name',
valueField: 'series_id'
});

this.select.render('seriesSelect');


but say i want to set the default value of the combo box to one of the items that is in the list. how would i go about doing it?

Thanks!!

tryanDLS
4 Apr 2007, 12:28 PM
try

this.select.setValue(value); where value is a value in the series_id col. That sets the value - it may not select the item in the dropdown. There's also selectByValue(value, scrollIntoView) and select(index, scrollIntoView)

jon.whitcraft
4 Apr 2007, 1:43 PM
try

this.select.setValue(value); where value is a value in the series_id col. That sets the value - it may not select the item in the dropdown. There's also selectByValue(value, scrollIntoView) and select(index, scrollIntoView)
Tim,

That works and it doesn't work. It puts the value in the field but doesnt allow me to specify the option value and the display value.

I want to be able to set the combo box to display IndyCar Series but the actually value to 1, so when i call sel.getValue() it should return 1 not IndyCar Series.

does that make sense??

tryanDLS
4 Apr 2007, 2:44 PM
I just tried this in the combo example.


var combo = new Ext.form.ComboBox({
store: store,
displayField:'state',
valueField:'abbr', <-- added this
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Select a state...',
selectOnFocus:true
});
combo.applyTo('local-states');

combo.selectByValue('CA', true); // this displays California in the field
// and California is highlighted when the select is expanded
var val = combo.getValue(); // returns CA

jon.whitcraft
4 Apr 2007, 6:37 PM
Tim.

Thanks. I'll try that when I get to work tomorrow.

Jon

jon.whitcraft
5 Apr 2007, 4:09 AM
Tim,

That doesn't work when you are loading a dynamic record set. I have modified my tool not not need me to set it when it's a dynamic loading combo box. I'll figure this out later.

Thanks for the help.

VinylFox
18 Apr 2007, 4:35 AM
Jon, did you find a solution to this?

jon.whitcraft
18 Apr 2007, 5:21 AM
kinda...i'll have to revisit it once i go and test on 1.0 (no time to upgrade off beta 2 svn).

Wolfgang
18 Apr 2007, 2:34 PM
I just tried this in the combo example.


...
combo.applyTo('local-states');

combo.selectByValue('CA', true); // this displays California in the field
// and California is highlighted when the select is expanded
var val = combo.getValue(); // returns CA


I gave this a try in Jon's example using the JSON data store.
The problem i faced:
Even i preloaded the store before creating the combobox, the combobox still has no data from the store available. So the item cannot be selected. Si i guess there is something missing...



// load the store on startup
// this works
selDs.load();

// build the combobox
var combo = new Ext.form.ComboBox({
store: selDs,
displayField : 'series_name',
valueField: 'series_id',
typeAhead: true,
triggerAction: 'all',
emptyText:'Select Series',
selectOnFocus:true
});

// nothing happens in both cases. the combobox has no data yet. the store has though.
combo.selectByValue('1', true); // 1 is a valid series_id
//combo.selectByValue(1, true); // 1 is a valid series_id

// still returns 'Select Series'
var val = combo.getValue();

VinylFox
18 Apr 2007, 2:45 PM
Just an fyi, we have two running posts on this. The other one is here (http://www.extjs.com/forum/showthread.php?t=4551).

oregontarheel
18 Apr 2007, 2:49 PM
I recently had this same problem - and I was able to get it to work by adding an event handler to the store. Something like this may work:



selDS.on('load', select.setValue(someVal));


The example I just gave is going to have some scope issues, I'm not sure exactly the best way to handle it, you can probably pass a scope as one of the options, but I'm still learning how to handle all that. In my application I am using a singleton object called App (similar to how examples use Example) which contains a drop menu and i just say App.select(setValue(someVal)), but this may not work in your case.

Please let me know if that helps at all, or if I'm way off target here, I'm just learning Ext and some of these JS concepts...

VinylFox
18 Apr 2007, 6:16 PM
I was not able to get this method to work either, i think it might have to do with the point at which im rendering my form and loading data into my data store? Do you have a complete example that I could take a peek at?

oregontarheel
18 Apr 2007, 11:21 PM
Here's the relevant parts of my code. Again this comes with the disclaimer that I may or may not know what I'm doing... so take this with a grain of salt, although I have recently solved what I think to be the same problem you are having.



var DataManager = function(){
return {
init : function(){
DataManager.buildMailboxStore();
},

buildMailboxStore : function(){
this.mailbox_store = new Ext.data.Store({
// load using HTTP
proxy: new Ext.data.HttpProxy({
url: [json-provider url goes here]
}),
reader: new Ext.data.JsonReader({
root:"mailboxes",
id:"id"
},
['mailUser','id','address'])
});
this.mailbox_store.load();
this.mailbox_store.on('load', function(){
EmailCenter.sidebar_mailbox_menu.setValue([set the value here]);
});
}
}
}

var EmailCenter = function(){
return {
init : function(){
this.sidebar_mailbox_menu = new Ext.form.ComboBox({
store: DataManager.mailbox_store,
valueField:'id',
displayField:'mailUser',
typeAhead: true,
mode: 'local',
triggerAction: 'all',
emptyText:'Select a mailbox...',
forceSelection: true,
selectOnFocus:true
});
this.sidebar_mailbox_menu.applyTo('mailbox');
}
}
}

Ext.EventManager.onDocumentReady(DataManager.init, DataManager, true);
Ext.EventManager.onDocumentReady(EmailCenter.init, EmailCenter, true);



That should be all the code that is needed to get this working, minus a base HTML framework with the appropriate container element (div with id of mailbox) set up. If it is incomplete, I apologize, it's probably too late and definitely too many beers deep to be posting... although this should get you on the right track. good luck. and if anyone has any issues with the way I'm doing things please let me know, because I'm very new to this whole world. Thanks!

Wolfgang
19 Apr 2007, 3:14 AM
I was not able to get this method to work either, i think it might have to do with the point at which im rendering my form and loading data into my data store? Do you have a complete example that I could take a peek at?

When using a form, first you need to render the form (which renders the combobox). If you do not do this, then the combo does not exist and cannot be set to any value.
This works for me.
-Render form
-Attach handler to load event
-Initiate load.




...
simple.render('form-ct');

// select combobox2 defaultvalue on startup
// load the store on startup
selDS.on('load', comboBox2.setValue('val-2', true));
selDS.load();
...

Although this works for i get this error:


l.fireFn has no properties
fire()ext-all-debug.js (line 1421)
fireEvent()ext-all-debug.js (line 1231)
loadRecords(Object success=true records=[2] totalRecords=2, Object, true)ext-all-debug.js (line 9632)
loadResponse(Object params=Object request=Object reader=Object, true, Object tId=1 status=200 statusText=OK)ext-all-debug.js (line 10052)
handleResponse(Object tId=1 status=200 statusText=OK)ext-all-debug.js (line 9849)
setProgId(Object conn=XMLHttpRequest tId=1, Object scope=Object argument=Object timeout=30000, undefined)

VinylFox
19 Apr 2007, 6:08 AM
wolfgand, I was also getting that error.

This is what I did to stop the error from happening...and coincidently, it made this problem ive been having go away and I am now receiving the correct value and display value on my ComboBox :)



fs.render('combobox');

ds_random_employee_data_active.on('load', function(){
random_employees_active.setValue(14);
});
ds_random_employee_data_active.load();


I have posted the working code back to my example page
(http://www.vinylfox.com/extjs/examples/forms-combobox-datastore/forms-combobox-datastore-working.php)
oregontarheel, thank you for posting your code and sending us in the right direction, its much appreciated.

jon.whitcraft
19 Apr 2007, 6:21 AM
Nice job guys but should we have to to bind an event to the load function? to me that seems backwards and an extra step to me. the one issues i see with the code though is that every time you run the load now it will select the item with value of 14.

in therory wouldn't you want to do this



ds_random_employee_data_active.on('load', function(){
random_employee_active.setValue(14);
}, this, {single: true});


that way it runs only once and you don't have to deal with it past that.

just an thought...

Wolfgang
19 Apr 2007, 7:02 AM
Nice job guys but should we have to to bind an event to the load function? to me that seems backwards and an extra step to me. the one issues i see with the code though is that every time you run the load now it will select the item with value of 14.

You are right. I saw this, too.
However, first thing was to get the value assigned.

Your idea using the new syntax for eventhandler to create a single event looks good and i am sure it will work.
In general however, I still hope there is another way to accomplish the inital value assignment, for example as a config option in the combobox.

jon.whitcraft
19 Apr 2007, 7:11 AM
What I think should happen is if you call cb.setValue('14') and it's tied to a DataStore it should run the ds.load() and then select the value when it's finished with the load, much like we are doing it now but so you only have to call this



cb.setValue('14');


instead of this:



ds_random_employee_data_active.on('load', function(){
random_employee_active.setValue(14);
}, this, {single: true});
ds_random_employee_data_active.load();


I'm not sure of jacks stance on doing it this way but I think it should be done.

I don't think that parameter when you create the the object but that's just my option.

oregontarheel
19 Apr 2007, 8:18 AM
I agree that using an event handler is not the best idea in most cases, because you don't always want it to be set to that value on load. in my case, the load value is not static, but a variable determined by another portion of my application which needs to be set each time the data store behind the combo box is reloaded, so it works in my case. great discussion though, i am really enjoying this forum, I have learned a lot from you guys in the past week...

Wolfgang
19 Apr 2007, 8:55 AM
What I think should happen is if you call cb.setValue('14') and it's tied to a DataStore it should run the ds.load() and then select the value when it's finished with the load, much like we are doing it now but so you only have to call this



cb.setValue('14');



Yes this would make sense. However, this would mean that each "setvalue()" call would also cause a load of the datastore, which might not be desired.
...:-?
Thinking more about it we have the following scenarios:
1.) Assign a value on startup. This certainly requires an initial load of the datastore.
2.) Assign a value at runtime with a request to update the datastore. So calling "ds.load()"
3.) Assign a value at runtime without a request to update the datastore. So not calling "ds.load()".

Since 2.) and 3.) are quite similar, i think the idea of the config option to support 1.) is not to bad. This way, 2.) and 3.) are up to the developer.

Regards

Wolfgang

jon.whitcraft
19 Apr 2007, 8:58 AM
Nice point Wolfgang. I didn't think of it like that.

Reputation++

VinylFox
19 Apr 2007, 9:14 AM
Yes this would make sense. However, this would mean that each "setvalue()" call would also cause a load of the datastore, which might not be desired.
...:-?

The data store is loaded each time you select the ComboBox, so it seems like loading the data each time you set the value would be logical behavior as well. With that said, I agree that it would be nice to have a config option that prevented this behavior.

So now all we need is for Jack to get wind of this. :) or possibly a Premium member to request it.

jon.whitcraft
19 Apr 2007, 9:17 AM
So now all we need is for Jack to get wind of this.

I can point him in this general direction. ;)

Wolfgang
19 Apr 2007, 11:50 AM
Just a note:


The data store is loaded each time you select the ComboBox, so it seems like loading the data each time you set the value would be logical behavior as well.
...

The combobox uses it own internal simpleStore (which is loaded via the attached external store). Given that it works as you said, the question would be if this behaviour should also be adjustable.
For example, if a combobox pulls nearly static data from a server (maybe because it is static in the scope of the current session), why should it then pull again and again data upon each selection?

jon.whitcraft
19 Apr 2007, 11:59 AM
Just a note:


The combobox uses it own internal simpleStore (which is loaded via the attached external store). Given that it works as you said, the question would be if this behaviour should also be adjustable.
For example, if a combobox pulls nearly static data from a server (maybe because it is static in the scope of the current session), why should it then pull again and again data upon each selection?
i do agree. i think it would be cool if once i loaded the box it switched to local mode.

Wolfgang
19 Apr 2007, 2:32 PM
I can point him in this general direction. ;)

Jon, thanks in advance :)

jon.whitcraft
19 Apr 2007, 4:36 PM
Jack came though again.

check out his first post on this thread

http://extjs.com/forum/showthread.php?t=3561

it explains a lot.


VinylFox: Jack said that would make a great tutorial ;)

Wolfgang
19 Apr 2007, 8:44 PM
Thanks for the link.
I made some further testing. What it comes down to is similar to what Jack said in that thread.
Even when calling a ds.load() upfront, at that time the store available to the combobox is empty. I thought one reason might have been the asnychrones nature of ajax calls.
So i tried a simpleStore instead - and it worked.

Then i tried the callback single shot workaround on the combobox using simpleStore:


// both are equviliant
//selDs.on('load', function() {comboBox2.setValue('val-1');}, this, {single: true});
//selDs.load();
comboBox2.store.on('load', function() {comboBox2.setValue('val-1');}, this, {single: true});
comboBox2.store.load();

... and got an error


this.el has no properties
setValue("Alabama")ext-all-debug.js (line 19973)
setValue("AL")ext-all-debug.js (line 20874)
(no name)()simpleForms.js (line 196)
createSingle()ext-all-debug.js (line 1336)
fire()ext-all-debug.js (line 1421)
fireEvent()ext-all-debug.js (line 1231)
loadRecords(Object records=[3] totalRecords=3, Object, true)ext-all-debug.js (line 9632)
load(Object, Object meta=Object, function(), Object data=[3] baseParams=Object paramNames=Object, Object)ext-all-debug.js (line 9996)
load(Object)ext-all-debug.js (line 9597)
(no name)()simpleForms.js (line 197)
fire()ext-all-debug.js (line 1421)
fireDocReady()ext-all-debug.js (line 1450)
[Break on this error] this.el.removeClass(this.emptyClass);

As one can see, the data is there.
What happend?
Accidently, i placed the code for the single shot event (in particular the call to load() which triggers that event), before form.render(). Because my computer is fast and internet is slow, that worked for the XHR call. But the simpleStore is fast, so the form was not rendered and therefore also not the combobox and thats why there was no element.

So in summary:
-The one-shot event seems to be a reliable way to set presets to comboboxes that uses an store via the httpproxy etc. (so ones using XHR)
-The one-shot events (of cause) also work for simpleStore.
-When using a simpleStore, also this way


comboBox3.setValue('AL', true);
comboBox3.selectByValue('AL', true);

can be used.
(Note: because of a bug in Ext 1.0 you need to explicit call setValue() before selectByValue()
See: http://extjs.com/forum/showthread.php?t=4551)

-When using a combobox with a form, all of this must happen _after_ the form is rendered.
If it works for you with the one-shot-event on an XHR proxy before you render the form, then this is nothing but luck, because you can easily face the race condition, depending on the timing of the XHR and building the form.

Regards

Wolfgang

mschering
6 Jul 2007, 1:29 AM
This solution works but it's not so nice to load the entire dataset when this is not necessary.

Shouldn't we just have a setValue(id, text); function? This way no useless query of all items in a row has to be made.

mschering
6 Jul 2007, 2:06 AM
I found a way to manually set a text and value:


<input type="text" name="user-select" value="Merijn Schering" />


var userSelect = new Ext.form.ComboBox({
store: ds,
displayField:'name',
hiddenName:'user_id',
typeAhead: true,
valueField: 'id',
triggerAction: 'all',
emptyText:GOlang['strPleaseSelect'],
width: 240,
selectOnFocus:true
});
userSelect.applyTo('user-select');
Ext.get('user_id').set({'value': 1});

The trick is to use a different hiddenName field and manually set it with Ext.get.