remember after refresh selected row in extjs grid

26,621

Solution 1

I wrote simple Ext.grid.Panel extension that automatically selects back rows that were selected before store reload. You can try it in this jsFiddle

Ext.define('PersistantSelectionGridPanel', {
    extend: 'Ext.grid.Panel',
    selectedRecords: [],
    initComponent: function() {
        this.callParent(arguments);

        this.getStore().on('beforeload', this.rememberSelection, this);
        this.getView().on('refresh', this.refreshSelection, this);
    },
    rememberSelection: function(selModel, selectedRecords) {
        if (!this.rendered || Ext.isEmpty(this.el)) {
            return;
        }

        this.selectedRecords = this.getSelectionModel().getSelection();
        this.getView().saveScrollState();
    },
    refreshSelection: function() {
        if (0 >= this.selectedRecords.length) {
            return;
        }

        var newRecordsToSelect = [];
        for (var i = 0; i < this.selectedRecords.length; i++) {
            record = this.getStore().getById(this.selectedRecords[i].getId());
            if (!Ext.isEmpty(record)) {
                newRecordsToSelect.push(record);
            }
        }

        this.getSelectionModel().select(newRecordsToSelect);
        Ext.defer(this.setScrollTop, 30, this, [this.getView().scrollState.top]);
    }
});

Solution 2

The straightforward solution is just save somewhere in js index of selected row. Then after reload you could easily select this row by index using grid's selection model.

Get selection model: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.grid.Panel-method-getSelectionModel

var selectionModel = grid.getSelectionModel()

Get selected rows: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.selection.Model-method-getSelection

var selection = selectionModel.getSelection()

Set selected row back: http://docs.sencha.com/ext-js/4-0/#!/api/Ext.selection.Model-method-select

selectionModel.select(selection)

Solution 3

Here is another way to select the previously selected record:

var selectionModel = grid.getSelectionModel()

// get the selected record
var selectedRecord = selectionModel.getSelection()[0]

// get the index of the selected record
var selectedIdx = grid.store.indexOfId(selectedRecord.data.id);

// select by index
grid.getSelectionModel().select(selectedIdx);

For some reason the grid.getSelectionModel().select(record) method wasn't working for me, but selecting by index seems to work.

Edit: found out why grid.getSelectionModel().select(record) method wasn't working. Apparently the store is reloaded, the record instances aren't the same (they have different automatically generated Ext IDs). You have to use selectAt() in this case.

Solution 4

for extjs 4.1.7 users

need a workarround about the statement in

refreshSelection() {

...
Ext.defer(this.setScrollTop, 30, this, [this.getView().scrollState.top])

}

thus setScrollTop no longer exists

so a working soluction is add me.getView().preserveScrollOnRefresh = true;

in initComponent

Ext.define('PersistantSelectionGridPanel', {
    extend: 'Ext.grid.Panel',
    selectedRecords: [],
    initComponent: function() {
        this.callParent(arguments);

        this.getStore().on('beforeload', this.rememberSelection, this);
        this.getView().on('refresh', this.refreshSelection, this);

        //-------------------------------------------
        me.getView().preserveScrollOnRefresh = true;
        //-------------------------------------------
    },
    rememberSelection: function(selModel, selectedRecords) {
        if (!this.rendered || Ext.isEmpty(this.el)) {
            return;
        }

        this.selectedRecords = this.getSelectionModel().getSelection();
        this.getView().saveScrollState();
    },
    refreshSelection: function() {
        if (0 >= this.selectedRecords.length) {
            return;
        }

        var newRecordsToSelect = [];
        for (var i = 0; i < this.selectedRecords.length; i++) {
            record = this.getStore().getById(this.selectedRecords[i].getId());
            if (!Ext.isEmpty(record)) {
                newRecordsToSelect.push(record);
            }
        }

        this.getSelectionModel().select(newRecordsToSelect);
    }
});
Share:
26,621
Rick Weller
Author by

Rick Weller

Updated on April 10, 2020

