5

I have an infinite scrolling grid panel in my app (ExtJs 4.2.1), similar to this example. The user can click a refresh button, then the rows of the grid must be updated with data from the DB. I call store.load() in the refresh button handler, and my data gets updated. This works nice for the first rows of the grid panel (records from page 1). But it does not work if the user scrolled down the grid. After store.load, the grid resets the scroll position to the top.

I am asking for a solution to reload the store and refresh the grid which keeps the current selection and also the current scroll position. The good thing: I have the global index of each record in the store.

Here is my code, there are thousands of entries in the DB.

Grid panel:

Ext.define('MyApp.view.MyGrid', {
    extend: 'Ext.grid.Panel',
    requires:[ 'Ext.grid.plugin.BufferedRenderer'],
    alias: 'widget.myGrid',
    plugins: 'bufferedrenderer',
    loadMask: true,
    selModel: {
        mode: 'MULTI',
        pruneRemoved: false
    },
    itemSelector: 'div.workspaceItemSelector',
    overItemCls: 'workspaceItemMouseOver',
    trackOver: true,
    autoScroll: true,
    verticalScroller: { variableRowHeight: true },
    defaultSortOrder: 'ASC',

    // and some column definitions ...
});

Store:

Ext.define('MyApp.store.MyStore', {
    extend: 'Ext.data.Store',
    autoLoad: false,
    buffered: true,
    pageSize: 100,
    leadingBufferZone: 100,
    remoteSort: true,
    model: 'MyApp.model.MyModel',
    storeId: 'myStore',
    proxy:  {
        type: 'rest',
        url: 'someUrl',
        reader: { type: 'json', totalProperty: 'total', root: 'items' }
    }
});

There is a solution for unbuffered grids, which does not work for me.

Community
  • 1
  • 1
Christoph
  • 1,023
  • 11
  • 23
  • try this [guaranteeRange](http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Store-method-guaranteeRange) – MMT Jun 21 '13 at 08:59
  • guaranteeRange is deprecated, they advice to use getRange(). But both will not reload the store, it just returns the outdated records. – Christoph Jun 21 '13 at 09:16
  • Can you please change store URL from http to https in the given example? It is giving error now. – Moksh Aug 30 '20 at 09:10

2 Answers2

4

On load controller function:

loadStoreFunction : function (grid) {

    var storeGrid = grid.getStore();
    var currentElement = grid.getSelectionModel().getSelection();
    storeGrid.load({
        scope: this,
        callback: function(records, operation, success) {
            grid.getView().focus();
            grid.getSelectionModel().select("index of currentElement"); // last position.
            grid.getSelectionModel().select(storeGrid.getRange().length-1); // last insert
                    storeGrid.loadPage(1+(index/totalCount),options); // Load row's page calculated.
        }
    });

}
mfruizs
  • 770
  • 14
  • 20
  • I tried your solution, scrolled down to record 250, selected, and pressed the refresh button. The selectionModel.select() does not work (does not scroll or select), since the store has no record at this index, only the first 100 records. I am pretty sure that the correct solution must somehow include to load the correct page (or pages?). – Christoph Jun 21 '13 at 07:32
  • Has it got pagingtoolbar ? then, you need calculate the row position with an algorithm ( calculate pag. and index position in this pag. ) – mfruizs Jun 21 '13 at 09:08
  • yes, there is a paging toolbar. But it should not have anything to do with the scroll position of the grid. – Christoph Jun 21 '13 at 09:21
  • Maybe, scrollBy it's that you looking for. http://docs.sencha.com/extjs/4.1.0/#!/api/Ext.Component-method-scrollBy – mfruizs Jun 21 '13 at 10:08
  • scrollBy requires you to give deltaX, deltaY, I do not have these values and do not see how to compute them reliably. I hope to use Ext.selection.Model.select, and just prove an index or an id, or something similar. – Christoph Jun 21 '13 at 12:38
  • this (**grid.getSelectionModel().select(storeGrid.getRange().length-1);**) is working for you? ... It is, we replace **storeGrid.getRange().length-1** and find the new position row in the store, **store.find(...)** http://docs.sencha.com/extjs/4.1.0/#!/api/Ext.data.Store-method-find – mfruizs Jun 21 '13 at 12:47
  • I think your answer is on the correct path. It works, as long the user does not scroll down. I just could not find how to reliably load the correct data when the user scrolled down to page 1+. – Christoph Jun 21 '13 at 12:51
  • Max 100 rows per page --> NumTotalRows/numPerPag = Number of pages. index% (Number of pages) = your_row_pag ... now, get the row position in this page. – mfruizs Jun 21 '13 at 12:52
  • I just found loadPage http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.data.Store-method-loadPage It works for me if I do storeGrid.loadPage(1+(index/totalCount),options). Please update your answer and I can accept it. – Christoph Jun 21 '13 at 13:18
0

Define the following in your grid's viewConfig:

viewConfig : { preserveScrollOnRefresh: true }

slashwhatever
  • 732
  • 8
  • 24