Tiếp tục với các bài viết trước, nay mình chia sẻ cách phân trang bằng Ajax trong ASP.NET MVC 5. Bài trước mình làm phân trang đơn giản bạn có thể xem lại tại đây
Bài này mình dùng code của bài trước chỉ sửa lại xiu là được! ::)
Bạn mở file HomeController.cs trong thư mục Controllers lên và chỉnh thêm cho mình như code sau:
public ActionResult Lists() { return View(); } [HttpGet] public JsonResult getAllPost(string txtSearch, int? page) { var data = (from s in _db.Posts select s); if (!String.IsNullOrEmpty(txtSearch)) { ViewBag.txtSearch = txtSearch; data = data.Where(s => s.Title.Contains(txtSearch)); } if (page > 0) { page = page; } else { page = 1; } int start = (int)(page - 1) * pageSize; ViewBag.pageCurrent = page; int totalPage = data.Count(); float totalNumsize = (totalPage / (float)pageSize); int numSize = (int)Math.Ceiling(totalNumsize); ViewBag.numSize = numSize; var dataPost = data.OrderByDescending(x => x.Id).Skip(start).Take(pageSize); List<Post> listPost = new List<Post>(); listPost = dataPost.ToList(); // return Json(listPost); return Json(new { data = listPost,pageCurrent = page,numSize=numSize }, JsonRequestBehavior.AllowGet); }
+ getAllPost(): return về dữ liệu Json cho phía client xử lý, đồng thời cũng nhận dữ liệu từ client gửi đến để xử lý phân trang
+ Lists(): return về View, do đó đồi hỏi bạn phải tạo một khung nhìn(View), sau khi tạo xong bạn sẽ được file Lists.cshtml trong thư mục Views/Post/Lists.cshtml
bạn open và chỉnh sửa giao điện file như sau:
@model MVC5_HelloWorld.Models.Post <div class="container"> <div class="row justify-content-center"> <div class="col-md-10"> <div class="card"> <div class="card-header"> List Posts <a href="@Url.Action("Store", "Post")" class="btn btn-success">Add</a> </div> <div class="card-body"> <div class="card-header"> Search <input type="text" name="txtSearch" placeholder="Search!" class="txtSearch"/> <button type="button" class="btn btn-warning" id="search">Search</button> </div> <table class="table table-bordered"> <thead> <tr> <th>STT</th> <th>Title</th> <th>Body</th> <th>Created_at</th> <th>Updated_at</th> <th>Edit</th> <th>Delete</th> </tr> </thead> <tbody class="load-list"> </tbody> </table> <div class="card-footer"> <nav aria-label="Page navigation example"> <ul class="pagination" id="load-pagination"> </ul> </nav> </div> </div> </div> </div> </div> </div>
Chú ý: chổ class="load-list" và id="load-pagination" dùng để hiển thị nội dùng ra và hiển thị nút phân trang
Xong giờ ta thiết lập code Ajax để xử lý phân trang trong ASP.NET MVC 5 thôi nào, trong đoạn code dưới đây mình có chú thích từng sự kiện, đoạn code dài quá, nên mình tách ra, cho dễ hình dung nghe
$(document).ready(function () { //function load pagination var load = function (txtSearch, page) { $.ajax({ url: '@Url.Action("getAllPost","Post")', type: "GET", data: { txtSearch:txtSearch , page: page }, dataType: 'json', contentType: 'application/json;charset=utf-8', success: function (result) { console.log(result); var str = ""; $.each(result.data, function (index, value) { //convert date to string var dateCreated = value.Created_at; var dateCreated_string = new Date(parseInt(dateCreated.replace("/Date(", "").replace(")/", ""), 10)); var created_at = dateCreated_string.getFullYear() + "/" + dateCreated_string.getMonth() + "/" + dateCreated_string.getDate(); var dateUpdated = value.Updated_at; var dateUpdated_string = new Date(parseInt(dateUpdated.replace("/Date(", "").replace(")/", ""), 10)); var Updated_at = dateUpdated_string.getFullYear() + "/" + dateUpdated_string.getMonth() + "/" + dateUpdated_string.getDate(); // //create list post var dateUpdated = new Date(value.Updated_at); str += "<tr>"; str += "<td>"+(value.Id)+"</td>"; str += "<td>"+value.Title + "</td>"; str += "<td>" + value.Body + "</td>"; str += "<td>" + created_at+ "</td>"; str += "<td>"+ Updated_at + "</td>"; str += "<td><a href='/Post/Edit/"+value.id+"' class='badge badge-warning'>Modify</a></td>"; str += "<td><a href='/Post/Delete/"+value.id+"' class='badge badge-danger'>Delete</a></td>"; str += "</tr>"; //create pagination var pagination_string = ""; var pageCurrent = result.pageCurrent; var numSize = result.numSize; //create button previous if (pageCurrent > 1) { var pagePrevious = pageCurrent - 1; pagination_string += '<li class="page-item"><a href="" class="page-link" data-page=' + pagePrevious + '>Previous</a></li>'; } for (i = 1; i <= numSize; i++){ if (i == pageCurrent) { pagination_string += '<li class="page-item active"><a href="" class="page-link" data-page=' + i + '>'+pageCurrent+'</a></li>'; } else { pagination_string += '<li class="page-item"><a href="" class="page-link" data-page=' + i + '>'+i+'</a></li>'; } } //create button next if (pageCurrent > 0 && pageCurrent < numSize) { var pageNext = pageCurrent + 1; pagination_string += '<li class="page-item"><a href="" class="page-link" data-page=' + pageNext + '>Next</a></li>'; } //load pagination $("#load-pagination").html(pagination_string); }); //load str to class="load-list" $(".load-list").html(str); } }); } //load init load(null, 1); });
Bên trên là đoạn code mình xử lý load phân trang, mình sẽ chèn vào 2 tham số (txtSearch,page), thông thường ban đầu, page=1, txtSearch=null
url: '@Url.Action("getAllPost","Post")': sẽ đi đến function getAllPost() file HomeControlle.cs, sao đó xử lý xong, return về dữ liệu theo kiểu Json
Các bạn có thể nhìn thấy mình có nhận dữ liệu về là kiểu Json, sao đó dùng $.earch() để lập dữ liệu ra. Bên cạnh đó bạn xem thẻ <a data-page=""></a> trong đoạn code trên mình có khai báo, giúp ta có thể dùng Ajax lấy ra số page để hiển thị
Tiếp tục ta xây dựng sự kiện click phân trang: ta sẽ click vào <a data-page=""></a> để lấy giá trị page
//click event pagination $("body").on("click",".pagination li a",function (event) { event.preventDefault(); var page = $(this).attr('data-page'); //load event pagination var txtSearch = $(".txtSearch").val(); if (txtSearch != "") { load(txtSearch, page) } else { load(null, page); } });
Trong đoạn code trên mình click vào thẻ <a href="" data-page=""></a> để lấy dữ liệu từ page-page, sau đó chèn vào hàm load(txtSearch,page) để gọi Ajax
Tiếp tục ta xây dựng hàm tìm kiếm
//click event search $("#search").click(function () { var txtSearch = $(".txtSearch").val(); if (txtSearch != "") { load(txtSearch, 1) } else { load(null, 1); } });
Đoạn code bên trên mình bắt sự kiện click tìm kiếm, sao đó lấy giá trị tìm kiếm chèn vào làm load()
Đoạn code Full Ajax
$(document).ready(function () { //function load pagination var load = function (txtSearch, page) { $.ajax({ url: '@Url.Action("getAllPost","Post")', type: "GET", data: { txtSearch:txtSearch , page: page }, dataType: 'json', contentType: 'application/json;charset=utf-8', success: function (result) { console.log(result); var str = ""; $.each(result.data, function (index, value) { //convert date to string var dateCreated = value.Created_at; var dateCreated_string = new Date(parseInt(dateCreated.replace("/Date(", "").replace(")/", ""), 10)); var created_at = dateCreated_string.getFullYear() + "/" + dateCreated_string.getMonth() + "/" + dateCreated_string.getDate(); var dateUpdated = value.Updated_at; var dateUpdated_string = new Date(parseInt(dateUpdated.replace("/Date(", "").replace(")/", ""), 10)); var Updated_at = dateUpdated_string.getFullYear() + "/" + dateUpdated_string.getMonth() + "/" + dateUpdated_string.getDate(); // //create list post var dateUpdated = new Date(value.Updated_at); str += "<tr>"; str += "<td>"+(value.Id)+"</td>"; str += "<td>"+value.Title + "</td>"; str += "<td>" + value.Body + "</td>"; str += "<td>" + created_at+ "</td>"; str += "<td>"+ Updated_at + "</td>"; str += "<td><a href='/Post/Edit/"+value.id+"' class='badge badge-warning'>Modify</a></td>"; str += "<td><a href='/Post/Delete/"+value.id+"' class='badge badge-danger'>Delete</a></td>"; str += "</tr>"; //create pagination var pagination_string = ""; var pageCurrent = result.pageCurrent; var numSize = result.numSize; //create button previous if (pageCurrent > 1) { var pagePrevious = pageCurrent - 1; pagination_string += '<li class="page-item"><a href="" class="page-link" data-page=' + pagePrevious + '>Previous</a></li>'; } for (i = 1; i <= numSize; i++){ if (i == pageCurrent) { pagination_string += '<li class="page-item active"><a href="" class="page-link" data-page=' + i + '>'+pageCurrent+'</a></li>'; } else { pagination_string += '<li class="page-item"><a href="" class="page-link" data-page=' + i + '>'+i+'</a></li>'; } } //create button next if (pageCurrent > 0 && pageCurrent < numSize) { var pageNext = pageCurrent + 1; pagination_string += '<li class="page-item"><a href="" class="page-link" data-page=' + pageNext + '>Next</a></li>'; } //load pagination $("#load-pagination").html(pagination_string); }); //load str to class="load-list" $(".load-list").html(str); } }); } //click event pagination $("body").on("click",".pagination li a",function (event) { event.preventDefault(); var page = $(this).attr('data-page'); //load event pagination var txtSearch = $(".txtSearch").val(); if (txtSearch != "") { load(txtSearch, page) } else { load(null, page); } }); //click event search $("#search").click(function () { var txtSearch = $(".txtSearch").val(); if (txtSearch != "") { load(txtSearch, 1) } else { load(null, 1); } }); //load init load(null, 1); });
Demo: