Author Topic: RefreshCell in a filtered grid updating the wrong cell  (Read 903 times)

ronrosell

  • Pro Enterprise
  • Newbie
  • *
  • Posts: 10
    • View Profile
RefreshCell in a filtered grid updating the wrong cell
« on: March 22, 2022, 10:04:42 am »
Hi Paramvir,

This may be because I've been coding for too long  ;) but I've got a bug that I can't figure out.

Below is the snippet of troublesome code. What I'm doing is letting the user double-click a cell. That sends an Ajax message to the server to toggle the cell's value (active/suspended). The server responds with the new cell contents, and a message displayed elsewhere on the screen.

It all works fine EXCEPT when the table is filtered. Let's say I filter it down to one row. It appears that the row that's being captured on the 4th line (var row = ui.rowIndx) is returning the row number in the filtered array (ie. 0) rather than the overall row number. Later on, in line 14, the cell in the 0 row of the entire table is changed (that is, in the hidden row at the very top of the table). So, while everything gets to the server alright, the wrong cell in the table gets updated by the response.

What I want to do is reference the row that the "clicked" cell is in on the entire, unfiltered table, and update the fourth cell (dataIndx 3) in that row.

I'm guessing I need something different in line 4 or 14, but I'm not sure what.

          if(ui.dataIndx==3){
            var usr = document.getElementById("user").value;
            var com = document.getElementById("co").value;
            var row = ui.rowIndx;
            console.log(row);
            var grid = this;
           $.ajax({
            type: "POST",
            dataType: "json",
            url: "/suspenduser",
            data: {seq:ui.rowData[0],val:ui.rowData[3],user:usr,co:com},
            success: function(data){
            traineelist[row][3]=data.val;
           grid.refreshCell( { rowIndx: row, dataIndx: 3 } );
           $("#message").html(data.message);
           $('#message').show();
           $('#message').fadeOut(3000);
            },
});
        }

paramvir

  • Administrator
  • Hero Member
  • *****
  • Posts: 6263
    • View Profile
Re: RefreshCell in a filtered grid updating the wrong cell
« Reply #1 on: March 22, 2022, 11:32:45 am »
Hi Ron

It looks like traineelist variable is the cause of mentioned issue.

Please use this
Code: [Select]
grid.updateRow( {
rowIndx: row,
newRow: { 3: data.val }
});

instead of
Code: [Select]
traineelist[row][3]=data.val;
grid.refreshCell( { rowIndx: row, dataIndx: 3 } );
« Last Edit: March 22, 2022, 12:16:35 pm by paramvir »

ronrosell

  • Pro Enterprise
  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: RefreshCell in a filtered grid updating the wrong cell
« Reply #2 on: March 22, 2022, 01:23:37 pm »
Hi Paramvir,

Unfortunately, that didn't do the trick. In fact, it made it worse ... now the cell doesn't update even when the table is unfiltered.  Before, it would update when it was unfiltered (ie every row was the original, unfiltered row) but not when it was filtered down to a few rows. 

What appears to be throwing it off is that the row reference (rowIndx) retrieved when the user double-clicks the cell is the row number relative to the filtered data being displayed, while when updating the cell after the ajax transaction completes the rowIndx always goes to the corresponding row in the unfiltered (total) list, not the filtered list.

Example: if I have 100 rows, and I filter out the first 20 and the last 77, leaving three rows, the rowIndx value at the start of the transaction will be 0,1 or 2(one of the three visible rows) but when the response returns the cell in row 0, 1, or 2 of the original table gets updated. If I reset the filter, I can see the changed cell in that row near the top.

traineelist is a reference to the source array of data (dataModel: {data: traineelist},)

The 4th zero-based element in each sub-array within traineelist holds the Status value. Updating that, and then calling grid.RefreshCell, works well except when the row references don't correspond to the original data array (ie the table was filtered at the start of the transaction.)

Sorting doesn't cause any problem, only filtering.

Using updateRow as you suggested doesn't appear to correct that.  I think what I'm looking for is a way to reference the row by its original position in the source data, not its current position in the filtered row.

Here's the code I have, with your change and my original part commented out, along with some additional comments.

