-1

In DataTables I can automatically add an ID to each <tr> row of my table by specifying DT_RowId in my ajax response data. This means that each row gets an id attribute, e.g.

<tr id="row_45">
    <td>foo</td>
    <td>bar</td>
</tr>

This is useful in my application because it means I can use URL's such as: /#row_45 and show row 45 at the top of the page.

This works fine providing the rows are on page 1.

My application shows 250 rows per page and each page is generated with an ajax request. Sometimes there are >1000 pages. So if I tried to open row 999 (/#row_999) in the same way, it doesn't work, because the data for it isn't within the document.

I am using pagination and DataTables in "serverSide" mode. This means that all of the data is not present on page load - making this problem harder. If I click "page 3" in the pagination it does an ajax request for records 750 - 1000 (250 per page).

Does anyone know if there's a workaround to this?

DataTables version 1.10.16

Andy
  • 5,142
  • 11
  • 58
  • 131
  • 1
    How does row id, which you assign client side (`row_45`, in your example) corresponds to your back end data? Is there some explicit id field/attribute? Where to you should scroll if required row is filtered out? –  Feb 27 '19 at 06:09
  • I have the same question as ygorbunkov. If the row number corresponds to the primary key of your database table, how will the client side know which page to go to in case some rows are deleted, or depending on current datatable sort and filters. Or are you assigning row numbers sequentially to all rows returned via ajax? – Cave Johnson Mar 05 '19 at 01:12
  • can you please post the code that you have tried to do this ? – Zulqarnain Jalil Mar 05 '19 at 11:22
  • Great use case, but I found it hard to provide guidance since you did not provide any code or JSFiddle that might have shaped a well defined solution space where people can add missing bits and pieces. – Sascha Gottfried Mar 05 '19 at 14:58

4 Answers4

1

This is how StackOverflow refers to a unique entity using a URI and uses a DOM identifier to navigate within the webpage rendered by the browser.

https://stackoverflow.com/questions/55000320/datatable-with-filter-data-dynamically/55000876#comment96759679_55000876

You have to apply a similar principle to your application. I think DataTables docs and especially the examples section cover a lot of use cases for server-side processing mode.

You have to design this into your application. There is no simple workaround.

Docs

Featured content

Sascha Gottfried
  • 3,303
  • 20
  • 30
  • That's great except Stack Overflow doesn't use DataTables.... Anyway I've posted some notes on what I found. The principles you have outlined are still relevant. – Andy Mar 06 '19 at 10:01
0

Is it safe to assume that the number in the id is a consecutive running number form 0?

Then we could determine the page number from the id and make dataTables load the correct page:

var rowIdx = '#row_45'.split('_')[1];
var table = $('#substancesTable').DataTable();

// Page number
var pageNo = Math.floor(rowIdx/table.page.info().length);

// Load page
table.page(pageNo).draw('page');

// Add scroll function if needed

Edit: if a server request is needed to determine the page where the row is, then it is made first:

// Make an ajax-call to get the rowIdx
var rowIdx = someAjaxFunctionToRequestThePageNo( '#row_45'.split('_')[1] );

var table = $('#substancesTable').DataTable();

// Page number
var pageNo = Math.floor(rowIdx/table.page.info().length);

// Load page
table.page(pageNo).draw('page');

// Add scroll function if needed
lofihelsinki
  • 2,491
  • 2
  • 23
  • 35
  • 1
    I'm having deja vu :) –  Mar 04 '19 at 13:44
  • Your code won't work with `serverSide: true` either, since there's no row with id 'row_45' in your DOM, as it hasn't been loaded yet. Despite of parsing row number where it is supposed to be known, can you explain how is your code different from mine? –  Mar 04 '19 at 13:49
  • It does work, it doesn't look for element with id 45 in the DOM. It only parses the number from the id-string and assumes the rows go from 0-n consecutively. `table.page(pageNo).draw('page')` moves dataTables to the page where `#row_45` is supposed to be and draws the page. It makes the needed ajax-call in the process. – lofihelsinki Mar 04 '19 at 14:16
  • Your code jumps to specific row **position** (which OP could have done by assigning explicitly `rowIndex =45` two weeks back, as I posted my original answer) but not the row as data entry, which position is dependent on sorting/filtering and is known server side only by the time you load the page. –  Mar 04 '19 at 14:38
  • ...And still lot is no different from mine. –  Mar 04 '19 at 14:39
  • No it's not a lot different, it just has a different approach to getting the page no and a different way to define the `table` var, with which the asker had some trouble with. It also moves the user to the correct page `draw('page')` , so basically there is quite a few differences after all. – lofihelsinki Mar 05 '19 at 05:20
  • Neither of the answers are correct. The issue - as I've discovered - is that you *first* have to make an ajax call to calculate which page the requested data will appear on. The `row_` ID's are not necessarily sequential as there is other functionality in the application to do a search which could result in, for example, `row_202` and `row_217` being next to each other. However, you don't know which page those rows are on - *that is the whole problem!* So it has to do an initial ajax call to calculate the page...*After* this it can it use DataTable's js to open that page and scroll to the row. – Andy Mar 05 '19 at 08:49
  • The whole answer was based on the assumption that the id's are sequential. That's stated on the first line of the answer. – lofihelsinki Mar 05 '19 at 08:59
  • Yes, *you* have assumed the ID's are sequential in *your* answer... it doesn't actually say that in the question. I haven't awarded the bounty because none of the answers addressed the actual issue that you can't even do this unless you make an ajax call to calculate the page number. The question clearly states "all of the data **is not** present on page load". The js about scrolling to a given row is only half of the answer, and furthermore only works if all the data is within the DOM - otherwise how would it even know where the row was? It wouldn't - that's why the initial ajax call is used – Andy Mar 05 '19 at 09:03
  • 1
    @Andy: Did you figure out the necessity of ajax call which will return desired row position before or after my last comment below my answer, which I left a week ago? The reason you didn't get proper answer is the question wording, in the first place - provided HTML sample is irrelevant and useless, crucial `serverSide` option was mentioned more then week after the question and first answer was posted. –  Mar 05 '19 at 10:02
  • 1
    @Andy: Without knowing wider context (data structure, environment, etc) there's no answer more precise than mine and this one (which is, basically, duplicating it with great added value in form of parsing number out of the string which you create manually by adding `row_` to the number :) you may expect –  Mar 05 '19 at 10:05
-3

The key to solving this - which nobody really addressed - is this: As stated in the question we are using DataTables in serverSide mode. It has pagination and when you click on each page it makes a separate ajax request to load just the data for that page. So for example if you click page 2, 3, 4 it is making 3 separate ajax requests - one per page. Herein lies the problem - if you want to scroll to row 999 you have to answer the question "on what page does row 999 appear"?

The only way you can do this is to call a serverside script which will calculate the page number and return it to the js used by the application. The reason this is needed is because if, for example, you were on page 1 and row 999 happens to be on page 4, you do not have the rows for page 4 anywhere in the DOM; indeed you wouldn't have these at all until you click page 4 on the pagination.

So, the first thing to do is to make an ajax request to an endpoint that calculates this page number and returns an integer. How the page number is calculated depends on the application. @Sascha Gottfried has kind of hinted at this in their answer. In our application the rows are not sequential, i.e. you could have row_999 followed by row_1052:

  • If they are sequential you could do something equivalent to ceil(999/250) which would tell you that row 999 appears on page 4, when there are 250 records per page.

  • If they are NOT sequential (as is the case in my application) the endpoint must provide a means of calculating it. There is no set answer to how you do this. In our application it depends on multiple search/filter parameters which can result in rows being out of sequence. However all the script needs to do is return an integer, e.g. echo json_encode(['page' => 4]);

Once this number is calculated you have to trigger the equivalent click for "page 4" (or whatever page number you want) in DataTables. This can be done in jquery by targetting the anchors inside .dataTables_paginate.

Then, you have to scroll down to the row - some information was provided by @ygorbunkov relating to this. Missing or not obvious is that you have to wait until the ajax request to populate the DataTable has completed before you attempt to scroll to the row - otherwise the data is not present to scroll to. This can be done by nesting a .done() in the ajax request to the endpoint which gets the data for page 4.

Although this is an incomplete answer these are the principles that are required. In the end we actually abandoned doing this in our application because the complexity of trying to implementing it outweighed any benefit!

E_net4
  • 27,810
  • 13
  • 101
  • 139
Andy
  • 5,142
  • 11
  • 58
  • 131
  • 1
    Now this is a good starting point for a question with a bounty. Nevertheless I think you have not outlined clearly enough the user interaction pattern to browse through a large entity collection with DataTables such that others could translate this into the technical domain of viable solutions using DataTables and web applications in general. – Sascha Gottfried Mar 06 '19 at 10:23
  • 1
    _which nobody really addressed_ Didn't @ygorbunkov exactly this in his comments, that there is no solving this without a server request to get the page number? – lofihelsinki Mar 07 '19 at 15:13
-4

Native Javascript has scrollIntoView :

var el = getElementById('row_4');
el.scrollIntoView(true);
tinwan
  • 307
  • 1
  • 4
  • Doesn't work because `row_999` is not within the scope of the page - that is the problem the question is asking about. – Andy Feb 18 '19 at 09:21
  • You can use scrollIntoView after the data of ajax's request have been rendered in page – tinwan Mar 04 '19 at 08:52