ExtJS: Fetching information from selected store in combo - extjs

I have the following ExtJS Textfield that lives in a form. I have a store called
store_Product that fetches data via ajax proxy and suggest them to the PCODE field.
In reality this store has many other fields such as price,color,size and so on..
I am trying to set an onchange listener on this field such that when the user select the PCODE, it delivers other information (of the Product selected) to other fields in the page.
The code bellows work. The console.log(store_Product.data) correctly fetches the data from the model. However, the data fetched is of the whole store. I just want the one selected. How would I change this code to do that.
{
fieldLabel: 'PCODE ',
name: 'pcode',
typeAhead: true,
xtype: 'combo',
store: store_Product,
displayField: 'pcode',
valueField: 'pcode',
allowBlank:false,
minChars:1,
forceSelection:true,
hideTrigger:true,
queryDelay: 0,
listeners:{
change: function(combo,value){
console.log(store_Product.data)
}
}
}
Thanks.

Of course it's gonna log everything. Have you tried looking at the value you're receiving in the handler?
change: function(combo, value) {
console.log(value);
var idx= store_Product.find('pcode', value),
record = store_Product.getAt(idx);
console.log(record);
}

If pcode is the id of your records, you can use Store.getById:
store_Product.getById(value)

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.
}

How to set combobox's value from extjs controller

I am working in extjs4. I have combobox with code as-
{
margin:'7 6 5 5',
xtype:'combobox',
fieldLabel:'Language',
name:'language',
id:'combo',
width:190,
allowBlank:false,
emptyText: '--Select language--',
labelWidth: 60,
store: new Ext.data.ArrayStore({
fields: ['id','value'],
data: [
['1','Marathi'],
['2','English']
]
}),
queryMode: 'local',
valueField:'id',
displayField:'value',
editable:false
},
Throuhout my functioning I want to set combobox's value defaultly to user's selected choice. So how to set combobox's value from controller
To select default value you can use event listener. After combobox has been rendered you can set value you need using setValue() method from Ext.form.field.Field and if you need to select combobox value on demand you can get it using Ext.getCmp('combo') and then use setValue() or even better set itemId instead of id and use componentQuery to fetch combobox and set value:
Ext.ComponentQuery.query('#combo')[0].setValue('2');
setValue( value ) : Ext.form.field.Field Sets the specified value(s)
into the field. For each value, if a record is found in the store that
matches based on the valueField, then that record's displayField will
be displayed in the field. If no match is found, and the
valueNotFoundText config option is defined, then that will be
displayed as the default field text. Otherwise a blank value will be
shown, although the value will still be set.
listeners:{
scope: this,
afterRender: function(me){
me.setValue('1');
}
}
Here is an example in fiddle
Try this:
Ext.getCmp('combo').setValue('1' or '2');

Cancel selection in BoxSelect or ComboBox in ExtJS

Alhough it sounds as it doesn't make any sense, it does if I get it to work...
What I'm trying to do is get the combo to do nothing, nothing at all... so I managed to stop it from adding the record to the selected records list. But I can't find the way to stop it from painting the item blue.
The best way to understand what I'm trying to do is check the live preview in the ExtJS Docs page, and see how if you select an item in the dropdown list it goes blue although it doesn't add it to the selectedRecords list.
Here is the url to the ExtJS Docs page...
http://docs.sencha.com/ext-js/4-0/#!/api/Ext.form.field.ComboBox
For those of you not familiar with the tool, just look for the Code Editor there, paste this code and click Live Preview.
// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL", "name":"Alabama"},
{"abbr":"AK", "name":"Alaska"},
{"abbr":"AZ", "name":"Arizona"}
]
});
// Create the combo box, attached to the states data store
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose State',
store: states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
multiSelect:true,
renderTo: Ext.getBody(),
onListSelectionChange:function(){
console.log('Do nothing');
}
});
Is this what you are looking for?
onListSelectionChange:function(){
this.picker.getSelectionModel().deselectAll();
}
See it working here: http://jsfiddle.net/lontivero/5Ftrf/1/
Update
If you want to keep the previously selected items as they are, you could try with this. It will prevent only new selections.
onListSelectionChange:function(){
var lastSelected = this.picker.getSelectionModel().lastSelected;
itemNode = this.picker.getNode(lastSelected || 0);
if (itemNode) {
this.picker.getSelectionModel().deselect(lastSelected );
}
}
in jsfiddle: http://jsfiddle.net/lontivero/5Ftrf/2/

Dynamically changing the DataStore of a ComboBox

