Introduction
In the next two posts, I’m going to show you how to build a load more button for your page using Asp.Net MVC, you can use it for any various kind of things, but in the case of this tutorial, I’ll use it for my fictitious product list. I’ll try not to complicate things and explain what I’ve done in simple and straightforward manner.
In a nutshell
To put it concisely, the way we are going to implement this feature is that we send a model into a method, this method generate a view and convert it to string and then we attach this string into the DOM, of course we need some code to calculate how many time we’ve clicked Load More button and multiply it with number of products that we want to load, and skip that amount and take the number of products that we need. I won’t bother with more explanation here, let’s jump straight into the code and I'll explain each part of code in detail.
Building the index view for showing already on page lists of products
First step is to send our model to our view and then build the view’s user interface to jump start our load more page. The important thing here is that we can’t use two nested foreach
loop, here we need to foreach loop for one bootstrap row and the inner loop for generating the actual products, for this start page we show four product on the page, any subsequent product must be loaded using load more button.
Here is the code for our controller action:
public ActionResult Index()
{
var model = _db.Products.OrderBy(p => p.ProductId).Take(4); ;
return View(model);
}
Here is the code for our View:
@using LoadMoreMVCSample.Helpers
@model IEnumerable<LoadMoreMVCSample.Models.Product>
@{
ViewBag.Title = "LoadMore Sample - HamidMosalla.com";
}
<br />
<br />
@foreach (var item in Model.Batch(4))
{
<div class="row">
<div class="col-md-10">
@foreach (var subitem in item)
{
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3"
style="padding-right: 5px; padding-left: 5px;">
<div class="thumbnail">
<h4 class="text-center">
<span class="label label-default">@subitem.ProductName</span></h4>
<p class="text-center" style="font-size: small;">
@subitem.ProductDate.ToLongDateString()</p>
<a href="/Product/Details/@subitem.ProductId/@subitem.ProductName">
<img src="@subitem.ProductPicture"
alt="@subitem.ProductName" class="img-responsive"></a>
<div class="caption">
<div class="row">
<div style="font-size: small;" class="col-md-12 col-xs-12 price">
@Html.Raw(subitem.ProductDescription)
<a href="#">Read more...</a>
</div>
</div>
<div class="row">
<div class="col-md-8">
<a href="#" class="btn btn-success"
style="width: 100%;">
<span class="glyphicon glyphicon-shopping-cart"></span>Add to Cart</a>
</div>
</div>
</div>
</div>
</div>
}
</div>
</div>
}
<br />
<p id="loadMore" style="text-align: center;">
<a class="btn btn-danger btn-lg">
LoadMore »
<span>
<img id="loading" style="display: none;" src="~/Content/ajax-loader.gif" />
</span>
</a>
</p>
@section scripts{
<script src="~/Scripts/CustomScript/LoadMore.js"></script>
}
You might notice the using of Batch here, what it does is that it'll batch our model so we can foreach through our item, here is the code for the method responsible for this feature that I’ve found on Stackoverflow:
public static IEnumerable> Batch(
this IEnumerable source, int batchSize)
{
using (var enumerator = source.GetEnumerator())
while (enumerator.MoveNext())
yield return YieldBatchElements(enumerator, batchSize - 1);
}
private static IEnumerable YieldBatchElements(
IEnumerator source, int batchSize)
{
yield return source.Current;
for (int i = 0; i < batchSize && source.MoveNext(); i++)
yield return source.Current;
}
If you don’t care about this much hassle, you can also use a simple for loop to do the one iteration, and to be honest the only reason I’ve done this in this manner was that I was curious how we can have nested for each loop. If you want, use a simple for loop like so:
For(int i=0; i < 1; i++)
You might also notice the script file at the end of our view, ignore it for the moment, I'll explain what I’ve done later in this article.
Build partial view for turning the loaded products to string
Next step is to build a partial view, later we give this partial view and a model with our products to a method and receive some string to work with, this view is pretty straightforward:
@model IEnumerable<LoadMoreMVCSample.Models.Product>
<div class="row">
<div class="col-md-10">
@foreach (var item in Model)
{
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3"
style="padding-right: 5px; padding-left: 5px;">
<div class="thumbnail">
<h4 class="text-center">
<span class="label label-default">@item.ProductName</span></h4>
<p class="text-center" style="font-size: small;">
@item.ProductDate.ToLongDateString()</p>
<a href="/Product/Details/@item.ProductId/@item.ProductName">
<img src="@item.ProductPicture" alt="@item.ProductName" class="img-responsive"></a>
<div class="caption">
<div class="row">
<div style="font-size: small;" class="col-md-12 col-xs-12 price">
@Html.Raw(item.ProductDescription)
<a href="#">Read more...</a>
</div>
</div>
<div class="row">
<div class="col-md-8">
<a href="#" class="btn btn-success"
style="width: 100%;"><span class="glyphicon glyphicon-shopping-cart">
</span>Add to Cart</a>
</div>
</div>
</div>
</div>
</div>
}
</div>
</div>
This is the end of part one, you can see the continuation of this article in part two, also I've included the source code, if the article formatting is hard to read you can read the code form the included source.