PDA

View Full Version : ComboBox for Grid (combo having local store)



durlabh
5 May 2008, 4:08 PM
Many people have been having confusion over how to handle rendering of combo boxes having a separate valueField and displayField. This is how we have been using in our applications:



Ext.ns("Ext.ux.renderer");

Ext.ux.renderer.ComboRenderer = function(options) {
var value = options.value;
var combo = options.combo;

var returnValue = value;
var valueField = combo.valueField;

var idx = combo.store.findBy(function(record) {
if(record.get(valueField) == value) {
returnValue = record.get(combo.displayField);
return true;
}
});

// This is our application specific and might need to be removed for your apps
if(idx < 0 && value == 0) {
returnValue = '';
}

return returnValue;
};

Ext.ux.renderer.Combo = function(combo) {
return function(value, meta, record) {
return ExtHelper.renderer.ComboRenderer({value: value, meta: meta, record: record, combo: combo});
};
}


Then, in grid config you can use the same renderer for combo:


// Your combo definition
var addressTypeCombo = Ext.form.ComboBox();

var cm = new Ext.grid.ColumnModel([
{header: 'Type', dataIndex: 'AddressTypeId', width: 100, renderer: Ext.ux.renderer.Combo(addressTypeCombo), editor: addressTypeCombo},
{header: 'Address', dataIndex: 'Address1', width: 130, editor: new Ext.form.TextField({maxLength:50})},
{header: 'Address 2', dataIndex: 'Address2', width: 110, editor: new Ext.form.TextField({maxLength:50})},
{header: 'Address 3', dataIndex: 'Address3', width: 110, editor: new Ext.form.TextField({maxLength:50})},
{header: 'Zip Code', dataIndex: 'PostalCode', editor: new Ext.form.TextField({maxLength:10}), width: 80},
{header: 'City', dataIndex: 'City', width: 80, editor: new Ext.form.TextField({maxLength:20})}]
])



Please note that the above combo box assumes that the store for combo will be local. This approach won't work with remote combos. For remote combo, we update a "proxy" field in the grid store that is used for rendering.

Let me know your suggestions/ improvements.

johnkpaul
22 May 2008, 7:17 AM
Do you have an example/demo of this? Does this allow for the combobox to show by default, without requiring any clicks on the editor grid panel?

neenhouse
27 May 2008, 1:05 PM
Thank you so much for this. This solved my problems: funny enough it worked for my remote comboboxes...

durlabh
27 May 2008, 1:17 PM
Hi Johnkpaul,

This code is a helper method for rendering. So, it shows the selected item in grid instead of value behind it. For example, let us say, you use a combo box editor for a column and it has a name value pair such as [[1, "Yes"], [2, "No"]]. Now, when you setup the column model for the grid, you'll notice that the grid shows values 1 and 2 instead of "Yes" or "No". However, when you edit the values, combo shows up just fine. This happens because we store values 1 and 2 in the data store. So, to render the converted values, we use a custom renderer. There are lot of examples out there. So, what this sample does is - use the store of the combobox itself to read the values. So, instead of specifying a renderer for each column, you can use this helper method.

Thanks,

Durlabh

maggiesnyder
17 Jul 2008, 4:12 PM
Completely perfect. Thank you!

I did change this line:

return ExtHelper.renderer.ComboRenderer({value: value, meta: meta, record: record, combo: combo});To this:

return Ext.ux.renderer.ComboRenderer({value: value, meta: meta, record: record, combo: combo});

CeeBee
31 Jul 2008, 4:33 AM
Had to do the change that maggiesnyder mentioned, but I'm still stuck using this with a combo bound to a remote store.

