简体   繁体   中英

Remember (persist) the filter, sort order and current page of Table in MVC 5 EF 6

So essentially I've done all my sorting, filtering and paging with the help of this tutorial, which has been very, very handy because I'm very new to this material. - http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application

The Controller:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using SunsUniversity.Models;
using SunsUniversity.DAL;
using PagedList;
using PagedList.Mvc;

namespace SunsUniversity.Controllers
{
    public class StudentController : Controller
    {
        private SchoolContext db = new SchoolContext();

        // GET: /Student/
        public ViewResult Index()
        {
            var students = from s in db.Students
                           select s;
            return View(students.ToList());
        }
        // GET: /Student/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Student student = db.Students.Find(id);
            if (student == null)
            {
                return HttpNotFound();
            }
            return View(student);
        }

        // GET: /Student/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: /Student/Create
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include="ID,LastName,FirstMidName,EnrollmentDate")] Student student)
        {
            try
            {
                if (ModelState.IsValid)
                {
                    db.Students.Add(student);
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
            }
            catch (DataException /* dex */)
            {
                //Log the error (uncomment dex variable name and add a line here to write a log.
                ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
            }
            return View(student);
        }

        // GET: /Student/Edit/5
        public ActionResult Edit(int? id)
        {
            var model = TempData["Index"];
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Student student = db.Students.Find(id);
            if (student == null)
            {
                return HttpNotFound();
            }
            return View(student);
        }

        // POST: /Student/Edit/5
        // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
        // more details see http://go.microsoft.com/fwlink/?LinkId=317598.
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include="ID,LastName,FirstMidName,EnrollmentDate")] Student student)
        {
            if (ModelState.IsValid)
            {
                db.Entry(student).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(student);
        }

        // GET: /Student/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Student student = db.Students.Find(id);
            if (student == null)
            {
                return HttpNotFound();
            }
            return View(student);
        }

        // POST: /Student/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Student student = db.Students.Find(id);
            db.Students.Remove(student);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

The Index:

@model IEnumerable<SunsUniversity.Models.Student>

@{
    ViewBag.Title = "Students";
}

<h2>@ViewBag.Title</h2>

<p class="indexOptions">
    @Html.ActionLink("Back", "Index", "Home")  @Html.ActionLink("Create New", "Create")
</p>
<table class="table table-striped table-hover">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.LastName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.FirstMidName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.EnrollmentDate)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.LastName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.FirstMidName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.EnrollmentDate)
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
            @Html.ActionLink("Details", "Details", new { id=item.ID }) |
            @Html.ActionLink("Delete", "Delete", new { id=item.ID })
        </td>
    </tr>
        }
    </tbody>
    <tfoot>
        <tr>
            <th class="filterable"></th>
            <th></th>
            <th class="filterable"></th>
            <th class="filterable"></th>
            <th></th>
            <th></th>
        </tr>
    </tfoot>

</table>

@section Outro{
    <script>
        $(document).ready(function () {
            var table = $('.table').DataTable();

            $(".table tfoot th").each(function (i) {
                if ($(this).hasClass("filterable")) {

                    var select = $('<select class="form-control"><option value="">Filter by</option></select>')
                    .appendTo($(this).empty())
                    .on('change', function () {
                        var val = $(this).val();

                        table.column(i)
                            .search(val ? '^' + $(this).val() + '$' : val, true, false)
                            .draw();
                    });

                    table.column(i).data().unique().sort().each(function (d, j) {
                        if (d.length > 0) {

                            select.append('<option value="' + d + '">' + d + '</option>');

                        }

                    });

                }
            });
        });
    </script>
}

Now my problem is: My application users asked if it were possible for pages that contain a table to remember the filter, sort order and current page of the table(because when they click a table item to carry out a task and then go back to it they'd like it to be "as they left it")

Cookies seem to be the way forward, but how to get the page to load these and set them in the table before it makes its first data request is a little beyond me at this stage.

Does anyone have any experience with this kind of thing? Thanks!

Few things can be added at the end in the Index file

Save Preferences : called from $(window).unload(function(){ ... });

Load Preferences : called from $(document).ready(function(){ ... });

The easiest way would be to save the filters, ordering and page you want to go to in the session storage, a cookie, or viewbag. You would send the parameters on all calls back to the server on back to page. EF doesn't support the operation you want as it only cares about getting and setting data. You have to manage the pagination, sorting, and filtering in YOUR code.

The example you refer to handles this by using these parameters of PagedList( a nuget package)

public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)

The parameters are what they say they are and are sent back on each page you navigate to.

Full method code:

public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
   ViewBag.CurrentSort = sortOrder;
   ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
   ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";

   if (searchString != null)
   {
      page = 1;
   }
   else
   {
      searchString = currentFilter;
   }

   ViewBag.CurrentFilter = searchString;

   var students = from s in db.Students
                  select s;
   if (!String.IsNullOrEmpty(searchString))
   {
      students = students.Where(s => s.LastName.Contains(searchString)
                             || s.FirstMidName.Contains(searchString));
   }
   switch (sortOrder)
   {
      case "name_desc":
         students = students.OrderByDescending(s => s.LastName);
         break;
      case "Date":
         students = students.OrderBy(s => s.EnrollmentDate);
         break;
      case "date_desc":
         students = students.OrderByDescending(s => s.EnrollmentDate);
         break;
      default:  // Name ascending 
         students = students.OrderBy(s => s.LastName);
         break;
   }

   int pageSize = 3;
   int pageNumber = (page ?? 1);
   return View(students.ToPagedList(pageNumber, pageSize));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM