Fine control scrolling to newly inserted row with scroller
Fine control scrolling to newly inserted row with scroller
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
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
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?You could use
column().data()
with theselector 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
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, perhapsscrollTo
should also.So the best solution I found is to add a
scrollme
class to the row, callrow.scrollTo()
, then indrawCallback
check if a tr withscrollme
exists and usescrollIntoView
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 somethingCan 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