Fine control scrolling to newly inserted row with scroller

Fine control scrolling to newly inserted row with scroller

sronsieksronsiek Posts: 52Questions: 11Answers: 0

Version Info: DT 1.11.3 scroller 2.0.5

I'm rendering a sorted table (~10k) rows with paging, deferred render and scroller enabled. serverSide is false so the entire table data is sent by the server via ajax, but scroller manages selective rendering of viewable data. On insertion of a new row I'd like to scroll so the new row is displayed at the top of the visible portion of the table and highlighted. The issue I'm encountering is that the DOM elements do not exist after insert & draw(). I've found a workaround whereby I call row.scrollTo() to bring the new row into view (creating the DOM elements), setting a timeout, after which I can access the row in the DOM and do a fine-grained scroll using scrollIntoView() and apply a css class for te highlighting.

The issue is that a timeout of 1s is required, and both scroll operations are visible to the user - it looks pretty ugly and it feels like I'm doing something wrong.

Is there a better, 'DataTables' way of achieving this?

Code:

Note: <%= raw( data ) %> resolves to an array of row data.

 var row = oTable.api().row.add( <%= raw( data ) %> ).draw();

  // Next line scrolls to bottom of table: maybe row.index() is not the *display* index?
  // oTable.api().scroller.toPosition( row.index(), true );

  // Next line scrolls new row into view - but we need to wait until the tr
  // has been created in the DOM before it can be retrieved using a jquery selector.
  row.scrollTo( true );
            
  setTimeout( function() {
    var id = row.data()[0]; 
    var tr = j('#'+id).parents('tr').get(0)
    if (tr) {
      // Next line very nicely scrolls so the new row is the first row of the table!
      tr.scrollIntoView({ behavior: 'smooth', block: 'start' });
      j(tr).addClass( 'row_selected' )   // Highlight the new row
    }
  }, 1000);  // We need a full second with (10 000 rows)

Answers

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,736
    edited January 2022

    Sounds like the problem you are trying to solve is applying the classname and not with scrolling to the correct row. Assuming that is the case maybe you can add the row as a jQuery object with the class added when the row is added. See this example, based on the client side 10000 row example.

    http://live.datatables.net/canuxuti/1/edit

    Kevin

  • sronsieksronsiek Posts: 52Questions: 11Answers: 0

    Thank you @kthorngren, that indeed solves the highlighting. But unlike your linked code, in my table the new row does not scroll to the top of the table, but some position south of the middle of the table.

    Is it maybe possible to get the display index (ie not row.index()) position from the row object after draw(), and use oTable.api().scroller.toPosition( dindex ) instead?

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,736
    edited January 2022

    You could use column().data() with the selector modifier of {order: 'applied'} to get the data in the order displayed. Then use indexOf() to get the index in the array which should match the index in the scroller buffer. If you have a column with unique data this option might work. For example:
    http://live.datatables.net/canuxuti/2/edit

    Kevin

  • sronsieksronsiek Posts: 52Questions: 11Answers: 0

    Thanks, tried that but the result is exactly the same as for row.scrollTo(): For me that function does not scroll to the top of the table body - from the docs I cannot tell if it's supposed to. scrollIntoView offers some finer control options, perhaps scrollTo should also.

    So the best solution I found is to add a scrollme class to the row, call row.scrollTo(), then in drawCallback check if a tr with scrollme exists and use scrollIntoView to get it to the top. This way the second scroll follows the first much more closely so it almost looks like a continuous operation. For some reason I still have to apply a 10ms timeout - DT is still doing something

  • kthorngrenkthorngren Posts: 20,141Questions: 26Answers: 4,736
    edited January 2022

    Can you post a link to your page or PM the developers a link so they can take a look?

    Maybe you are doing some columns.render function or something else that is causing a timing issue.

    Kevin

Sign In or Register to comment.