jQuery Infinite Scroll
Infinite scroll became a kind of standard in modern web apps, so I wanted to implement it in a project I’m working on. I’ve browsed the net looking for the way to accomplish this task, and found this example, which seemed quite cool and easy to implement. Its owner allowed everyone to use the script, as long as they keep the author’s credits. I’ve made few changes to better suit my needs, but the overall script is still the same. This is a short tutorial on how to implement the infinite scroll in C# ASP.Net application, using jQuery.
If you take a look at the original code, you’ll see that the data to be shown is taken from an html file. In my project, I’m fetching the data from server, in chunks of 50 records per call. Since I wanted to keep it as simple as possible and not change the script if not necessary, I’ve created server method that returns the string containing html list item objects to be added to my content div. Here is it how it all looks like:
ASPX:
1
2
3
4
5
6
|
< div > < h2 >News Feed</ h2 > < ul
id = "content" ></ ul > < div
id = "loading" >Wait a moment... it's loading!</ div > < div
id = "nomoreresults" >Sorry, no more results.</ div > </ div > |
Note that the “content” element is the list to add the items to.
cs:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
[System.Web.Services.WebMethod( true )] public
static string
GetNewsFeed( int
currentCount) { StringBuilder newsFeedSb =
new
StringBuilder(); List notifications = ActionManager.GetNewsFeed(Global.CurrentUser, 50, currentCount*50); foreach
(BLL.Action notification in
notifications) { string
messageText = "" ; // some magic here, e.g.: string
notificationDate = notification.ActionDate !=
null
? ((DateTime)notification.ActionDate).ToString( "yyyy-MM-dd" ) :
"date unknown" ; messageText =
string .Format( "<li><p>{0}: You have updated your profile.</p></li>" , notificationDate); // more business logic... if
(messageText != "" ) { newsFeedSb.Append(messageText); } } return
newsFeedSb.ToString(); } |
In this server method, I’m getting the data from database layer in chunks of 50, and in order to know which page I’m on, I use currentCount, sent by the ajax request.
When it comes to javascript, I’ve made couple of changes to the original script.
First of all, I’ve added a global variable count, to track current page I’m on. It is set to 0 on load. In original scrollpagination.js, I’ve changed loadContent method, so each time the data is successfully received on client, the count value increases by 1. Also, in the ajax call, count value is sent as data parameter. Finally, dataType I need is json, instead of html. All the changes are highlighted in the following code:
scrollpagination.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
var
count = 0; $.fn.scrollPagination.loadContent = function (obj, opts) { var
target = opts.scrollTarget; var
mayLoadContent = $(target).scrollTop() + opts.heightOffset >= $(document).height() - $(target).height(); if
(mayLoadContent) { if
(opts.beforeLoad != null ) { opts.beforeLoad(); } $(obj).children().attr( 'rel' ,
'loaded' ); $.ajax({ type:
'POST' , url: opts.contentPage, data:
"{'currentCount':'"
+ count + "'}" ,
//opts.contentData, contentType:
"application/json; charset=utf-8" , success:
function (data) { $(obj).append(data.d); var
objectsRendered = $(obj).children( '[rel!=loaded]' ); count++; if
(opts.afterLoad != null ) { opts.afterLoad(objectsRendered); } }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert(errorThrown); }, dataType:
"json" }); } }; |
Of course, method name and location have to be set, and also, I’ve removed contentData property, since I don’t need it anymore (it is set in scrollpagination.js).
1
2
3
4
5
6
7
8
9
10
11
12
13
|
$( '#content' ).scrollPagination({ 'contentPage' : window.location.pathname +
'/GetNewsFeed' , 'scrollTarget' : $(window), 'heightOffset' : 10, 'beforeLoad' :
function () { $( '#loading' ).fadeIn(); }, 'afterLoad' :
function (elementsLoaded) { $( '#loading' ).fadeOut(); var
i = 0; $(elementsLoaded).fadeInWithDelay(); } }); |
So, that’s it! Piece of cake