if(ui.dataIndx==3){
            var usr = document.getElementById("user").value;
            var com = document.getElementById("co").value;
            var row = ui.rowIndx;   //this is row 0 of the filtered table, row 21 of the unfiltered table in my example
            var grid = this;
           $.ajax({
            type: "POST",
            dataType: "json",
            url: "/suspenduser",
            data: {seq:ui.rowData[0],val:ui.rowData[3],user:usr,co:com},
            success: function(data){
            console.log(row);  //shows row relative to the current display
            console.log(data.val);   //shows returned value, correctly
            console.log(ui.rowData[0]);   //shows col 0 value (a hidden identifier for the record on the server) correctly.

            //old code; cell would update if grid was unfiltered
            //traineelist[row][3]=data.val;
            //grid.refreshCell( { rowIndx: row, dataIndx: 3 } );  //this is updating row 0 of the total, unfiltered table

              //new code; cell never updates   
               grid.updateRow( { 
               rowIndx: row,
          newRow: { 3: data.val }
            });


           $("#message").html(data.message);
           $('#message').show();
           $('#message').fadeOut(3000);
            },
});
        }

The server receives the call and responds with the correct status change (Active or Suspended) but the cell doesn't update. Previously, it did with the column unfiltered.

Thanks for your help Paramvir. Please let me know if anything stands out.

  UPDATE: I tried a test where, using my old code, I used:

traineelist[4][3]=data.val;
grid.refreshCell( { rowIndx: row, dataIndx: 3 } );

This locks the ajax return to updating the 5th array in the original data. 

Then I tried filtering the data so that the original zero-based row 4 was always visible. That worked. If I double-clicked the cell that was originally in row 4, it would update even if, after filtering, it was in row 3 or something.

So this is telling me that the problem is finding the correct array element to update in traineelist, yes?
« Last Edit: March 22, 2022, 01:43:42 pm by ronrosell »

ronrosell

  • Pro Enterprise
  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: RefreshCell in a filtered grid updating the wrong cell
« Reply #3 on: March 22, 2022, 02:33:31 pm »
I've got a workable workaround for the issue. If there's a better way to identify the original 0-based position of a row in the source data array, please let me know!

1) The first item in each element in the array is a sequence number identifying a record in the database
2) As the data set is built, I'm now prepending that with a zero-based index number.  So, if the first sequence number is 23432343, it becomes 0-23432343
3) In the browser, I'm parsing that into an original row reference (ie the position of element in the data array) and the original sequence number.
4) I'm referencing that original row reference when updating the traineelist source data, but the displayed rowIndx when updating the cell.

Here's the code:

 cellDblClick: function( event, ui ) {
            var sequence = ui.rowData[0].split("-") //gets the original sequence number and the row index number in the source data
            if(ui.colIndx==2){
            getreg(sequence[1])} //calls a function to display a registration form
        else{
            if(ui.dataIndx==3){  //this is the "active/suspended" status column;
            var usr = document.getElementById("user").value;
            var com = document.getElementById("co").value;
            var row = ui.rowIndx;         
            var grid = this;
           $.ajax({
            type: "POST",
            dataType: "json",
            url: "/suspenduser",
            data: {seq:sequence[1],val:ui.rowData[3],user:usr,co:com},
            success: function(data){
            traineelist[sequence[0]][3]=data.val; // uses the prepended original element number from the source data
            grid.refreshCell( { rowIndx: row, dataIndx: 3 } );
           $("#message").html(data.message);
           $('#message').show();
           $('#message').fadeOut(3000);
            },
});
        }
        }},
« Last Edit: March 22, 2022, 02:35:27 pm by ronrosell »

paramvir

  • Administrator
  • Hero Member
  • *****
  • Posts: 6263
    • View Profile
Re: RefreshCell in a filtered grid updating the wrong cell
« Reply #4 on: March 22, 2022, 03:16:21 pm »
updateRow is supposed to work fine as rowIndx passed to this method is in context of filtered data. Could you please share a simple and small test case on jsfiddle reproducing the issue so that I can check it

Alternatively you can use filterModel: {hideRows: true}, it filters data without changing rowIndx of the rows

https://paramquery.com/pro/api#option-filterModel
« Last Edit: March 22, 2022, 03:19:58 pm by paramvir »

ronrosell

  • Pro Enterprise
  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: RefreshCell in a filtered grid updating the wrong cell
« Reply #5 on: March 22, 2022, 04:08:37 pm »
Thank you Paramvir!

filterModel {hideRows:true} seems to be what I was looking for!  I can back out my workaround with the next server update.

I'll also try to get a jsfiddle up so you can check on the issue I ran into using the updateRow approach (once the dust settles here in a day or two ... I'm working around the clock at the moment.)

Is there any performance downside to using the filterModel approach?  Does that slow down grid filtering or anything like that? (It doesn't appear to, but I thought I'd check with you.)

Thanks again!

paramvir

  • Administrator
  • Hero Member
  • *****
  • Posts: 6263
    • View Profile
Re: RefreshCell in a filtered grid updating the wrong cell
« Reply #6 on: March 22, 2022, 10:26:50 pm »
Hi Ron

There is no performance issue with using it, only issue is that hideRows mode of filtering doesn't work well with paging.