Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load first x items and give user the option to load more in MVC.NET

What would be the best way to load, for example, the first 25 items of the IEnumerable of an Index view in ASP.NET MVC?

I have a model and have created a controller and views using scaffolding. In the index page I create a div containing some info for each instance in the model of the view (List of Question objects). I would like to display the first 25 items and give the user the possibility to load more using a link at the bottom saying "Load the next 25 questions...".

How would this be possible?

like image 207
E. V. d. B. Avatar asked Mar 20 '23 23:03

E. V. d. B.


2 Answers

This is similar to paging except that you retain the previous fetches. Your view model needs to have one more property of a helper class:

public class PagingInfo
{
    public int TotalItems { get; set; }
    public int ItemsPerPage { get; set; }
    public int CurrentPage { get; set; }
    public int TotalPages
    {
        get { return (int)Math.Ceiling((decimal)TotalItems / ItemsPerPage); }
    }
}

public class QuestionsListViewModel
{
    public IEnumerable<Question> Questions { get; set; }
    public PagingInfo PagingInfo { get; set; }
}

And when you render the QuestionsListViewModel, use a similar Razor Code:

@foreach (var p in Model.Questions)
{
    // render Questions
}

@Html.ActionLink("Load next 25 items", "Questions", "Controller", new { page = Model.PagingInfo.CurrentPage + 1 }))

Questions is your Controller Action as follows:

    public ViewResult Questions(int page = 1)
    {
        QuestionsListViewModelmodel = new QuestionsListViewModel
        {
            // we need to get all items till now to render again 
            Questions = repository.Questions
                                  .Take(page * PageSize),
            PagingInfo = new PagingInfo
            {
                CurrentPage = page,
                ItemsPerPage = 25,
                TotalItems = repository.Questions.Count()
            }
        };

        return View(model);
    }

You can actually use the TotalItems property to give a smart message for loading next items.

If you don't want to go the MVC way, then you can leverage client side scripting to achieve the same.

like image 56
Raja Nadar Avatar answered Apr 07 '23 19:04

Raja Nadar


Have you considered PagedList library for pagination? All what you have to do is to reference PagedList library in your ASP.NET MVC application

To install PagedList.Mvc, run the following command in the Package Manager Console. You can use NuGet to get this package too.

PM> Install-Package PagedList.Mvc

Your viewmodel

public class QuestionViewModel
{
        public int QuestionId { get; set; }
        public string QuestionName { get; set; }
}

In your controller, reference PagedList

using PagedList;

and the Index method of your controller will be something like

public ActionResult Index(int? page)
{
            var questions = new[] {
                new QuestionViewModel { QuestionId = 1, QuestionName = "Question 1" },
                new QuestionViewModel { QuestionId = 1, QuestionName = "Question 2" },
                new QuestionViewModel { QuestionId = 1, QuestionName = "Question 3" },
                new QuestionViewModel { QuestionId = 1, QuestionName = "Question 4" }
            };

            int pageSize = 3;
            int pageNumber = (page ?? 1);
            return View(questions.ToPagedList(pageNumber, pageSize));
}

And your Index view

@model PagedList.IPagedList<ViewModel.QuestionViewModel>
@using PagedList.Mvc; 
<link href="/Content/PagedList.css" rel="stylesheet" type="text/css" />


<table>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.QuestionId)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.QuestionName)
        </td>
    </tr>
}

</table>

<br />

Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
@Html.PagedListPager( Model, page => Url.Action("Index", new { page }) )
like image 40
Dennis R Avatar answered Apr 07 '23 21:04

Dennis R