Extjs : Selecting same value in multiselect combo not removing value - extjs

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

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: Show/hide control on checkbox selectionchange

I have an ExtJS check-tree ExtJS Check Tree that I am trying to add some control to based on items checked/unchecked. It doesn't seem to fire correctly though.
Here is a Fiddle Example
When checkbox 'A' is selected, I want to hide the textfield, 'testValue', which works, but then if I unselect checkbox 'A', I want to show the textfield, 'testValue', which does not work.
For this test I am merely looking to see if the selections.selected.length === 0. However, when I unselect any of the checkboxes, the listener does not seem to be firing, since the alert message is not getting triggered - plus, if I then try to reselect the check box again it still does not fire.
I would use a selection Model (as outlined below) to achieve this (since I know it works), but then this places checkboxes on all my tree items when I just want to have the leaf nodes with checkboxes.
selModel: {
type: 'checkboxmodel',
listeners: {
selectionchange: 'onCheckedNodesChange'
}
}
Any suggestions would be most welcome!
EDIT
Adding allowDeselect: true and a listener for select and deselect sort of worked (I updated the Fiddle to exhibit the behavior):
selModel: {
allowDeselect: true,
listeners: {
deselect: function(model, record, index) {
text = record.get('text');
alert(text);
},
select: function(model, record, index) {
text = record.get('text');
alert(text);
}
}
},
I want to make sure that when 'A' is selected, the textfield remains hidden, but if you select another item in the list and then deselect it, the textfield returns.
I am trying to use the getChecked() method alone with when selectionchange event occurs. However, this only seems to return data when I do a submit (for example, on the Get checked nodes control). Any suggestions would be most welcome. This should not be so difficult.
For tree panel we have checkchange event it is similar to the selectionchange event.
http://docs.sencha.com/extjs/4.2.5/#!/api/Ext.tree.Panel-event-checkchange
checkchange( node, checked, eOpts )
Fires when a node with a checkbox's checked property changes
Parameters
node : Ext.data.TreeModel
The node who's checked property was changed.
checked : Boolean
The node's new checked state
eOpts : Object
The options object passed to Ext.util.Observable.addListener.
var fields = [
{
name: 'column'
},
{
name: 'leaf',
type: 'boolean'
},
{
name: 'checked',
type: 'boolean'
},
{
name: 'cls',
type: 'string',
defaultValue: 'x-tree-noicon'
},
];
this.dataModel = Ext.define('Filter-' + this.getId(), {
extend: 'Ext.data.Model',
fields: fields,
});
columns: [
{
xtype: 'treecolumn',
width: 200,
itemId: "filter",
dataIndex: 'column' ,
renderer: function (val, metaData, r) {
},
scope: this,
},
],
listeners: {
'checkchange': Ext.bind(function (node, checked,eOpts) {
},
scope: this
The checkboxes you are seeing are not part of the selection behaviour. Instead, they come from the checked configuration on the NodeInterface class.
Your tree panel is using the default selModel, which is row-based selection, with no deselect option. If you want the in-tree checks to control the selection, you'll need to configure that manually, probably by listening to change events from the store.
OTH, if all you care about is finding out which items are checked or not, you can use the getChecked() method on the TreePanel

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');

ExtJS: Fetching information from selected store in combo

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)

ExtJs combo loses selected value on store page load

I have an ExtJS 4.1 combo box with a JsonStore and queryMode: 'remote', with paging and filtering, as such:
...
queryMode: 'remote',
allowBlank: true,
forceSelection: true,
autoSelect: false,
pageSize: 25,
typeAhead: true,
minChars: 2,
...
When I load my form with a saved value in this combo box, I load the store passing the saved value as a query (filtering) parameter, to make sure that the selected value is definitely within the returned records, and then I set that value as the combo selected value as such:
mycombo.getStore().load({
params: {
query: displayField
},
scope: {
field: combo,
valueField: valueField,
displayField: displayField
},
callback: function(records, operation, success) {
this.field.setValue(this.valueField);
}
});
So far, so good, the above works fine. The problem is, that if the user then clicks on the dropdown arrow to select another value for the combo, the 1st page of the store is loaded, erasing all previously selected values, and even if nothing is selected, the previously selected value is lost.
This problem is generic, and is quite similar to this question:
ExtJS paged combo with remote JSON store. Display selected value with paging
and can be summarized as such:
In an ExtJS combo box with a remote store and paging, selected values are lost when the loaded page changes.
I tried setting clearOnPageLoad: false for the store, but then each time a new page is loaded, the records are appended to the end of the list. I would have expected this parameter to cache the loaded pages and still show me the correct page while moving back and forth.
So, any ideas on how to keep the selected value while moving between pages? I suppose I could create a record with the selected value manually and append it to the store on each page load until a new value is selected, but this sounds like too much effort for something so basic.
We ended up contacting Sencha support since we have a paid license. This is the answer we got back:
Ext.override(Ext.form.field.ComboBox, {
onLoad: function() {
var me = this,
value = me.value;
if (me.ignoreSelection > 0) {
--me.ignoreSelection;
}
if (me.rawQuery) {
me.rawQuery = false;
me.syncSelection();
if (me.picker && !me.picker.getSelectionModel().hasSelection()) {
me.doAutoSelect();
}
}
else {
if (me.value || me.value === 0) {
if (me.pageSize === 0) { // added for paging; do not execute on page change
me.setValue(me.value);
}
} else {
if (me.store.getCount()) {
me.doAutoSelect();
} else {
me.setValue(me.value);
}
}
}
}
});
Had the same problem, and 'pruneRemoved: false' didn't work (it seems to be used only in grids). This is the solution:
Ext.override(Ext.form.field.ComboBox,{
// lastSelection is searched for records
// (together with store's records which are searched in the parent call)
findRecord: function(field, value) {
var foundRec = null;
Ext.each(this.lastSelection, function(rec) {
if (rec.get(field) === value) {
foundRec = rec;
return false; // stop 'each' loop
}
});
if (foundRec) {
return foundRec;
} else {
return this.callParent(arguments);
}
}
});
Hope it doesn't have negative side effects. I've tested it a bit and it seems OK.
I am experiencing this issue in extjs 6.0.1.
I discovered a work around that might be helpful for others.
I used override for onLoad to add the selected record from the combo to the store prior to calling the base onLoad.
This works because if the selected record is in the page being viewed, the combo is smart enough to not clear the selection. In other words, the reason the selection is being cleared as you page is because the selected record is not in the page you are viewing.
onLoad: function (store, records, success)
{
var selection = this.getSelection();
if (selection)
{
records.unshift(selection);
store.insert(0, records);
}
this.callParent(arguments);
}

Resources