Thursday, December 20, 2018

Asp.net MVC : Implement infinite scroll using Jquery

Here in this article I am going to explain how to implement infinite scroll using Jquery in asp.net MVC application.

Description:
I am showing list of country in application. Instead of pagination want to show all records on scroll. To fulfill this requirement I am using Jquery.

Implementation:

Model class:
   public partial class CountryMaster
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string CountryCode { get; set; }
    }

Add Controller
Add an empty controller to project.

Complete source code of Controller:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using infinitescroll.Models;

namespace infinitescroll.Controllers
{
    public class CountryController : Controller
    {
        private testEntities db = new testEntities();
         public const int RecordsPerPage = 20;
        //
        // GET: /test/
         public CountryController()
        {
            ViewBag.RecordsPerPage = RecordsPerPage;
        }
        //
        // GET: /Country/
         public ActionResult Index(int? pageNum)
        {
            pageNum = pageNum ?? 0;
            ViewBag.IsEndOfRecords = false;
            if (Request.IsAjaxRequest())
            {
                var customers = GetRecordsForPage(pageNum.Value);
                ViewBag.IsEndOfRecords = (customers.Any()) && ((pageNum.Value * RecordsPerPage) >= customers.Last().Key);
                return PartialView("_CustomerRow", customers);
            }
            else
            {
                LoadAllCustomersToSession();
                ViewBag.Customers = GetRecordsForPage(pageNum.Value);
                return View("Index");
            }
            return View();
        }
        public void LoadAllCustomersToSession()
        {
            var customers = db.CountryMasters;
            int custIndex = 1;
            Session["country"] = customers.ToDictionary(x => custIndex++, x => x);
            ViewBag.TotalNumberCustomers = customers.Count();
        }
        public Dictionary<int, CountryMaster> GetRecordsForPage(int pageNum)
        {
            Dictionary<int, CountryMaster> country = (Session["country"] as Dictionary<int, CountryMaster>);
            int from = (pageNum * RecordsPerPage);
            int to = from + RecordsPerPage;
            return country
                .Where(x => x.Key > from && x.Key <= to)
                .OrderBy(x => x.Key)
                .ToDictionary(x => x.Key, x => x.Value);
        }
        //       
        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}




Add View :
Add view for index action.
Complete source of view :

@model IEnumerable<infinitescroll.Models.CountryMaster>
@{
    ViewBag.Title = "Country List";
}

<table class="infinite-scroll">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.CountryCode)
        </th>
        <th></th>
    </tr>
    <tbody style="height:500px">
        @Html.Partial("_CustomerRow", (ViewBag.Customers as Dictionary<int, infinitescroll.Models.CountryMaster>))
    </tbody>

</table>
<div id="loading">
    <img src='@Url.Content("~/images/spin.gif")' /><p><b>Loading the next @ViewBag.RecordsPerPage&hellip;</b></p>
</div>
@section scripts{
    <script src="~/Scripts/infiniteScroll.js"></script>
    <script type="text/javascript">
        $(function () {
            $("div#loading").hide();
        });
        var moreRowsUrl = "/country/index";
        $(window).scroll(scrollHandler);
    </script>
}


Create partial view :
Complete source of partial view :

@model Dictionary<int, infinitescroll.Models.CountryMaster>
@foreach (var cust in Model)
{
    <tr>
        <td>@cust.Value.Name</td>
        <td>@cust.Value.CountryCode</td>
    </tr>
}



Jquery Code :

var page = 0,
    inCallback = false,
    hasReachedEndOfInfiniteScroll = false;

var scrollHandler = function () {
    if (hasReachedEndOfInfiniteScroll == false &&
            ($(window).scrollTop() == $(document).height() - $(window).height())) {
        loadMoreToInfiniteScrollTable(moreRowsUrl);
    }
}

function loadMoreToInfiniteScrollTable(loadMoreRowsUrl) {
    if (page > -1 && !inCallback) {
        inCallback = true;
        page++;
        $("div#loading").show();
        $.ajax({
            type: 'GET',
            url: loadMoreRowsUrl,
            data: "pageNum=" + page,
            success: function (data, textstatus) {
                if (data != '') {
                    $("table.infinite-scroll > tbody").append(data);
                    $("table.infinite-scroll > tbody > tr:even").addClass("alt-row-class");
                    $("table.infinite-scroll > tbody > tr:odd").removeClass("alt-row-class");
                }
                else {
                    page = -1;
                }

                inCallback = false;
                $("div#loading").hide();
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
            }
        });
    }
}

function showNoMoreRecords() {
    hasReachedEndOfInfiniteScroll = true;
}




2 comments:

  1. Replies
    1. I have uploaded the project. Kindly check if you are missing/skip something

      Delete