Comments

  • Rick Weller
    Rick Weller about 4 years

    I have a problem. I use extjs grid. This grid will be refreshed every seconds.

    I refresh with this function:

    ND.refresh = function() {
        ND.commList.load();
    }
    
    
    var refreshSeconds = refreshRate * 1000;
    var t = setInterval('ND.refresh()', refreshSeconds);
    

    But when someone selected a row to highlight it it reset this selection. How can I remember the selected row and highlight it again after refresh?

    This is my grid:

    var grid = Ext.create('Ext.grid.Panel', {
         autoscroll: true,
         region: 'center',
         store: ND.dashBoardDataStore,
         stateful: true,
         forceFit: true,
         loadMask: false,
         stateId: 'stateGrid',
    
         viewConfig: {
             stripeRows: true
         },
         columns: [{
             text: 'Vehicle',
             sortable: true,
             flexible: 1,
             width: 60,
             dataIndex: 'vehicle'
         }, {
             text: 'CCU',
             sortable: true,
             flexible: 0,
             width: 50,
             renderer: status,
             dataIndex: 'ccuStatus'
         }]
     });
    

    Thanks guys

    • sbgoran
      sbgoran over 12 years
      What version of Ext do you use? Test code (in JsFiddle) would be nice so we have a starting point to help you in a best possible way.
    • Rick Weller
      Rick Weller over 12 years
      Thanks for your reply. I use EXT 4.0.2. i don't know fiddle. How do i need to put it in there?
  • Rick Weller
    Rick Weller over 12 years
    i think i do something wrong because it isnt working. i use a listener: itemclick: function () { var selectionModel = grid.getSelectionModel(); var selection = selectionModel.getSelection(); selectionModel.select(selection); var data = grid.getSelectionModel().selected.items[0].data; ND.internals.load({ url: ND.url });
  • Andrey Selitsky
    Andrey Selitsky over 12 years
    you should restore selection after your reloading is completed. So it's a good idea call selectionModel.select in grid's store load event.
  • Rick Weller
    Rick Weller over 12 years
    hey looking good. I have only two issues. In firefox i get this error: this.selectedRecords[i].getId is not a function. When i use it in chrome it will always select the first row after refresh. Any idea what that could be? THANKS for the help :)
  • Rick Weller
    Rick Weller over 12 years
    the error in firefox is fixed. But it is still going to the first row
  • Rick Weller
    Rick Weller over 12 years
    jsfiddle.net/ZemWB is where i placed my grid with your code. Can you see what is wrong with it?
  • sbgoran
    sbgoran over 12 years
    First of all in that jsFiddle you created ND is undefined. I guess you copy/paste code from your project but it is not runnable. I guess you could have issues if you haven't set idProperty in your model (look at my test fiddle)
  • Rick Weller
    Rick Weller over 12 years
    You are my hero! I didn't had a idProperty in my model. Thanks thanks thanks
  • sbgoran
    sbgoran over 12 years
    No problem, glad I could help :)
  • Rick Weller
    Rick Weller over 12 years
    I have no another issue :) I got a list higher then the screen, if i scroll down, select a row the row will stay selected but after refresh it scrolls back up. Can i do something about that?
  • sbgoran
    sbgoran over 12 years
    Well you could try something with Ext.view.Table.saveScrollState method and Ext.grid.Panel.setScrollTop method. You can fetch view object of a grid panel with Ext.grid.Panel.getView method. Of course use appropriate methods in rememberSelection and refreshSelection methods of a custom extension.
  • sbgoran
    sbgoran over 12 years
    I updated code in answer, so now panel set vertical scroll to its previous value. You can play with solution in that fiddle.
  • Rick Weller
    Rick Weller over 12 years
    hey Sbgoran. There is an issue what i can't fix. When the page loads i get an error this.el is undefined and isn't loading the store. When the refresh function start it loads the store. I tried to remove this code and store loads fine. Do you have an idea what this.el could be?
  • sbgoran
    sbgoran over 12 years
    I really don't know what is wrong in your code, but I added a check in rememberSelection that shouldn't do any harm, try it out, it might help.
  • Ruan Mendes
    Ruan Mendes about 12 years
    This is great but it should be a plugin, not a base class!
  • sbgoran
    sbgoran about 12 years
    @JuanMendes You are probably right, but I guess that answer shows the main idea for solution to a problem it should not be very hard to make plugin out of this. Maybe I'll do it when I get a chance, should be fun thing to do :)
  • Jerinaw
    Jerinaw over 10 years
    In your initComponent you try to use "me" without defining it.
  • sbgoran
    sbgoran over 10 years
    @comecme It was a while ago, so if I remember well reason lays in a way Ext grid render its view, I think that they used defer call during grid panel rendering inside library itself, so if you call setScrollTop immediately, you'll get some sort of "null variable" or "non existent DOM element" error. It could be that later versions of Ext removed this and that it is not necessary anymore.
  • Eagle_one
    Eagle_one about 9 years
    #{GridPanel-ID}.getSelectionModel().select(index, true); Works good for me :-)