Link to Implementing Load More button using ASP.NET MVC and jQuery - Part One
Building JsonResult Controller Action for Turning View to String and Receiving What We Need From It
Here is the code for this method:
[HttpPost]
[AllowAnonymous]
public JsonResult LoadMoreProduct(int size)
{
var model = _db.Products.OrderBy(p => p.ProductId).Skip(size).Take(4);
int modelCount = _db.Products.Count();
if (model.Any())
{
string modelString = RenderRazorViewToString("_LoadMoreProduct", model);
return Json(new { ModelString = modelString, ModelCount = modelCount });
}
return Json(model);
}
LoadMoreProduct size parameter
In LoadMoreProduct
action, size is responsible for providing a number for use in skip method, each time you click the load more button, we count how many times you hit it and multiply it with number of product that we want to return which in this case is 4 and send it to this method and receive new set of products.
LoadMoreProduct modelCount variable
We use this variable to send total number of products in our database so we can calculate when to hide the load more button, it will become more clear once you see the JavaScript portion of the page.
RenderRazorViewToString method
This method is responsible for taking a partial view and a model and rendering the partial view and giving us some html in the form of string
, here’s the definition of RenderRazorViewToString
which I’ve found on Stackoverflow:
public string RenderRazorViewToString(string viewName, object model)
{
ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext,viewName);
var viewContext =
new ViewContext(ControllerContext, viewResult.View,ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
LoadMoreProduct – Send the html String and Number of Products to JavaScript
In the end, we send the ModelString
to whoever is calling it, and we use it to attach the html string to the DOM with some effect and also send the modelcount
for counting how many products are left to show and then hide the load more button when there is no more product to show. Let’s waste no more time here and jump straight into the script part.
Load More JavaScript Part, Taking the Necessary Part form the Controller Action and Attach It to the DOM
Here is the code for JavaScript part, following this code, I’ll try to explain what I’ve done in as much detail as possible:
$(function () {
var loadCount = 1;
var loading = $("#loading");
$("#loadMore").on("click", function (e) {
e.preventDefault();
$(document).on({
ajaxStart: function () {
loading.show();
},
ajaxStop: function () {
loading.hide();
}
});
var url = "/Product/LoadMoreProduct/";
$.ajax({
url: url,
data: { size: loadCount * 4 },
cache: false,
type: "POST",
success: function (data) {
if (data.length !== 0) {
$(data.ModelString).insertBefore("#loadMore").hide().fadeIn(2000);
}
var ajaxModelCount = data.ModelCount - (loadCount * 4);
if (ajaxModelCount <= 0) {
$("#loadMore").hide().fadeOut(2000);
}
},
error: function (xhr, status, error) {
console.log(xhr.responseText);
alert("message : \n" +
"An error occurred, for more info check the js console" +
"\n status : \n" + status + " \n error : \n" + error);
}
});
loadCount = loadCount + 1;
});
});
In the first line, we define the loadCount
variable, we then multiply this variable with 4
, because we have four products already on the page, we need to send this number to our action parameter and skip loadCount
multiplied with four number of products and take another four, we do it with assigning it to the size and send it to our action, and in the end we one plus this value, so next time we click the load more button, we multiply 4 product by 2 and receive 8, so we need to skip 8 product and receive another four.
The next important part is what we do with what is returned from our action, our controller action as you saw returns a modelString
to the JavaScript side, and then we have the html string that we simply attach to the DOM (before loadMore
paragraph in this case) after ensuring the data is not empty and give it some effect or whatever using this code:
$(data.ModelString).insertBefore("#loadMore").hide().fadeIn(2000);
The next part is the code we use to calculate when we need to hide our load more button, we do it with this code:
var ajaxModelCount = data.ModelCount - (loadCount * 4);
if (ajaxModelCount <= 0) {
$("#loadMore").hide().fadeOut(2000);
Here, we multiply loadCount
to four, and then subtract the number from data.ModelCount
. We receive the modelcount
which is all the products in database from our controller action every time we hit the LoadMoreProduct
action, and when the ajaxModelCount
is zero or less, we know that we don’t have any more products to show and we simply hide our loadmore button.
Other part of our code like the one with ajaxStart
and ajaxStop
in it, is for showing the loading animation in our button which is not obligatory and somewhat irrelevant to the problem we are trying to solve here.
If you need the sample project on github or can take a look at the original post here:
Implementing Load More button using ASP.NET MVC and jQuery - Part Two - Hamid MosallaCodeProject