How to add an empty item to ExtJS combobox?
Asked Answered
C

6

19

I want to add and empty item (display value is blank, item height is kept as normal) to an Ext.form.ComboBox. I refered 2 links below to configure my combobox, but it still not display the empty item:

Here is my code:

this.abcCombo = new Ext.form.ComboBox({
    name : 'abcCombo',
    hiddenName : 'abcCombo-id',
    fieldLabel : "My Combobox",
    width : 250,
    editable : false,
    forceSelection : true,
    mode : 'local',
    triggerAction : 'all',
    valueField : 'id',
    displayField : 'fullName',
    store : new Ext.data.JsonStore({
        fields : ['id', 'fullName']
    }),
    tpl : '<tpl for="."><div class="x-combo-list-item">{fullName}&nbsp;</div></tpl>'
});

The combobox store's data will be loaded after an Ajax request (i.e 3 items in data items). And the combobox has only 3 item (not 4 as I expected). Do you have any idea about my problem?! Thank you so much!

Contexture answered 22/2, 2012 at 17:20 Comment(0)
S
13

Since your adding the combobox values later, why not just initialize the store with one blank value:

store : new Ext.data.JsonStore({
    fields : ['id', 'fullName'],
    data : [{id: 0, fullName: ''}]
}),

Later when you do store.add(theRestOfThem), that blank one will still be there.

Had to revisit this today (15 Apr 2017) for ExtJS 4.2:

The easiest way is to include an empty string in the store as above, it can also be done with a load listener on the store:

listeners: 
{
    load: function(store, records) 
    {
        store.insert(0, [{
            fullName: '',
            id: null
        }]);
    }
}

Then add a tpl config to the combobox with &nbsp; after the display field:

tpl: '<tpl for="."><div class="x-boundlist-item">{fullName}&nbsp;</div></tpl>',

(the display field is fullName in the OPs case)

Swellfish answered 22/2, 2012 at 17:47 Comment(4)
Thank you for your response. But when we add this empty item at initialization step, the combobox will display it with the item height is minimized, not normal height as the others.Medora
@napoleonit76 Sorry, use space instead of '', see edit. I had this same problem at first now that I remember it.Swellfish
If you include an empty item in the store, you would have to execute something else to do the validation. Normally, the default validator would just check that the value selected is in the store. I don't see this as a viable option.Enphytotic
Adding $nbsp; was causing too many issues for me so I found another solution using style. <style> .x-boundlist li:empty { height: 20px; } </style>Lustral
B
14

You can add an "empty" record at the beginning:

 listeners: {
     load: function(store, records) {
          store.insert(0, [{
              fullName: '&nbsp;',
              id: null
          }]);
     }
  }
Bitch answered 6/4, 2013 at 16:49 Comment(1)
I used this listener with the listener from @Mr_Green's comment.Cocci
S
13

Since your adding the combobox values later, why not just initialize the store with one blank value:

store : new Ext.data.JsonStore({
    fields : ['id', 'fullName'],
    data : [{id: 0, fullName: ''}]
}),

Later when you do store.add(theRestOfThem), that blank one will still be there.

Had to revisit this today (15 Apr 2017) for ExtJS 4.2:

The easiest way is to include an empty string in the store as above, it can also be done with a load listener on the store:

listeners: 
{
    load: function(store, records) 
    {
        store.insert(0, [{
            fullName: '',
            id: null
        }]);
    }
}

Then add a tpl config to the combobox with &nbsp; after the display field:

tpl: '<tpl for="."><div class="x-boundlist-item">{fullName}&nbsp;</div></tpl>',

(the display field is fullName in the OPs case)

Swellfish answered 22/2, 2012 at 17:47 Comment(4)
Thank you for your response. But when we add this empty item at initialization step, the combobox will display it with the item height is minimized, not normal height as the others.Medora
@napoleonit76 Sorry, use space instead of '', see edit. I had this same problem at first now that I remember it.Swellfish
If you include an empty item in the store, you would have to execute something else to do the validation. Normally, the default validator would just check that the value selected is in the store. I don't see this as a viable option.Enphytotic
Adding $nbsp; was causing too many issues for me so I found another solution using style. <style> .x-boundlist li:empty { height: 20px; } </style>Lustral
M
3

This is how we can add a blank field in Combo box

In java Map or any other collection put key value like this

fuelMap.put("","&nbsp;"); // we need to add "&nbsp;" not ""," " or null 
                          // because these will add a fine blank line in Combobox 
                          // which will be hardly noticeable.

In js file, it should be like this :

Listener for combo box

listeners: {
    select: function (comp, record, index) {
        if (comp.getValue() === "" || comp.getValue() === "&nbsp;") {
            comp.setValue(null);
        }
    }
}
Mcknight answered 6/12, 2012 at 20:19 Comment(0)
W
3
this.abcCombo = new Ext.form.ComboBox({
    name : 'abcCombo',
    hiddenName : 'abcCombo-id',
    fieldLabel : "My Combobox",
    width : 250,
    editable : false,
    forceSelection : true,
    mode : 'local',
    triggerAction : 'all',
    valueField : 'id',
    displayField : 'fullName',
    store : new Ext.data.JsonStore({
       fields : ['id', 'fullName']
    }),
    tpl : '<tpl for="."><div class="x-combo-list-item">{fullName}&nbsp;</div></tpl>'

    //make sure to add this
    //if not added, empty item height is very small
    listConfig : {
        getInnerTpl: function () {
            return '<table><tr><td height="12">{fullName}</td></tr></table>';
        }
    }

});

on initializing the component, you can do this (on controller):

populateMyComboBox([yourComboBoxComponent], true);

on the populate function:

populateMyComboBox : function(comboBox, insertEmpty) {
    var list;
    if (insertEmpty) {
        list.push({id : 0, fullName : ''});
    }

    var mStore = Ext.create('Ext.data.Store', {
        fields: ['data', 'label'],
        data : list.concat([real_data])
    }),

    comboBox.bindStore(mStore);
}
Waldo answered 23/5, 2013 at 4:30 Comment(1)
for extjs 4 this solution breaks the combobox, the simplest solution i found was removing the whole templating stuff and simply put tpl: new Ext.XTemplate('<tpl for=".">' + '<li style="height:22px;" class="x-boundlist-item" role="option">' + '{name}' + '</li></tpl>'), into the Ext.create/config for the comboboxBollix
S
2

In Ext 4.2.1 (probably others), just add to combobox config:

tpl : '<tpl for="."><div class="x-boundlist-item">{fullName}&nbsp;</div></tpl>'
Saltwort answered 10/2, 2016 at 0:5 Comment(1)
This is an EXCELLENT trick, which absolutely solves my current headache, many thanks!Lanneret
P
1

If the store uses inline data then store.load even won't fire. Maybe there is a better solution, but I ended up inserting store records on combobox.render:

{
    xtype: 'combo',
    displayField: 'name',
    valueField: 'value',
    store: {
        type: 'MyInlineStore',
    },
    listeners: {
        render: function(el){
            el.getStore().insert(0, [{name: '[Any]', value: ''}]);
            el.setValue(''); //select [Any] by default
        }
    },
}
Perished answered 8/5, 2017 at 22:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.