صفحه بندی به صورت ajax همراه با جستجو و فیلتر در Asp.net MVC5
شنبه 7 مرداد 1396در این مقاله قصد داریم یک View ایجاد کنیم که محصولات را به صورت ajax بتوانیم جستجو و فیلتر کنیم و همچنین از صفحه بندی استفاده کنیم .
شاید یکی از مشکلاتی که برای شما هم پیش آمده باشد صفحه بندی به صورت ajax همراه با جستجو و فیلتر باشد .
در این مقاله قصد داریم با استفاده از ajax این کار را به ساده ترین راه ممکن انجام دهیم .
برای این منظور یک پروژه از نوع MVC ایجاد می کنیم .
EntityFrameWork را از طریق Nuget در پروژه نصب می کنیم .
کلاس Product را در پوشه Model ایجاد می کنیم و کد های زیر را در آن قرار می دهیم .
public class Product { public int id { get; set; } public string name { get; set; } [AllowHtml] public string content { get; set; } public string excerpt { get; set; } public DateTime? date { get; set; } public decimal price { get; set; } public int quantity { get; set; } public int status { get; set; } public int author { get; set; } public string images { get; set; } public string featured_image { get; set; } } public class ProductDBContext : DbContext { public ProductDBContext() : base("DefaultConnection") { } public DbSet<Product> Products { get; set; } }
در کدهای بالا بعد از تعریف DbContext را نیز بعد از کلاس Product انجام دادیم .
در sql server managment یک دیتابیس به اسم TestPage ایجاد می کنیم .
این کانکشن استرینگ را به فایل Web.config در پروژه اضافه می کنیم .
<connectionStrings> <add name="DefaultConnection" connectionString="Data Source=.;Initial Catalog=TestPage;Integrated Security=True;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" /> </connectionStrings>
حالا وارد پروژه شده از سربرگ Toolsمنوی NuGet Package Manager-> Package Manager Console را انتخاب می کنیم .
ابتدا دستور Enable-migrations رو می نوسیم و Enter را می زنیم .
بعد از آن Add-migration MyDb
و بعد از آن Update-database
حالا می توانیم از طریق sql server managment وارد جدول Product شده و تعدادی رکورد وارد کنیم .
بعد از ساخت دیتابیس نوبت به ساخت صفحه می شود .
روی پوشه Controllers کلیک راست می کنیم و New Scaffolded Item را می زنیم .
گزینه ی MVC5 controller with views,using EntityFramework را انتخاب می کنیم .
در صفحه بعدی که باز می شود .
Model class : Product
Data context class : ProductDBContext
نام کنترلر هم ProductsController
Add را می زنیم تا کنترلر و ویو های متناظر آن ساخته شود .
وارد کنترلر ساخته شده می شویم و به جای کدهای Index کدهای پایین را کپی می کنیم.
[HttpGet] public ActionResult Index() { /* No logic required here, let's just render the view */ return View(); } [HttpPost] public string Index(FormCollection collection) { /* Setup default variables that we are going to populate later */ var pag_content = ""; var pag_navigation = ""; /* Define all posted data coming from the view. */ int page = Convert.ToInt32(collection["data[page]"]); /* Page we are currently at */ string sort = collection["data[sort]"] == "ASC" ? "asc" : "desc"; /* Order of our sort (DESC or ASC) */ string name = collection["data[name]"]; /* Name of the column name we want to sort */ int max = Convert.ToInt32(collection["data[max]"]); /* Number of items to display per page */ string search = collection["data[search]"]; /* Keyword provided on our search box */ int cur_page = page; page -= 1; int per_page = max > 1 ? max : 16; bool previous_btn = true; bool next_btn = true; bool first_btn = true; bool last_btn = true; int start = page * per_page; var all_items_query= db.Products.Where(x => x.id != 0).OrderByDescending(p => p.name) .Skip(start) .Take(per_page); if (sort == "desc") { if (name == "name") { /* Let's build the query using available data that we received form the front-end via ajax */ all_items_query = db.Products.Where(x => x.id != 0).OrderByDescending(p=>p.name) .Skip(start) .Take(per_page); /* Get only the products to display. */ }else if (name == "price") { /* Let's build the query using available data that we received form the front-end via ajax */ all_items_query = db.Products.Where(x => x.id != 0).OrderByDescending(p => p.price) .Skip(start) .Take(per_page); /* Get only the products to display. */ } else { /* Let's build the query using available data that we received form the front-end via ajax */ all_items_query = db.Products.Where(x => x.id != 0).OrderByDescending(p => p.date) .Skip(start) .Take(per_page); /* Get only the products to display. */ } } else { if (name == "name") { /* Let's build the query using available data that we received form the front-end via ajax */ all_items_query = db.Products.Where(x => x.id != 0).OrderBy(p => p.name) .Skip(start) .Take(per_page); /* Get only the products to display. */ } else if (name == "price") { /* Let's build the query using available data that we received form the front-end via ajax */ all_items_query = db.Products.Where(x => x.id != 0).OrderBy(p => p.price) .Skip(start) .Take(per_page); /* Get only the products to display. */ } else { /* Let's build the query using available data that we received form the front-end via ajax */ all_items_query = db.Products.Where(x => x.id != 0).OrderByDescending(p => p.date) .Skip(start) .Take(per_page); /* Get only the products to display. */ } } /* Get total items in our database */ var count_query = db.Products .Where(x => x.id != 0); /* Get total products count. */ /* If there is a search keyword, we search through the database for possible matches*/ if (search != "") { /* The "Contains" method matches records using the LIKE %keyword% format */ all_items_query = all_items_query.Where(x => x.name.Contains(search) || x.content.Contains(search) || x.excerpt.Contains(search) ); count_query = count_query.Where(x => x.name.Contains(search) || x.content.Contains(search) || x.excerpt.Contains(search) ); } /* We now fetch the data from our database */ var all_items = all_items_query.ToList(); int count = count_query.Count(); if (count > 0) { /* Loop through each item to create views */ foreach (var item in all_items) { pag_content += "<div class='col-sm-3 item-" + item.id + "'>" + "<div class='panel panel-default'>" + "<div class='panel-heading item-name'>" + item.name + "</div>" + "<div class='panel -body p-0 p-b'>" + "<a href='/Products/Details/" + item.id + "'><img src='/Content/Images/" + "dummy-shirt.png" + "' width='100%' class='img-responsive item-featured' /></a>" + "<div class='list-group m-0'>" + "<div class='list-group-item b-0 b-t'>" + "<i class='fa fa-calendar-o fa-2x pull-left ml-r'></i>" + "<p class='list-group-item-text'>Price</p>" + "<h4 class='list-group-item-heading'>$<span class='item-price'>" + item.price + "</span></h4>" + "</div>" + "<div class='list-group-item b-0 b-t'>" + "<i class='fa fa-calendar fa-2x pull-left ml-r'></i>" + "<p class='list-group-item-text'>On Stock</p>" + "<h4 class='list-group-item-heading item-stock'>" + "" + "</h4>" + "</div>" + "</div>" + "</div>" + "<div class='panel-footer'>" + "</p><a href='/Products/Details/" + item.id + "' class='btn btn-success btn-block'>View Item</a></p>" + "</div>" + "</div>" + "</div>"; } } else { /* Show a message if no items were found */ pag_content += "<p class='p-d bg-danger'>No items found</p>"; } pag_content = pag_content + "<br class = 'clear' />"; /* Bellow is the navigation logic and view */ decimal nop_ceil = Decimal.Divide(count, per_page); int no_of_paginations = Convert.ToInt32(Math.Ceiling(nop_ceil)); var start_loop = 1; var end_loop = no_of_paginations; if (cur_page >= 7) { start_loop = cur_page - 3; if (no_of_paginations > cur_page + 3) { end_loop = cur_page + 3; } else if (cur_page <= no_of_paginations && cur_page > no_of_paginations - 6) { start_loop = no_of_paginations - 6; end_loop = no_of_paginations; } } else { if (no_of_paginations > 7) { end_loop = 7; } } pag_navigation += "<ul>"; if (first_btn && cur_page > 1) { pag_navigation += "<li p='1' class='active'>First</li>"; } else if (first_btn) { pag_navigation += "<li p='1' class='inactive'>First</li>"; } if (previous_btn && cur_page > 1) { var pre = cur_page - 1; pag_navigation += "<li p='" + pre + "' class='active'>Previous</li>"; } else if (previous_btn) { pag_navigation += "<li class='inactive'>Previous</li>"; } for (int i = start_loop; i <= end_loop; i++) { if (cur_page == i) pag_navigation += "<li p='" + i + "' class = 'selected' >" + i + "</li>"; else pag_navigation += "<li p='" + i + "' class='active'>" + i + "</li>"; } if (next_btn && cur_page < no_of_paginations) { var nex = cur_page + 1; pag_navigation += "<li p='" + nex + "' class='active'>Next</li>"; } else if (next_btn) { pag_navigation += "<li class='inactive'>Next</li>"; } if (last_btn && cur_page < no_of_paginations) { pag_navigation += "<li p='" + no_of_paginations + "' class='active'>Last</li>"; } else if (last_btn) { pag_navigation += "<li p='" + no_of_paginations + "' class='inactive'>Last</li>"; } pag_navigation = pag_navigation + "</ul>"; /* Lets put our variables in a dictionary */ var response = new Dictionary<string, string> { { "content", pag_content }, { "navigation", pag_navigation } }; /* Then we return the Dictionary in json format to our front-end */ string json = new JavaScriptSerializer().Serialize(response); return json; }
به پوشه Views -> Products می رویم و فایل Index.cshtml را باز می کنیم و کدهای زیر را جایگزین آن می کنیم.
@model IEnumerable<WebApplication1.Models.Product> @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <h2>Products</h2> <div class="products-view-all"> <form class="post-list"> <input type="hidden" value=""> </form> <div class="clearfix"> <article class="navbar-form navbar-left p-0 m-0 ml-b"> <div class="form-group"> <label>Per Page: </label> <select class="form-control post_max m-b"> <option value="4">4</option> <option value="8">8</option> <option value="16">16</option> </select> </div> <label> Search Keyword: <input type="text" placeholder="Enter a keyword" class="form-control post_search_text m-b"> </label> <div class="form-group"> <label>Order By: </label> <select class="form-control post_name m-b"> <option value="name">Name</option> <option value="price">Price</option> <option value="date">Date Posted</option> </select> <select class="form-control post_sort m-b"> <option value="ASC">ASC</option> <option value="DESC">DESC</option> </select> </div> <input type="submit" value="Filter" class="btn btn-primary post_search_submit m-b"> </article> </div> <hr> <div class="clearfix"> <div class="pagination-container clearfix"><br class="clear"></div> <div class="pagination-nav"></div> </div> </div>
روی پوشه Scripts کلیک راست می کنیم گزینه Add -> JavaScriptFile یک فایل از نوع JavaScript به نام App.js ایجاد می کنیم و محتوای آن را ، محتوای زیر قرار می دهیم .
/** * App Class * * @author Carl Victor Fontanos * @author_url www.carlofontanos.com * */ /** * Setup a App namespace to prevent JS conflicts. */ var app = { Posts: function () { /** * This method contains the list of functions that needs to be loaded * when the "Posts" object is instantiated. * */ this.init = function () { this.get_all_items_pagination(); } /** * Load front-end items pagination. */ this.get_all_items_pagination = function () { _this = this; /* Check if our hidden form input is not empty, meaning it's not the first time viewing the page. */ if ($('form.post-list input').val()) { /* Submit hidden form input value to load previous page number */ data = JSON.parse($('form.post-list input').val()); _this.ajax_get_all_items_pagination(data.page, data.name, data.sort); } else { /* Load first page */ _this.ajax_get_all_items_pagination(1, $('.post_name').val(), $('.post_sort').val()); } /* Search */ $('body').on('click', '.post_search_submit', function () { _this.ajax_get_all_items_pagination(1, $('.post_name').val(), $('.post_sort').val()); }); /* Search when Enter Key is triggered */ $(".post_search_text").keyup(function (e) { if (e.keyCode == 13) { _this.ajax_get_all_items_pagination(1, $('.post_name').val(), $('.post_sort').val()); } }); /* Pagination Clicks */ $('body').on('click', '.pagination-nav li.active', function () { var page = $(this).attr('p'); _this.ajax_get_all_items_pagination(page, $('.post_name').val(), $('.post_sort').val()); }); } /** * AJAX front-end items pagination. */ this.ajax_get_all_items_pagination = function (page, order_by_name, order_by_sort) { if ($(".pagination-container").length > 0 && $('.products-view-all').length > 0) { $(".pagination-container").html('<img src="/Content/Images/loading.gif" class="ml-tb" />'); var post_data = { page: page, search: $('.post_search_text').val(), name: order_by_name, sort: order_by_sort, max: $('.post_max').val(), }; $('form.post-list input').val(JSON.stringify(post_data)); var data = { action: 'get-all-products', data: JSON.parse($('form.post-list input').val()) }; $.ajax({ url: '/Products/Index', type: 'POST', data: data, success: function (response) { response = JSON.parse(response); if ($(".pagination-container").html(response.content)) { $('.pagination-nav').html(response.navigation); $('.table-post-list th').each(function () { /* Append the button indicator */ $(this).find('span.glyphicon').remove(); if ($(this).hasClass('active')) { if (JSON.parse($('form.post-list input').val()).th_sort == 'DESC') { $(this).append(' <span class="glyphicon glyphicon-chevron-down pull-right"></span>'); } else { $(this).append(' <span class="glyphicon glyphicon-chevron-up pull-right"></span>'); } } }); } } }); } } } } /** * When the document has been loaded... * */ jQuery(document).ready(function () { posts = new app.Posts(); /* Instantiate the Posts Class */ posts.init(); /* Load Posts class methods */ });
رفرنس آن را به فایل _Layout در قسمت اسکریپت ها اضافه می کنیم .
وارد پوشه Content می شویم و یک پوشه به نام Images اضافه می کنیم و یک عکس به نام dummy-shirt.png و loading.gif به آن اضافه می کنیم . ( می توانید از اینترنت دانلود کنید )
وارد فایل Site.css می شویم و کدهای زیر را به آن اضافه می کنیم .
/* Pagination Styles */ .pagination-nav { margin: 30px 0 20px 0; } .pagination-nav ul {margin: 0; padding: 0;} .pagination-nav ul li {display: inline-block; margin: 3px; padding: 6px 10px; background: #FFF; color: black; border-radius: 2px; } .pagination-nav ul li.active:hover {cursor: pointer; background: #18bc9c; color: white; } .pagination-nav ul li.inactive {background: #e8e8e8;} .pagination-nav ul li.selected {background: #18bc9c; color: white;}
پروژه آماده است و شما می توانید آن را اجرا کنید .
امیدوارم که از این مقاله استفاده کنید . آموزش asp.net mvc
با تشکر محسن سلمانی
- ASP.net MVC
- 4k بازدید
- 11 تشکر