3

I have a list in asp.net mvc 5

I have limited the number of records to be displayed in page.

now on scroll I do ajax call, the first call works fine but when I scroll down more it recall the function repeatedly 5 to 10 times and lost it again display the data, it was really strange, I could not find solution

My Controller:

public ActionResult Index()
{
    int starting = 0;
    if (Request.Form["starting"] != null)
    {
        starting = Convert.ToInt32(Request.Form["starting"]);
    }

    int takes = 15;
    if (Request.Form["takes"] != null)
    {
        takes = Convert.ToInt32(Request.Form["takes"]);
    }
    //string strpost = "&ajax=1";

    var query = db.MyEmployee.ToList().Skip(starting).Take(takes);


    if (Request.IsAjaxRequest())
    {

        starting = starting+15;
        query = db.MyEmployee.ToList().Skip(starting).Take(takes);
        ViewData["starting"] = starting;
        ViewBag.takes = takes;
        return PartialView("_PartialIndex",query);
    }
    ViewBag.starting = starting;
    ViewBag.takes = takes;
    return View(query);

}

My Model:

     public class Employee
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public string Email { get; set; }
}

My View and partial view code:

 <div id="mypage">
@model IEnumerable<MVC5WAuth.Models.Employee>

@{
    ViewBag.Title = "Index";
}

<h2>Index 1</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Id)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.FullName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Email)
        </th>
        <th></th>
    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Id)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.FullName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Email)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
                @Html.ActionLink("Details", "Details", new { id = item.Id }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.Id })
            </td>
        </tr>
    }

</table>


<script type="text/javascript">


    $(window).scroll(function () {
        if ($(window).scrollTop() == $(document).height() - $(window).height()) {
            // ajax call get data from server and append to the div



            var ajax_image = "<img src='../Content/loading.GIF' >";
            $('#mypage').html(ajax_image);
            var params = '&starting=' + @ViewBag.starting + '&takes=' + @ViewBag.takes;
            $.ajax({
                url:'@Url.Action("Index", "Employees")',
                type: "POST",
                data: params,

            })
            .done(function (r) {

                $('#mypage').html(r);
            });

        }
    });

</script>

10
  • 1
    Where you make use of ViewBag in your javascript function will never update as it's not being reloaded as part of the AJAX call. I'd suggest persisting a variable in JS that you can increment on each AJAX call. Commented Mar 31, 2016 at 10:31
  • 1
    Your script is using @ViewBag.starting and @ViewBag.takes which are the initial values when you first generate the view (they are no updated just because you set them again in the method). You need to maintain the values as javascript variable and increment them Commented Mar 31, 2016 at 10:31
  • As i can see you don't change your starting variable in js. That's why you get same data again and again. And about 5-10 call can be something wrong with your calculations in first line. Commented Mar 31, 2016 at 10:32
  • No I don't get same data again and again if you see my function under Request.isAjax i set starting = starting+10 which works but it reloads the page if you just copy and past my code you will see it Commented Mar 31, 2016 at 10:42
  • @MehdiJalal, You are getting the same data each time you make the ajax() call. The value of starting is 0 when you first generate the view and when ever you scroll and make the ajax call, it posts back starting=0 so the result of starting = starting+10; is always 10 Commented Mar 31, 2016 at 10:49

1 Answer 1

1

You current code is just replacing the existing view each time you scroll and make a ajax call, not updating the existing view with the next set of rows you want. You code also has some inefficiencies such as materializing all your records to an in-memory set before calling .Skip() and .Take().

You need to break this into 2 separate methods and views, one to generate the initial view, and one to return a partial of just the records you want to append to the main view.

Controller

public ActionResult Index()
{
    return View();
}
public ActionResult Fetch(int startIndex)
{
    query = db.MyEmployee.OrderBy(x => x.ID).Skip(startIndex).Take(15);
    return PartialView(query);
}

Index.cshtml

@model IEnumerable<MVC5WAuth.Models.Employee>
....
<table class="table">
    <thead>
        <tr>
            <th>@Html.DisplayNameFor(model => model.Id)</th>
            ....
        </tr>
    </thead>
    <tbody id="tbody">
        @{ Html.RenderAction("Fetch", new { startIndex = 0 }); } // generate the 1st 15 rows
    </tbody>
</table>

<script type="text/javascript">
    var start = 15;
    var url = '@Url.Action("Fetch")';
    var tbody = $('#tbody');
    $(window).scroll(function () {
        if ($(window).scrollTop() == $(document).height() - $(window).height()) {
            ....
            $.get(url, { startIndex: start }, function(response) {
                tbody.append(response);
                start += 15; // increment for next call
            });
        }
    });
</script>

Fetch.cshtml

@model IEnumerable<MVC5WAuth.Models.Employee>
@foreach (var item in Model)
{
    <tr>
        <td>@Html.DisplayFor(m => item.Id)</td>
        ....
    </tr>
}
Sign up to request clarification or add additional context in comments.

2 Comments

On the first load it calls both functions, I mean I brings the Index function view list data plus the fetch function partial view data in one view duplicate
Thanks by going here and there finally I solved it by your way

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.