I am using Doctrine and trying to implement an infinite scroll on a collection of notes displayed on the user’s browser.
The application is very dynamic, therefore when the user submits a new note, the note is added to the top of the collection straightaway, besides being sent (and stored) to the server.
Which is why I can’t use a traditional pagination method, where you just send the page number to the server and the server will figure out the offset and the number of results from that.
To give you an example of what I mean, imagine there are 20 notes displayed, then the user adds 2 more notes, therefore there are 22 notes displayed. If I simply requests “page 2”, the first 2 items of that page will be the last two items of the page currently displayed to the user.
Which is why I am after a more sophisticated method, which is the one I am about to explain.
Please consider the following code, which is part of the server code serving an AJAX request for more notes:
// $lastNoteDisplayedId is coming from the AJAX request
$lastNoteDisplayed = $repository->findBy($lastNoteDisplayedId);
$allNotes = $repository->findBy($filter, array('numberOfVotes' => 'desc'));
$offset = getLastNoteDisplayedOffset($allNotes, $lastNoteDisplayedId);
// retrieve the page to send back so that it can be appended to the listing
$notesPerPage = 30
$notes = $repository->findBy(
array(),
array('numberOfVotes' => 'desc'),
$notesPerPage,
$offset
);
$response = json_encode($notes);
return $response;
Basically I would need to write the method getLastNoteDisplayedOffset, that given the whole set of notes and one particoular note, it can give me its offset, so that I can use it for the pagination of the previous Doctrine statement.
I know probably a possible implementation would be:
getLastNoteDisplayedOffset($allNotes, $lastNoteDisplayedId) {
$i = 0;
foreach ($allNotes as $note) {
if ($note->getId() === $lastNoteDisplayedId->getId()) {
break;
}
$i++;
}
return $i;
}
I would prefer not to loop through all notes because performance is an important factor.
I was wondering if Doctrine has got a method itself or if you can suggest a different approach.
In an old project, I used to create an infinite scroll as you want to do.
What I’ve done is a web service that can receive a parameter called offset.
In my javascript, I add an event that detect if the user has scroll down enough the document. When the event is triggered, I create the ajax query, I count number of elements allready present in the page (they were in a table).
Then in my doctrine query, I’ve done something like that:
Then in my template, I generate new table row that will be appended with JS.
Note: That now, I certainly return json then parse it on client side 😉