ComboBox in editable grid: can't see the value - extjs

I have an editable grid that uses a store. I want to insert a combobox in one of the fields.
This is my store for the grid:
new Ext.data.Store({ ....
proxy: new Ext.data.HttpProxy......
reader: new Ext.data.JsonReader({
root: 'rows',
fields: [..... {name:'wid', mapping: 'wid'},
There is another store for combobox only, which has 'wid' and 'name' fields.
In my column model:
header: 'Worker',
dataIndex: 'wid',
editor: new Ext.grid.GridEditor(workerCmb),
renderer:function(value, p, record){
return record.data['name'];}
And the combo itself:
valueField: 'wid',
displayField: 'name',
When the grid is loaded its field "Worker" is empty (it is ok), but there is no combobox in it. When I start editing it, I see all the list. After editing the 'id' is saved to the store, but the 'name' is not shown, neither is the combobox.
What am I doing wrong?

this helped:
Ext.util.Format.comboRenderer = function(combo){
return function(value){
var record = combo.findRecord(combo.valueField || combo.displayField, value);
return record ? record.get(combo.displayField) : combo.valueNotFoundText;
}
}

If you enable filtering ('queryMode = local') in your combobox keep in mind that every letter you put in is applied to the store. Therefore, the function findRecord will fail to find display names for the ones that are filtered out. This will affect the other lines you have in the same grid since after you finish editing the whole grid view will refresh.
To make sure you don't loose any records when the loop kicks in, remove the filters from the combobox store before you try to find the record.
Ext.util.Format.comboRenderer = function(combo){
return function(value){
combo.store.clearFilter(); // -> addition
var record = combo.findRecord(combo.valueField || combo.displayField, value);
return record ? record.get(combo.displayField) : combo.valueNotFoundText;
}
}

Related

Extjs widget tagfield can't set selected value in list from remote store

I have a trouble with my tagfield inside widgetcolumn.
I used remote store for tagfield and "autoLoadOnValue" for display loaded value in column. And it's works right. But i have a problem with values list.
If a column has a value, it is not highlighted as selected in the list. But in html the loaded value is defined as the selected.
And if you select a different value, two values will be highlighted at once.
How can I make it so that when I expand the list, the value loaded in the column is highlighted? Is there any way to update the drop-down list?
This my fiddle: https://fiddle.sencha.com/#view/editor&fiddle/3d29
UPD: queryMode: 'local' does not work for me because in my app I load the store with extraParams and I always get new values for store
Any ideas??
It happens because your tag field store is reloading on expand and loosing the selected values. You can use queryModel: 'local' to prevent store reload.
...
widget: {
xtype: 'tagfield',
store: this.tagStore,
valueField: 'tag',
displayField: 'field',
autoLoadOnValue: true,
//filterPickList: false,
queryMode : 'local', // use this to avoid store reload on
listeners: {
select: function (cmp, record) {
const dataIndex = cmp.getWidgetColumn().dataIndex;
const widgetRecord = cmp.getWidgetRecord()
let valuesArr = [];
Ext.each(record, function (item) {
valuesArr.push(item.data.tag)
})
widgetRecord.set(dataIndex, valuesArr);
console.log(record)
}
}
}
...
Or you can use the following override (or you can extend the tag field with appropriate logic) to store the selected value and after store reload re-select it:
Ext.define('overrides.form.field.Tag', {
override: 'Ext.form.field.Tag',
initComponent: function() {
this.getStore().on('beforeload', this.beforeStoreLoad, this);
this.getStore().on('load', this.afterStoreLoad, this);
this.callParent();
},
beforeStoreLoad: function(store) {
this.beforeStoreLoadFieldValue = this.getValue();
},
afterStoreLoad: function(store) {
this.setValue(this.beforeStoreLoadFieldValue);
}
});

Extjs : Selecting same value in multiselect combo not removing value

I am using ext5 multiselect combo. If we select a value from the dropdown, say 'Other' and click outside to cancel the dropdown.
Now the value 'Other' will be shown in combo.
Again click the dropdown and select tha same value 'Other', it should remove 'Other' from its values. But rather it adds same value once again.
My code is given below:
xtype: 'combo',
emptyText: 'Retail BI',
name: 'chainRefId',
store: Ext.create('shared.store.filter.ChainRefs'),
displayField: 'name',
multiSelect: true,
valueField: 'chain_ref_id',
listeners: {
expand: function(){
this.getStore().load();
},
change: function(combo, newVal) {
if (!combo.eventsSuspended) {
var storeCombo = Ext.ComponentQuery.query('combo[name=storeId]')[0];
storeCombo.getStore().removeAll();
storeCombo.setValue(null);
var chainCombo = Ext.ComponentQuery.query('combo[name=chainId]')[0];
chainCombo.getStore().removeAll();
chainCombo.setValue(null);
}
}
}
Is there a solution for this?
Thanks in advance.
Your combo's store gets reloaded on each expand. Technically the record corresponding to the value you selected the first time disappears on the second store load, so the removing logic does not "see" it and therefore leaves it in the field.
Remove this:
expand: function(){
this.getStore().load();
}
and just use autoLoad: true on the store.
I have faced the same problem. I have provided a workaround for this. This fix holds good for tagfield too.
//on combo store load event
load: function () {
// I am assuming reference to combo
var rawVal = combo.getValue();
// If combo is multiselct, getValue returns an array of selected items.
// When combo is configured as remote, everytime it loads with new records and therefore removes the old reference.
// Hence, do setValue to set the value again based on old reference.
combo.setValue(rawVal);
// Here you can see, based on old reference of selected items, the drop down will be highlighted.
}

extjs4 combobox trunks value

I have a comboBox within a form, the valueField is the ObjectId field of a document in mongodb, it displays the proper value of the fields in the comboBox, but it returns just a part of the value with getValue, getRawValue returns the value of the displayField.
This is the code of the comboBox:
{
xtype: 'combo',
fieldLabel:'Firm',
store:Ext.data.StoreManager.lookup('bbCompaniesStore'),
displayField: 'firm',
valueField: '_id',
name: 'country',
labelAlign: 'top',
cls: 'field-margin',
flex: 1
}
This is how I get the value from the form:
var nomeField = formPanel.items.get(0).items.get(0);
var firmField = formPanel.items.get(0).items.get(1);
var noteField = formPanel.items.get(0).items.get(2);
var contact = Ext.ModelManager.create({nome: nomeField.getValue(), note: noteField.getValue(),'firm_id':firmField.getValue()}, 'Contact');
It works but it trunks the value of _id, I checked with firebug, the server sends the rigth data,I think that extjs does some kind of normalization, before I solved using getRawValue, but with combobox it returns the displayField. I do not know how to fix this problem.

Dynamically Loading data when performing cascading in comboboxes in extjs [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Cascading Combobox in extjs
Hi I have two comboboxes ,viz..
AcademicClass
{
xtype : 'combobox',
emptyText : 'Academic Class',
displayField : 'name',
id:'comboacademicclass',
valueField : 'id',
store:classstore,
triggerAction:'all',
mode:'local',
listeners : {
'select' : {
fn: function(combo1, value) {
var comboSubject=Ext.getCmp('combo-subject');
var classId=Ext.getCmp('comboacademicclass').getValue();
comboSubject.setDisabled(true);
comboSubject.setValue('');
comboSubject.getStore().removeAll(true);
comboSubject.getStore().load({url:'http://localhost:8080/WebService/rest/type/academicSubjectByClass/'+classId+'.json'});
// Using this loading data in second combobox by passing first combobox Id.:- 'classId'.
comboSubject.setDisabled(false);
}
}
}
}
AcademicSubject:
{
xtype : 'combobox',
emptyText : 'Academic Subject',
id:'combo-subject',
displayField : 'name',
valueField : 'id',
disabled:true,
store:subjectstore,
triggerAction:'all',
mode:'local'
,lastQuery:''
}
Its showing output only first time selection but on second time selection its just showing "Loading" and not dispalying output. Please Help.
Well you should listen with the AcademicSubject combo on the AcademicClass for the select or the change event and activate the listening combo along with it. You will also get the selected value and can so prepare the query for the activate combo. You could do this like
combobox.queryData = [{ property: 'fieldName', value: value}];
combobox.reset();
combobox.doQuery(combobox.queryData);
where combobox is a reference to the activated combo (AcademicSubject ) and value a propertyvalue from the AcademicClass combo. To ensure the use of your new query use
combobox.on('beforequery', function (e) {
e.query = e.combo.queryData;
});
Please note:
For the snippets above I recommend to use queryParam: 'filter' which would enable you to use default serverside filter behavior without the need to introduce a new param.

extjs 3.4 editable grid: how to separate displayField and ValueField in column

I'm trying to make something that looks like: http://dev.sencha.com/deploy/ext-3.4.0/examples/grid/edit-grid.html
But I want to change Light column:
I want it to contain ids instead of actual values.
I can force combobox to separate values from presentation but not the actual column value (in fact I don't know where to store id-value mapping for column (not just for the editor)):
new Ext.grid.EditorGridPanel({
...
store: new Ext.data.Store ({
...
fields: [
'MagicId',
...
]
})
columns: [
{
header: 'Magic',
dataIndex: 'MagicId',
editor: new Ext.form.ComboBox({
store: new Ext.data.Store({
...
fields: ['id', 'title']}),
valueField: 'id',
displayField: 'title',
editable: 'false'
})
},
...
]
When I select "Magic title" in combobox I get MagicId in my grid anyway. I understand why it's happening but can't make it work the way I need it to work...
I tried to replace all unnecessary code with ... to help you reading.
Thank you for your attention.
Keep the ID field in your grid/store, then use the "renderer" property to display something else. ID-text mapping could be stored in an array or an object:
{
header: 'Magic',
dataIndex: 'MagicId',
renderer: function(value) {
return magicIdValueArray[value];
}
...
}
EDIT:
Since you already have the ID-value mapping in the combo store, I would use that store to fetch the value (it needs to be declared outside the combobox).
renderer: function(value) {
var record = comboStore.findRecord('id', value);
return record.title;
}

Resources