zoukankan      html  css  js  c++  java
  • 排序、搜索、分页

    排序、搜索、分页

    系列教程:MVC5 + EF6 + Bootstrap3

     

    上一节:MVC5 + EF6 + Bootstrap3 (10) 数据查询页面

     

    源码下载:点我下载

     

    目录

     

     

    前言

     

    上一节我们做到了如下的一个基础查询页面。本节我们向这个页面中加入排序、搜索和分页功能。

     

     

    排序

     

    从上图中的地址栏中可以看到这个页面调用的是Company Controller下的Index Action.因此我们就先打开Controllers文件夹下的CompanyController.cs文件,写入如下代码:

     

    复制代码
     1 using System.Linq;
     2 using System.Web.Mvc;
     3 using SlarkInc.DAL;
     4 using System;
     5 
     6 namespace SlarkInc.Controllers
     7 {
     8     public class CompanyController : Controller
     9     {
    10         private CompanyContext db = new CompanyContext();
    11         public ViewResult Index(string sortOrder)
    12         {
    13             ViewBag.FirstNameSortParm = String.IsNullOrEmpty(sortOrder) ? "first_desc" : "";
    14             ViewBag.LastNameSortParm = sortOrder == "last" ? "last_desc" : "last";
    15             var workers = from w in db.Workers
    16                         select w;
    17             }
    18             switch (sortOrder)
    19             {
    20                 case "first_desc":
    21                     workers = workers.OrderByDescending(w => w.FirstName);
    22                     break;
    23                 case "last_desc":
    24                     workers = workers.OrderByDescending(w => w.LastName);
    25                     break;
    26                 case "last":
    27                     workers = workers.OrderBy(w => w.LastName);
    28                     break;
    29                 default:
    30                     workers = workers.OrderBy(w => w.FirstName);
    31                     break;
    32             }
    33             return View(workers.ToList());
    34         }
    35     }
    36 }
    复制代码

     

    第11行,Index Action 的参数sortOrder用来传递给Controller排序的信息。sortOrder有4个可能值。这4个值体现在18到32行的switch..case语句中。如果是first_desc则对FirstName用OrderByDescending倒序排列。如果是last_desc则对LastName倒序排列。如果是last则对LastName用OrderBy函数顺序排列。如果是空则对FirstName顺序排列。第13-14行用Viewbag存储当前排列的相反排列字符串,用于在View中生成链接。第15-16行,用Linq to Entity 从数据库中选取要排序的数据。第33行将排序好的数据以List的形式传递给View。

     

    在对应的View文件~ViewsCompanyIndex.cshtml中,修改其表头部分,代码如下。

     

    复制代码
    <tr>
            <th>
                @Html.ActionLink("First Name", "Index", new { sortOrder = ViewBag.FirstNameSortParm })
            </th>
            <th>
                @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.LastNameSortParm })
            </th>
            <th>@Html.DisplayNameFor(model => model.Sex)</th>
            <th>@Html.DisplayNameFor(model => model.Rating)</th>
    </tr>
    复制代码

     

     黄色的部分为修改后的代码。我们把以前纯文本的表头改成一个超链接,链接的参数从ViewBag中获得。点击链接可以获得与当前排序相反的排序效果。

     

     通过浏览器查看此页面。之后点击LastName链接,则按照上面代码会生成如下页面:

     

     

     

    参数sortOrder为last则这个表按lastName顺序排列。

     

    搜索

     

    一般查询页面都会有搜索功能帮助我们查看自己想要的页面。下面我们就来实现这个功能。

     

    还是从Controller开始,Index Action的代码写成如下形式:

     

    复制代码
     1 public ViewResult Index(string sortOrder, string searchString)
     2 {
     3     ViewBag.FirstNameSortParm = String.IsNullOrEmpty(sortOrder) ? "first_desc" : "";
     4     ViewBag.LastNameSortParm = sortOrder == "last" ? "last_desc" : "last";
     5     var workers = from w in db.Workers
     6                 select w;
     7     if (!string.IsNullOrEmpty(searchString))
     8     {
     9         workers = workers.Where(w => w.FirstName.Contains(searchString)
    10                                 || w.LastName.Contains(searchString));
    11     }
    12     switch (sortOrder)
    13     {
    14         case "first_desc":
    15             workers = workers.OrderByDescending(w => w.FirstName);
    16             break;
    17         case "last_desc":
    18             workers = workers.OrderByDescending(w => w.LastName);
    19             break;
    20         case "last":
    21             workers = workers.OrderBy(w => w.LastName);
    22             break;
    23         default:
    24             workers = workers.OrderBy(w => w.FirstName);
    25             break;
    26     }
    27     return View(workers.ToList());
    28 }
    复制代码

     

    上面代码中黄色的部分就是我们所添加的。第1行,searchString向Controller传递用来搜索的字符串。第7行,字符串不为空时执行搜索。这里的搜索用到了Linq里的Where函数,它通过一个Lambda表达式来筛选出符合条件的数据。这个条件就是9-10行的"或"连接的两个Contains函数。Contains函数表示其所属字符串是否包含其参数字符串。整个筛选条件表示返回所有FisrtName或LastName包含筛选字符串的记录。

     

     下面看~ViewsCompanyIndex.cshtml的改动:

     

    复制代码
    @using(Html.BeginForm())
    {
          <p>
               Find by name: @Html.TextBox("SearchString","", new { @class = "form-control", @Style = "display:inline" })
               @Html.Submit("Submit")
          </p>
    }
    复制代码

     

    在table的上面加入这些代码,它是一个Form,包含一个输入框和提交按钮,这个Form会把输入框中的搜索字符串提交给当前Controller完成搜索操作。其中的输入框,加入了class和style对其进行了Bootstrap美化。

     

    通过浏览器查看这个页面,在搜索框中输入b并且提交,之后会出现如下页面:

     

     

    可以看到搜索结果是FirstName或LastName包含b(不分大小写),的所有记录。

     

    分页

     

    数据查询免不了要分页。这里我们用一个名为PagedList的插件来实现这个功能。

     

    如下所示,在菜单栏里选择工具->库程序包管理->程序包管理控制台。

     

     

     之后会在Visual Studio窗口的下面看到一个程序包管理控制台窗口。在其中输入Install-Package PagedList.Mvc。PagedList就会自动安装到项目中。窗口如下所示。

     

     

    Paged List 安装好后,我们就开始修改代码,从Controller开始:

     

    复制代码
     1 using System.Linq;
     2 using System.Web.Mvc;
     3 using SlarkInc.DAL;
     4 using System;
     5 using PagedList;
     6 
     7 namespace SlarkInc.Controllers
     8 {
     9     public class CompanyController : Controller
    10     {
    11         private CompanyContext db = new CompanyContext();
    12         public ViewResult Index(string sortOrder, string searchString, string currentFilter, int? page)
    13         {
    14             ViewBag.CurrentSort = sortOrder;
    15             ViewBag.FirstNameSortParm = String.IsNullOrEmpty(sortOrder) ? "first_desc" : "";
    16             ViewBag.LastNameSortParm = sortOrder == "last" ? "last_desc" : "last";
    17             if(searchString != null)
    18             {
    19                 page = 1;
    20             }
    21             else
    22             {
    23                 searchString = currentFilter;
    24             }
    25             ViewBag.CurrentFilter = searchString;
    26 
    27             var workers = from w in db.Workers
    28                         select w;
    29             if (!string.IsNullOrEmpty(searchString))
    30             {
    31                 workers = workers.Where(w => w.FirstName.Contains(searchString)
    32                                         || w.LastName.Contains(searchString));
    33             }
    34             switch (sortOrder)
    35             {
    36                 case "first_desc":
    37                     workers = workers.OrderByDescending(w => w.FirstName);
    38                     break;
    39                 case "last_desc":
    40                     workers = workers.OrderByDescending(w => w.LastName);
    41                     break;
    42                 case "last":
    43                     workers = workers.OrderBy(w => w.LastName);
    44                     break;
    45                 default:
    46                     workers = workers.OrderBy(w => w.FirstName);
    47                     break;
    48             }
    49             int pageSize = 3;
    50             int pageNumber = (page ?? 1);
    51             return View(workers.ToPagedList(pageNumber,pageSize));
    52         }
    53     }
    54 }
    复制代码

     

     黄色标记的为需要改动的部分。第5行,需要引用PagedList。第12行currentFilter参数用来在翻页时保持搜索字符串不丢失。第17到25行的作用是,当有一个新的字符串要搜索,那么翻当前页就自动变成第一页,否则,当前页不变。第49-51行设置每页3条数据,设置页数,并将数据以List的形式发送个View。其中(page ?? 1)的意思是如果page为null则给page赋值为1否则,page不为null那么该是多少就是多少。所以能让默认页为1.

     

    复制代码
     1 @model PagedList.IPagedList<SlarkInc.Models.Worker>
     2 @using PagedList.Mvc;
     3 <link href="~/Content/PagedList.css" rel="stylesheet" />
     4            <br />
     5            @using(Html.BeginForm("Index","Company",FormMethod.Get))
     6            {
     7                <p>
     8                    Find by name: @Html.TextBox("SearchString",ViewBag.CurrentFilter as string, new { @class = "form-control", @Style = "display:inline" })
     9                    @Html.Submit("Submit")
    10                </p>
    11            }
    12 <table class="table">
    13     <tr>
    14         <th>
    15             @Html.ActionLink("First Name", "Index", new { sortOrder = ViewBag.FirstNameSortParm })
    16         </th>
    17         <th>
    18             @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.LastNameSortParm })
    19         </th>
    20         <th>Sex</th>
    21         <th>Rating</th>
    22     </tr>
    23     @foreach (var item in Model)
    24     {
    25         <tr>
    26             <td>
    27                 @Html.DisplayFor(modelItem => item.FirstName)
    28             </td>
    29             <td>
    30                 @Html.DisplayFor(modelItem => item.LastName)
    31             </td>
    32             <td>
    33                 @Html.DisplayFor(modelItem => item.Sex)
    34             </td>
    35             <td>
    36                 @Html.DisplayFor(modelItem => item.Rating)
    37             </td>
    38         </tr>
    39     }
    40 </table>
    41 <br/>
    42 Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
    43 @Html.PagedListPager(Model, page => Url.Action("Index",
    44     new {page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter}))
    复制代码

     

     第1行定义了PagedList 类型的model。第2行引用PagedList。第3行,引入,PagedList相关的css文件,这个文件在安装插件的时候会自动保存到项目里。第5行BeginForm函数的参数有变化,其生成的Form会使用Get方法。Get方法会在url里显示提交的参数,这样可以通过url来记录查询参数,方便通过复制url给他人来展现自己的查询结果。第42行用于显示第几页,共几页。第43-44行,用于生成每一页的按钮。

     

    运行此页面,当页面出来时点击页面下方的"2"按钮转到第2页。生成的页面如下所示:

     

     

    可以看到页面下方的分页按钮和页数统计,美观大方。

     

    结尾

     

    嗯,不知不觉,快半夜一点了。加油!

     

    喜欢的话就推荐下吧!

     

    上一节:MVC5 + EF6 + Bootstrap3 (10) 数据查询页面

     

    作者:Slark.NET

    出处:http://www.cnblogs.com/slark/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。如有问题或建议,请多多赐教,非常感谢。

     

     

     

  • 相关阅读:
    TypeError: can't compare offset-naive and offset-aware datetimes bugfix
    pg_restore数据库恢复指令
    第四十期百度技术沙龙笔记整理
    JS事件模型小结
    matlab Newton method
    Markdown 语法的简要规则
    iOS社交分享Twitter、Facebook、拷贝到剪切板、LINE、及邮件
    Linux系统调用过程分析
    iOS自己定义返回button(不影响返回手势)
    MAVEN项目模块化
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4204480.html
Copyright © 2011-2022 走看看