AJAX pagedlist with partial view
Asked Answered
T

2

7

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?

Trakas answered 10/7, 2014 at 14:33 Comment(0)
T
13

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();
        }
    }
Trakas answered 11/7, 2014 at 14:10 Comment(2)
The ActionResult always needs to be Index, or you will be redirected to something like controller/middleaction/?page=2&pageSize=sizeMichelinemichell
I needed to include the following script within index to get it work: @section Scripts{ <script type="text/javascript" src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script> }Escadrille
S
3

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>
Submersed answered 24/8, 2015 at 21:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.