I have a combo box which populates its values based on the selection of another combobox.
I have seen examples where the params in the underlying store are changed based on the selection, but what I want to achieve is to change the store itself of the second combo based on the selection on the first combo. This is my code, but it doesn't work. Can someone please help?
{
xtype: 'combo',
id: 'leads_filter_by',
width: 100,
mode: 'local',
store: ['Status','Source'],
//typeAhead: true,
triggerAction: 'all',
selectOnFocus:true,
typeAhead: false,
editable: false,
value:'Status',
listeners:{
'select': function(combo,value,index){
var filter_to_select = Ext.getCmp('cmbLeadsFilter');
var container = filter_to_select.container;
if (index == 0){
filter_to_select.store=leadStatusStore;
filter_to_select.displayField='leadStatusName';
filter_to_select.valueField='leadStatusId';
} else if(index==1) {
filter_to_select.store=leadSourceStore;
filter_to_select.displayField='leadSourceName';
filter_to_select.valueField='leadSourceId';
}
}
}
},
{
xtype: 'combo',
id: 'cmbLeadsFilter',
width:100,
store: leadStatusStore,
displayField: 'leadStatusName',
valueField: 'leadStatusId',
mode: 'local',
triggerAction: 'all',
selectOnFocus:true,
typeAhead: false,
editable: false
},
That is not how its designed to work!! When you set a store in the config, you are binding a store to the combo. You don't change the store, instead you are supposed to change the data when required.
The right way of doing it would be to load the store with correct data from the server. To fetch data, you can pass params that will help the server side code get the set of options you need to load.
You will not want to change the store being used... Simply put, the store is bound to the control as it is instantiated. You can, however, change the URL, and params/baseParams used in any additional POST requests.
Using these params, you can code your service to return different sets of data in your combo box's store.
For the proposed problem you can try below solution :
Use below "listener" snippet for the first "leads_filter_by" combo. It will handle the dynamic store binding / changing for the second combobox.
listeners:{
'select': function(combo,value,index){
var filter_to_select = Ext.getCmp('cmbLeadsFilter');
var container = filter_to_select.container;
if (index == 0){
//filter_to_select.store=leadStatusStore;
filter_to_select.bindStore(leadStatusStore);
filter_to_select.displayField='leadStatusName';
filter_to_select.valueField='leadStatusId';
} else if(index==1) {
//filter_to_select.store=leadSourceStore;
filter_to_select.bindStore(leadSourceStore);
filter_to_select.displayField='leadSourceName';
filter_to_select.valueField='leadSourceId';
}
}
}
Hope this solution will help you.
Thanks & Regards.
I had a similar problem. The second combobox would load the store and display the values, but when I would select a value, it would not actually select. I would click the list item and the combobox value would remain blank.
My research also suggested that it was not recommended to change the store and field mappings on a combobox after initialization so here was my solution:
Create a container in the view that would hold the combobox to give me a reference point to add it back later
Grab a copy of the initial config off of the combobox ( this lets me set my config declaritively in the view and not hard code it into my replace function ... in case I want to add other config properties later)
Apply new store, valueField and displayField to that config
Destroy old combobox
Create new combobox with modified config
Using my reference from step 1, add the new combobox
view:
items: [{
xtype: 'combobox',
name: 'type',
allowBlank: false,
listeners: [{change: 'onTypeCombo'}],
reference: 'typeCombo'
}, { // see controller onTypeCombo for reason this container is necessary.
xtype: 'container',
reference: 'valueComboContainer',
items: [{
xtype: 'combobox',
name: 'value',
allowBlank: false,
forceSelection: true,
reference: 'valueCombo'
}]
}, {
xtype: 'button',
text: 'X',
tooltip: 'Remove this filter',
handler: 'onDeleteButton'
}]
controller:
replaceValueComboBox: function() {
var me = this;
var typeComboSelection = me.lookupReference('typeCombo').selection;
var valueStore = Ext.getStore(typeComboSelection.get('valueStore'));
var config = me.lookupReference('valueCombo').getInitialConfig();
/* These are things that get added along the way that we may also want to purge, but no problems now:
delete config.$initParent;
delete config.childEls;
delete config.publishes;
delete config.triggers;
delete config.twoWayBindable;
*/
config.store = valueStore;
config.valueField = typeComboSelection.get('valueField');
config.displayField = typeComboSelection.get('displayField');
me.lookupReference('valueCombo').destroy();
var vc = Ext.create('Ext.form.field.ComboBox', config);
me.lookupReference('valueComboContainer').add(vc);
},

Resources