My grid is bound to a remote store (let's call it grid_store) that autoloads and has the fields "country_code" and "shipping_cost". "country_code" uses a combobox-editor that is bound to another remote store (named combo_store) that has been loaded previously and has the fields "country_code" (maps to valueField) and "country_name" (maps to displayField). I'd like to show the displayField's value of the combo_store inside the grid, instead of the initially loaded grid_store value.


For remote combo, we update a "proxy" field in the grid store that is used for rendering

So how does this actually work?

durlabh
31 Jul 2008, 5:03 AM
CeeBee, there are examples in Grid FAQ thread that answer your question. However, let me just summarize how we do it:

Let us say you need CountryId and StateId in your grid. So, we'll add CountryName and StateName as two additional proxy fields in the grid. Now your fields will look something like this:



[{name: 'CountryId', type: 'int'}, {name: 'StateId', type: 'int'}, {name: 'CountryName', type: 'string'}, {name: 'StateName', type: 'string'}];


Now in the grid configuration also, you'll do something like this:


[{header: 'Country', dataIndex: 'CountryId', editor: new Ext.form.ComboBox(), renderer: function(v, m, r) { return r.get('CountryName'); }}]


Then, on selection of combo, to update the country name we add an event handler like this:


grid.on('validateedit', function(e) {
var dataIndex = e.field;
switch(dataIndex) {
case "CountryId":
case "StateId":
var combo = grid.getColumnModel().getCellEditor(e.column, e.row).field;
var displayFieldName = e.field.replace('Id', 'Name');
e.record.set(displayFieldname, combo.getRawValue());
break;
}
});


I hope this helps!

RobbyGCT
10 Nov 2008, 7:42 AM
hi,
thanks at first, this helped me much.
But i have a 'problem'... its not realy a problem, but it dont looks good to users.
Ok, thats what i got: a grid, a combobox inside the grid and a listener for dblClick on column...
the dblClick opens a Ext.Window and if the user dblClicked on my combobox, thats inside the grid, the combobox is visible through the window.


bye Robby

rootnode_
10 Dec 2008, 1:57 AM
Good stuff. In my view this should be the default renderer for comboboxes

Animal
7 Feb 2009, 1:57 AM
Many people have been having confusion over how to handle rendering of combo boxes having a separate valueField and displayField. This is how we have been using in our applications:



Ext.ns("Ext.ux.renderer");

Ext.ux.renderer.ComboRenderer = function(options) {
var value = options.value;
var combo = options.combo;

var returnValue = value;
var valueField = combo.valueField;

var idx = combo.store.findBy(function(record) {
if(record.get(valueField) == value) {
returnValue = record.get(combo.displayField);
return true;
}
});

// This is our application specific and might need to be removed for your apps
if(idx < 0 && value == 0) {
returnValue = '';
}

return returnValue;
};

Ext.ux.renderer.Combo = function(combo) {
return function(value, meta, record) {
return ExtHelper.renderer.ComboRenderer({value: value, meta: meta, record: record, combo: combo});
};
}


Then, in grid config you can use the same renderer for combo:


// Your combo definition
var addressTypeCombo = Ext.form.ComboBox();

var cm = new Ext.grid.ColumnModel([
{header: 'Type', dataIndex: 'AddressTypeId', width: 100, renderer: Ext.ux.renderer.Combo(addressTypeCombo), editor: addressTypeCombo},
{header: 'Address', dataIndex: 'Address1', width: 130, editor: new Ext.form.TextField({maxLength:50})},
{header: 'Address 2', dataIndex: 'Address2', width: 110, editor: new Ext.form.TextField({maxLength:50})},
{header: 'Address 3', dataIndex: 'Address3', width: 110, editor: new Ext.form.TextField({maxLength:50})},
{header: 'Zip Code', dataIndex: 'PostalCode', editor: new Ext.form.TextField({maxLength:10}), width: 80},
{header: 'City', dataIndex: 'City', width: 80, editor: new Ext.form.TextField({maxLength:20})}]
])



Please note that the above combo box assumes that the store for combo will be local. This approach won't work with remote combos. For remote combo, we update a "proxy" field in the grid store that is used for rendering.

Let me know your suggestions/ improvements.

