'Retain the selection in previous page when moved to next in ExtJS Combo box
I have the ExtJs form combo which shows the values in the dropdown as checkbox and the value to select. I have used the pagination to list all the values with no of pages. I need the selected value to be retained in the current page even when we move to next or previous page and comes back to the same page(without selecting any thing in prev, next pages).
Code:
Ext.create('Ext.form.ComboBox', {
id: 'ageComboPickerReport',
name: 'ageComboPickerReport',
maxHeight: 150,
margin: '0 5 0 0',
width: 150,
emptyText: "Select tags",
listConfig: {
getInnerTpl: function (displayField) {
return '<div class="x-combo-list-item"><img src="" class="chkCombo-default-icon
chkCombo" /> {' + displayField + '}</div>';
},
autoEl: { 'q-name': 'rpt-age-criteria-list'
}, labelAlign: 'top',
pageSize: 25,
displayField: 'age', valueField: 'id', forceSelection: true, store: me.ageStore,
//Disable Typing and Open Combo
onFocus: function () {
if (!this.isExpanded) {
me.ageStore.load()
this.expand()
} this.getPicker().focus();
}
}),
Could any one tell me how to retain the selected value in the page when move to other page and comes back
Solution 1:[1]
I faced a very similar issue, in my case I had a grid with checkbox selection model, and I wanted to retain the selected rows during moving between pages. I am quite sure (although not 100%) that there is no built-in functionality for that in ExtJS. I can tell what I did, hope it helps, although you have to adopt it because it is not for ComboBox
, but for Grid
.
Since this is a paged store, not all of the records are loaded, only the ones that are currently on the displayed page. (I assume your store is remote because I see you call load
on it.) So to achieve what you like, you need to:
- keep track of the selected record ids to be able the reset selection on page,
- keep track the items (records) themselves as well, since you will likely need them,
- after a page is loaded and displayed, set the selection accordingly.
(This solution can have issues, so you need to be careful. Depending on the use case, it is possible for example that the user selects something, goes to another page and come back, but the previously selected row is no more available (it was deleted by someone else). You have to consider whether it affects you.)
The complete code is complicated and not general enough to share it, but I can outline the steps I did:
- Set up two
data
entries inviewmodel
to track the selected record ids and items (records):
data: {
multiSelection: {
ids: {},
items: [],
},
}
- Add listeners to the grid's
select
anddeselect
events in theview
:
listeners: {
select: 'onGridSelect',
deselect: 'onGridDeselect',
},
- Create
onGridSelect
andonGridDeselect
functions in thecontroller
, and also add aisDataChanged
variable to the controller to indicate whether the store was changed (it is changed on each paging). It is important because I will programatically change the selection, and I don't want my listeners to be executed in this case, only when the user interacts. Like this:
isDataChanged: false,
onGridSelect: function(selModel, record, index, eOpts) {
if (isDataChanged) {
return;
}
const viewModel = this.getViewModel(),
multiSelection = viewModel.get('multiSelection');
multiSelection.ids[record.getId()] = true;
Ext.Array.push(multiSelection.items, record);
},
onGridDeselect: function(selModel, record, index, eOpts) {
if (isDataChanged) {
return;
}
const viewModel = this.getViewModel(),
multiSelection = viewModel.get('multiSelection');
delete multiSelection.ids[record.getId()];
Ext.Array.remove(multiSelection.items, record);
},
- Finally, add a listeners to the store to detect changes, this will be called every time the user moves between pages. This is a little tricky, because I need to access the grid from the store listeners which is not very ExtJS like, but I had to (
store
needs to be the grid's store:
store.on('datachanged', function(store, eOpts) {
// this part you have to figure out, my solution is way too specific
// for share
const grid = ...;
// this was important for me, if the store is really changed,
// deleted, added rows etc., I deleted the selection, but
// you can consider it
if (store.getUpdatedRecords().length > 0 ||
store.getRemovedRecords().length > 0 ||
store.getNewRecords().length > 0) {
// access the `viewmodel` and reset `multiSelection` data entries to
// default, I `return` here to skip the rest
return;
}
// disable listener
grid.getController().isDataChanged = true;
const selModel = grid.getSelectionModel(),
multiSelection = grid.getViewModel().get('multiSelection');
// deselect everything
selModel.deselectAll();
// get an array of the saved selection and find out, which
// record from the current page is in the saved multiSelection
const selected = [];
Ext.Array.each(grid.getStore().getRange(), function(record) {
if (multiSelection.ids[record.getId()]) {
Ext.Array.push(selected, record);
}
});
// apply selection to current page
selModel.select(selected);
// enable listener
grid.getController().isDataChanged = false;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Peter Koltai |