I can't quite figure out how to get a partial view to render a paged list using ajax.
The closest I've got it to working is the example from Using paging in partial view, asp.net mvc
I'm basically trying to create a page with a list of comments per user where the page can be changed in the same way as the answers tab on the stackoverflow users page.
The paging works fine the on the first pager click, but then the the partial view is all that is returned once I click on the pager again.
Controller:
public class ProductController : Controller
{
public IQueryable<Product> products = new List<Product> {
new Product{ProductId = 1, Name = "p1"},
new Product{ProductId = 2, Name = "p2"},
new Product{ProductId = 3, Name = "p3"},
new Product{ProductId = 4, Name = "p4"},
new Product{ProductId = 5, Name = "p5"}
}.AsQueryable();
public object Index()
{
return View();
}
public object Products(int? page)
{
var pageNumber = page ?? 1; // if no page was specified in the querystring, default to the first page (1)
var onePageOfProducts = products.ToPagedList(pageNumber, 3); // will only contain 25 products max because of the pageSize
ViewBag.OnePageOfProducts = onePageOfProducts;
return PartialView("_Products");
}
}
Views:
Index.cshtml:
<link href="/Content/PagedList.css" rel="stylesheet" type="text/css" />
<h2>List of Products</h2>
<div id="products">
@Html.Action("Products", "Product")
</div>
@section scripts{
<script type="text/javascript">
$(function() {
$('#myPager').on('click', 'a', function() {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
success: function(result) {
$('#products').html(result);
}
});
return false;
});
});
</script>
}
_Products.cshtml:
@using PagedList.Mvc;
@using PagedList;
<ul>
@foreach(var product in ViewBag.OnePageOfProducts){
<li>@product.Name</li>
}
</ul>
<!-- output a paging control that lets the user navigation to the previous page, next page, etc -->
<div id="myPager">
@Html.PagedListPager((IPagedList)ViewBag.OnePageOfProducts, page => Url.Action("Products", new { page }))
</div>
Model
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
}
Can anyone show me what I'm doing wrong?
I ended up using the unobtrusive ajax example from the pagedlist source [https://github.com/troygoode/PagedList][1]
partial view:
@using PagedList;
@using PagedList.Mvc;
<ul id="names" start="@ViewBag.Names.FirstItemOnPage">
@foreach(var i in ViewBag.Names){
<li>@i</li>
}
</ul>
@Html.PagedListPager((IPagedList)ViewBag.Names, page => Url.Action("Index", new { page }), PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing( new AjaxOptions(){ HttpMethod = "GET", UpdateTargetId = "unobtrusive"}))
Index:
@{
ViewBag.Title = "Unobtrusive Ajax";
}
@using PagedList;
@using PagedList.Mvc;
@Styles.Render("~/Content/PagedList.css")
<h2>Unobtrusive Ajax</h2>
<p>Example of paging a list:</p>
<div id="unobtrusive">
@Html.Partial("UnobtrusiveAjax_Partial")
</div>
Controller:
public class UnobtrusiveAjaxController : BaseController
{
// Unobtrusive Ajax
public ActionResult Index(int? page)
{
var listPaged = GetPagedNames(page); // GetPagedNames is found in BaseController
if (listPaged == null)
return HttpNotFound();
ViewBag.Names = listPaged;
return Request.IsAjaxRequest()
? (ActionResult)PartialView("UnobtrusiveAjax_Partial")
: View();
}
}
Just in case, since the original question wasn't answered. I guess the problem was that on click handlers weren't reattached to the new pager elements generated by AJAX request. I also don't like unobstrusive AJAX solution in this case, since pager id is hardcoded in the nested view while passing it in some other way may be too cumbersome.
<script type="text/javascript">
// better not to clutter global scope of course, just for brevity sake
var attachHandlers = function() {
$('#myPager a').click(function() {
$('#myPager').load(this.href, function() {
attachHandlers();
});
return false;
});
};
$(document).ready(function () {
attachHandlers();
});
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With