30
votes

I'm migrating my application from ExtJs 3 to 4 version. I have several comboboxes at my formPanel, and previously I've used hiddenName and all that stuff to submit valueField instead of displayField.

All my adaptation works fine (value field IS submitting), but I can't set the default values for comboboxes, they are shown as empty after page load. Previously, I did that just with specifying the 'value' parameter in config. Is there any ideas how to fix that?

My code - Model and Store:

Ext.define('idNamePair', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'id', type: 'string'},
        {name: 'name',  type: 'string'}
    ]
});

var dirValuesStore = new Ext.data.Store({
    model: 'idNamePair',
    proxy: {
        type: 'ajax',
        url: '../filtervalues.json',
        reader: {
            type: 'json',
            root: 'dir'
        }
    },
    autoLoad: true
});

Combo config:

{
    triggerAction: 'all',
    id: 'dir_id',
    fieldLabel: 'Direction',
    queryMode: 'local',
    editable: false,
    xtype: 'combo',
    store : dirValuesStore,
    displayField:'name',
    valueField:'id',
    value: 'all',
    width: 250,
    forceSelection:true
}
9
Please post some sample code for us to take a look at the issue and a possible solution.onteria_
The question is precisely. There is no code required even if I don't know the answer cause I am still stuck in 3.xsra
I guess it is again a question of asynchronous loading of store and combo, because if store is defined inside combo - it works fine.BlackLine
I noticed the same problem too.Marko

9 Answers

23
votes

I had the same problem, afaik has to do with selectlist rendering before the items are added to the store. I tried the callback method mentioned above without any luck (guess it would have to be a callback on the selectlist rather than the store).

I added this line after adding items to the store and it works fine:

Ext.getCmp('selectList').setValue(store.getAt('0').get('id'));
13
votes

Adding loading: true to your store config will fix it. There seems to be a problem with autoLoad: true and forceSelection: true. This little hack will make your combobox believe the store is loading even if the load function hasn't been fired yet.

10
votes

The best way for doing this is that listen to afterrender event and then set the default value in the callback function.

See this code:

new Ext.form.field.ComboBox({
    //This is our default value in the combobox config
    defaultValue: 0,
    listeners: {
        //This event will fire when combobox rendered completely
        afterrender: function() {
           //So now we are going to set the combobox value here.
           //I just simply used my default value in the combobox definition but it's possible to query from combobox store also.
           //For example: store.getAt('0').get('id'); according to Brik's answer.
           this.setValue(this.defaultValue);    
        }
    }
});
5
votes

I noticed your Combo config has queryMode: 'local'. That value is intended for when your data is stored locally in an array. But your model is using an AJAX proxy. Could it be that this confuses Ext so it can't find the default value you're trying to set? Try removing queryMode so it defaults to the value of 'remote' (or set it explicitly.)

UPDATE: I was migrating my own app from Ext3 to 4 right after posting the above, and I ran into the exact same problem. I'm sure queryMode is part of it, but the main problem is that the combobox doesn't have the data needed yet at the time it's rendered. Setting value does give it a value but there's nothing in the data store yet to match it with, so the field appears blank. I discovered that the autoLoad property can also specify a callback function to be used when the data is loaded. Here's what you could do:

store: new Ext.data.Store({
    model: 'MyModel',
    autoLoad: {
        scope: this,
        callback: function() {
            var comboBox = Ext.getCmp("MyComboBoxId");
            var store = comboBox.store;

            // set the value of the comboBox here
            comboBox.setValue(blahBlahBlah);
        }
    }
    ...
})
4
votes

You can either put the logic directly into the callback, or set up a function to handle all stores.

var store1 = Ext.create('Ext.data.Store', {
    ...
    autoLoad: {
        callback: initData 
    }
});

var store2 = Ext.create('Ext.data.Store', {
    ...
    autoLoad: {
        callback: initData 
    }
});

var myComboStores = ['store1', 'store2']

function initData() {
    var loaded = true;
    Ext.each(myComboStores, function(storeId) {
        var store = Ext.StoreManager.lookup(storeId);
        if (store.isLoading()) {
            loaded = false;
        }
    }
    if(loaded) {
        // do stuff with the data
    }
}

=====================

For those reading, the value config/property on your 'combo' object should be set to some value so the combo box gets an initial value. You have already done this. The value 'all' also needs to be in your store before it'll set it as the default.

value: 'all'

Also, it's good practice to set a value for the valueField config, which you've done already. If you don't, the select listener won't get the correct value when calling combo.getValue().

1
votes

I bet this has to do with the time you (asynchronously) load the combobox, and the time you set the value of the combobox. To overcome this problem, simply do this:

Ext.define('idNamePair', {
    extend: 'Ext.data.Model',
    fields: [
        {name: 'id', type: 'string'},
        {name: 'name',  type: 'string'}
    ]
});

var dirValuesStore = new Ext.data.Store({
    model: 'idNamePair',
    proxy: {
        type: 'ajax',
        url: '../filtervalues.json',
        reader: {
            type: 'json',
            root: 'dir'
        }
    },
    autoLoad: false // set autoloading to false
});

Autoloading of the store is off. Now, after you have placed your ComboBox at a certain place -- using the code in your starting post -- you simply load the store manually: dirValuesStore.load();.

That is probably after the config Ext.apply(this, {items: [..., {xtype: 'combo', ...}, ...]}) in some component's initComponent().

1
votes

Try this code:

var combo = new Ext.form.field.ComboBox({
    initialValue : something,
    listeners: {
        afterrender: function(t,o ) {
           t.value = t.initialValue;    
        }
    }
}) 
1
votes

Specifying the 'value' parameter in the config is a correct way to set the default values for comboboxes.

In your example, just set forceSelection:false, it will work fine.

In case you want to set forceSelection:true, you should make sure the data returned from your store contains an item which has the value equaling to your default value ('all' in this case).Otherwise, it'll be an empty text by default. To be more clearly, please replace your dirValuesStore definition by this:

    var dirValuesStore = Ext.create('Ext.data.Store', {
        fields: ['id', 'name'],
        data: [
            {id: 'all', name: 'All'},
            {id: '1', name: 'Name 1'},
            {id: '2', name: 'Name 2'},
            {id: '3', name: 'Name 3'},
            {id: '4', name: 'Name 4'}
        ]
    })

You will see it works!

1
votes

In Extjs 5.0.1 this should work, in config combo:

...
editable: false,
forceSelection: true,
emptyText: '',