javascriptdatagriddojostoredojox.grid.datagrid

Dojo - Rows disappears from DataGrid after calling sort


I've came across an issue with DataGrid when sorting the grid.

With this isseue, all rows disappears when we execute this sequence of actions in one call flow:

  1. add one Item to the grid's store.
  2. delete one item from the grid's store
  3. save store
  4. call grid.sort.

After calling the grid.sort all rows from grid diapers (although they are still in the store). They are back if we repeat the same procedure.

I have a reproducer code for this, my custom Grid component based on DataGrid is here: MyGrid.js

If you call the addOneDelOne of MyGrid like I'm doing in line 38 of Scenarios.js You will be able to reproduce the issue.

In this code, items are removed from the store if there are more than 4 items.

Also the issue does not appear if we sort the grid if the number of added items are grater than deleted items.

I've tested it on Dojo 1.9 and 1.13


Solution

  • I believe we found the solution for this problem. Issue was with _onFetchBegin method of Dojo's DataGrid.

    When we call sort on DataGrid it actually clears some counters by calling updateRowCount(0).

    One of the counters that is cleared is this.invalidated.rowCount which is actually used by DataGrid and dojo to print the records. The number of printed records is equal to this.invalidated.rowCount value.

    Later, during the grid.sort() call processing, dojo goes to the _fetch(0, isRender); method. This method eventually calls this.store.fetch({...}) which updates the grid based on items returned from store. It is done by callback methods _onFetchBegin and _onFetchComplete. The problem was in _onFetchBegin

    In our case the number of items returned from store was equal to the number row in grid. if(this.rowCount != size) <-- this is false. Mind that we dont use this.invalidated.rowCount here but this.rowCount. this.invalidated.rowCount was set to 0 in updateRowCount(0) previously. Normally, when this condition would be true we would call this.updateRowCount(size); where size is the number of items in the store. And dojo would print the grid with rows. But in our case, this.rowCount and size was the same (we add on record, and remove one record) so we ended up couple lines further in DataGrid

    if(!size){
            this.views.render();
            this._resize();
            this.showMessage(this.noDataMessage);
            this.focus.initFocusView();
        }else{
            this.showMessage();   <- we ended up here. And we we do not update the RowCount :(
        }
    

    If we modify Dojo's DataGrid by adding this.updateRowCount(size); before this.showMessage();

    like this

    else{
            this.updateRowCount(size);
            this.showMessage();
        }
    

    It will be ok.