This is a very good idea. I think you should submit a Feature Request that comboRenderer be added to Ext.util.Format the same way dateRenderer (http://extjs.com/deploy/dev/docs/?class=Ext.util.Format&member=dateRenderer) is.

roderick.wu
16 Feb 2009, 12:29 AM
Hi, durlabh (http://extjs.com/forum/member.php?u=14842) , i can do this for 'local' data, but failed to setup "remote" one.

I have setup the key pair of "id" and "value", but it keep showing the 'id' in the grid

do you have any examples for remote mode? Thanks.

roderick.wu
16 Feb 2009, 1:09 AM
Hi, team, i have resolved the remote display issue, below is the code, fyi.

Define a ext.data.store and load data from a proxy first.
then add the rederer below:


renderer:function(value)
{
var index = listStore.find("ID",value);
var typeName = listStore.getAt(index).get("Name");
return typeName;
},

durlabh
16 Feb 2009, 9:16 PM
You might be interested in looking at the following thread also:

http://extjs.com/forum/showthread.php?t=37781&page=2

ulisses.gomes
31 May 2009, 2:21 PM
=D>
Tnkz a lot

dizor
6 Jun 2009, 10:47 AM
I have problem with durlabh code - mode:remote, and if i do search in combo and later do



grid.getView().refresh();


all values previously asigned with displayField:'label' changed to valueField :'id'. That's because in store after query is only searched label & id - and than i do "refresh" store have no items (label) for assign.

Any solution for this?

dizor
8 Jul 2009, 4:31 AM
anybody?

Thomas_K
20 Oct 2009, 1:20 AM
if anyone need this comborenderer for extjs 3

change..



var field = combo.editor.field;


to



if(combo.editor) var field = combo.editor.field;
else var field = combo;

ronmichael
9 Mar 2010, 12:37 PM
I've been using a variation of this renderer for a while. Is it correct to assume that we still need to us this in Ext JS version 3?

And has anyone else noticed some odd behavior if you type in a value in the combo rather than select a value with the mouse? If you start typing something, it'll show matches and look like it's going to autofill, but if you hit Tab it'll just blank out the field and not save your new value. The standard examples of the combo in the grid field don't behave this way, so I assume it's something to do with the custom renderer but I haven't been able to solve it. It makes it impossible to enter data exclusively with the keyboard... you have to use the mouse to pick things from the combo.

rogerio.carrasqueira
30 Sep 2010, 6:54 AM
Do you have a example for remote mode?

durlabh
30 Sep 2010, 6:56 AM
As mentioned in earlier post, check this out: http://www.sencha.com/forum/showthread.php?37781-comboboxes-with-remote-datastores-(a-solution)&p=188131#post188131

colinm
21 Jan 2011, 9:44 AM
Hi,
i wondered if someone if it is possible to create a Combobox in a grid but with a different store for each combobox.
so for example the list of traductions of a book ... this depends of each book ....
so far, it seems quite difficult to me .. but since extjs rocks ... it should be right?
any thoughts/links/solutions?

durlabh
21 Jan 2011, 9:49 AM
You should be able to change the store data (or combobox itself) by listening to beforeedit event of the EditorGrid.

colinm
21 Jan 2011, 11:08 AM
thx .. it sounds logic .. i will try tomorrow ... just if you know on top of your head .. is it possible to have the combobox displaying the down arrow all the time (so far, it seems that i am obliged to double click on the cell to have the combobox option coming out)

i will let you know if i succeed with my combobox
thx again

durlabh
21 Jan 2011, 11:14 AM
For changing the editor, use setEditor method in beforeedit event. To give it a look of combobox being active always, you can use a renderer and return a class name that makes the rendered area look like a dropdown. Also, you can change clickstoedit property to make it single click edit instead of double click.

colinm
21 Jan 2011, 1:54 PM
thx again ..
i am thinking again about my previous post (having a combobox displaying a 'row contextual store') .. well i am not sure your previous answer works .. can you extend about the following problem:
when the grid is displayed you want to have a default view in each combo to be different .. for the example of a book list, each book as a different translator list and if you click on a combo the displayed list is different ..
-> to have a different displayed list, i agree than changing the store in the beforeedit method should do it ... but to have different values per default in each store .. would you suggest to first create a store with all the default values?

logive
27 Apr 2011, 5:59 PM
funny enough it worked for my remote comboboxes,there are some place modified

Ext.ns("Ext.ux.renderer");
Ext.ux.renderer.ComboRenderer = function(options) {
var value = options.value;
var combo = options.combo;
var returnValue = value;
var valueField = combo.valueField;

var idx = combo.store.findBy(function(record) {
if(record.get(valueField) == value) {
returnValue = record.get(combo.displayField);
return true;
}
});

// This is our application specific and might need to be removed for your apps
if(idx < 0 && value == 0) {
returnValue = '';
}

return returnValue;
};
Ext.ux.renderer.Combo = function(combo) {
return function(value, meta, record) {
return Ext.ux.renderer.ComboRenderer({value: value, meta: meta, record: record, combo: combo});
};
}
------------------------------------------------------
{
header: '币制',
dataIndex: 'rptype',
sortable: true,
width: 95,
editor: rptypeFun("rptype",'','rpTypeAction_listAll.do'),
renderer:Ext.ux.renderer.Combo(Ext.getCmp('rptype'))
},

bee
19 May 2011, 7:21 AM
hi guys, in many threads the topic was discussed on combo box, and I referred all those steps, but I am getting undefined combo box on editor grid panel. can anyone suggest me the solution ?

rajivchaudhary_it
8 Sep 2011, 10:44 PM
Hi ,
I Have a grid with the combo box and other columns , i want to change the value of other columns when i changed the selection of my combo.

example will be highly appreciable

rajivchaudhary_it
8 Sep 2011, 10:56 PM
Thanks Guys , my question is already answered in this post ..;) didt see it properly

Maurod69
27 Dec 2013, 12:45 PM
Hello I am fairly new to Extjs and I am trying to have a couple of comboboxes in a grid panel. We have tried a couple of ways to accomplish this with no lock. We have the two columns with a editor and we define the combobox inside. The problem as many people have reported is that the combo does not appear as a combobox for the user when the page is loaded and only when the user clicks on the cell then the cell becomes a dropdown.
Here is a code snipet of what I have
return {
extend: 'Ext.grid.Panel'columns: [
{
dataIndex: 'whatever',
text: 'blabla',
editor: {
xtype: 'combobox',
store: 'mystore',
queryMode: 'local',
renderer: function (value, metaData, record, rowIndex, colIndex, store, view, self) {

this.columns[1].getEditor().store = Ext.create('Ext.data.Store', {
fields: ['value', 'Label'],
data: value
})
return value[0].Label;
}
}
},


Can someone shed some light? I have read the example with the helper but am not sure how to apply it.