2012年7月9日 星期一

ASP.NET MVC 資料分頁 MVCPaging 2.0 應用 Part.4:分頁進階處理

MvcPaging 2.0 的應用在前三篇文章中,從一般的資料分頁開始實作,再修改為 AJAX 資料分頁,到了 Part.3 這一篇的 AJAX 資料分頁就改使用 jQuery 來處理,這一系列的實作應該可以對使用 MvcPaging 來處理資料分頁有了一定的了解,而接下來這一篇將介紹比較進階的操作處理,我們將以「Dynamic LINQ + Entity Framework - Part.4:ASP.NET MVC 進階應用」這一篇的實作範例來做修改。

image


對「Dynamic LINQ + Entity Framework - Part.4:ASP.NET MVC 進階應用」實作範例的資料分頁修改已經完成,如下:

一般的資料分頁

image

使用 jQuery 的 AJAX 分頁

image

因為這兩個部分的修改都是跟之前的文章內容大致相同,所以就沒有再寫文章來做介紹。

 

有個地方對於操作的便利性並不是很好,這個地方就是「資料欄位的排序選擇與顯示」

image

雖然說我們在表單中有提供排序欄位以及排序類型的下拉選單讓使用者做選擇,而在送出表單的資料後,在顯示的資料表格的欄位名稱列也會對目前的排序欄位與排序類型做特別的顯示,

image

但如果可以直接點選表格的標題欄位來做為排序欄位與排序類型的選擇,這樣的操作方式對使用者來說會是比較清楚與直接的方式,接下來我們就要做這樣的修改,並且維持 AJAX 的顯示方式,以及移除表單中的排序欄位與排序類型的下拉選單。

 

我們在「Dynamic LINQ + Entity Framework - Part.4:ASP.NET MVC 進階應用」這篇文章中有做一個功能,這個功能就是讓表格的欄位標題可以將排序的欄位與類別做明顯的顯示,下面的這個 method 就是做這個事情,

   1:  #region -- DisplaySortColumnStyle --
   2:   
   3:  /// <summary>
   4:  /// Displays the sort column style.
   5:  /// </summary>
   6:  /// <param name="columnName">Name of the column.</param>
   7:  /// <returns></returns>
   8:  private MvcHtmlString DisplaySortColumnStyle(string columnName)
   9:  {
  10:      string result = columnName;
  11:   
  12:      if (columnName.Equals(this.SortColumnName, StringComparison.OrdinalIgnoreCase))
  13:      {
  14:          string displayColumnName = string.Format("<span style=\"color: red;\">{0} {1}</span>",
  15:              columnName,
  16:              this.SortType.Equals("asc", StringComparison.OrdinalIgnoreCase) ? "▲" : "▼");
  17:   
  18:          result = displayColumnName;
  19:      }
  20:   
  21:      return MvcHtmlString.Create(result);
  22:  }
  23:   
  24:  #endregion

而在 Controller 的 Action() 方法中的 ViewBag 用 Func 來載入這個 method

ViewBag.DisplaySortColumnStyle = new Func<string, MvcHtmlString>(DisplaySortColumnStyle);

然後前端的 View Page 的表格欄位修改為以下的內容,就可以對有排序的欄位做明顯的顯示處理,

<th>
    @ViewBag.DisplaySortColumnStyle("CompanyName")
</th>
<th>
    @ViewBag.DisplaySortColumnStyle("ContactName")
</th>
<th>
    @ViewBag.DisplaySortColumnStyle("ContactTitle")
</th>
<th>
    @ViewBag.DisplaySortColumnStyle("Address")
</th>
<th>
    @ViewBag.DisplaySortColumnStyle("City")
</th>
<th>
    @ViewBag.DisplaySortColumnStyle("Region")
</th>
<th>
    @ViewBag.DisplaySortColumnStyle("PostalCode")
</th>
<th>
    @ViewBag.DisplaySortColumnStyle("Country")
</th>
<th>
    @ViewBag.DisplaySortColumnStyle("Phone")
</th>
<th>
    @ViewBag.DisplaySortColumnStyle("Fax")
</th>

顯示執行結果

image

 

但現在我們的作法則是,這個表格欄位標題不僅是顯示用途,而是要讓使用者可以點選,用點選欄位的方式取代原來選擇下拉選單的方式,所以後端 Controller 的 method 以及前端 View Page 都需要做修改,首先要新增加一個 method,我們要讓欄位標題顯示的是一個可以點選的 HyperLink element,增加的 method 如下:

   1:  #region -- SortColumnLink --
   2:  /// <summary>
   3:  /// sort column HyperLink.
   4:  /// </summary>
   5:  /// <param name="columnName">Name of the column.</param>
   6:  /// <returns></returns>
   7:  private MvcHtmlString SortColumnLink(string columnName)
   8:  {
   9:      string result = string.Format("<a class=\"sortColumnLink\" href=\"{0}\" id=\"{0}_{1}\">{2}</a>", columnName, "asc", columnName);
  10:   
  11:      if (columnName.Equals(this.SortColumnName, StringComparison.OrdinalIgnoreCase))
  12:      {
  13:          string sortColumnLink = string.Format("<a class=\"sortColumnLink\" href=\"{0}\" id=\"{0}_{1}\" style=\"color: red;\">{2} {3}</a>",
  14:              columnName,
  15:              this.SortType,
  16:              columnName,
  17:              this.SortType.Equals("asc", StringComparison.OrdinalIgnoreCase) ? "▲" : "▼");
  18:   
  19:          result = sortColumnLink;
  20:      }
  21:   
  22:      return MvcHtmlString.Create(result);
  23:  } 
  24:  #endregion

處理 PartialView 的 Action 方法中的 ViewBag 則是修改為:

ViewBag.DisplaySortColumnLink = new Func<string, MvcHtmlString>(SortColumnLink);

前端 PartialView 的內容如下:

@model PagedList<MvcMSSQL.Models.Customer>
 
@if (Model != null && Model.Count > 0)
{
    <div class="pager">
        @Html.Pager(Model.PageSize, Model.PageNumber, Model.TotalItemCount)
 
        Displaying @Model.ItemStart - @Model.ItemEnd of @Model.TotalItemCount item(s)
    </div>
    <br />
    
    <table>
        <thead>
            <th>
                @ViewBag.DisplaySortColumnLink("CompanyName")
            </th>
            <th>
                @ViewBag.DisplaySortColumnLink("ContactName")
            </th>
            <th>
                @ViewBag.DisplaySortColumnLink("ContactTitle")
            </th>
            <th>
                @ViewBag.DisplaySortColumnLink("Address")
            </th>
            <th>
                @ViewBag.DisplaySortColumnLink("City")
            </th>
            <th>
                @ViewBag.DisplaySortColumnLink("Region")
            </th>
            <th>
                @ViewBag.DisplaySortColumnLink("PostalCode")
            </th>
            <th>
                @ViewBag.DisplaySortColumnLink("Country")
            </th>
            <th>
                @ViewBag.DisplaySortColumnLink("Phone")
            </th>
            <th>
                @ViewBag.DisplaySortColumnLink("Fax")
            </th>
        </thead>
        <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @item.CompanyName
                </td>
                <td>
                    @item.ContactName
                </td>
                <td>
                    @item.ContactTitle
                </td>
                <td>
                    @item.Address
                </td>
                <td>
                    @item.City
                </td>
                <td>
                    @item.Region
                </td>
                <td>
                    @item.PostalCode
                </td>
                <td>
                    @item.Country
                </td>
                <td>
                    @item.Phone
                </td>
                <td>
                    @item.Fax
                </td>
            </tr>
        }
        </tbody>
    </table>
}

而這個 PartialView 中的 jQuery 處理:

   1:  <script type="text/javascript">
   2:      $(document).ready(function () {
   3:          $('.pager> a').each(function (i, item) {
   4:              var page = $(item).attr('href').replace('@(Url.Action("PagedAjax2Partial", "Advanced"))?page=', '');
   5:              $(item).attr('href', '#').click(function () { postPage(page); });
   6:          });
   7:   
   8:          $('[class="sortColumnLink"]').each(function (i, item) {
   9:              var sortColumnName = $(item).attr('href');
  10:              var sortType = $(item).attr('id').replace(sortColumnName + "_", "");
  11:              var currentStyle = $(item).attr('style');
  12:              if ($.trim(currentStyle).length > 0) {
  13:                  sortType = sortType == 'asc' ? 'desc' : 'asc';
  14:              }
  15:   
  16:              $(item).attr('href', '#').click(function () {
  17:                  $('#sortColumnName').val(sortColumnName);
  18:                  $('#sort').val(sortType);
  19:                  ButtonSubmitEventHandler();
  20:              });
  21:          });
  22:      });
  23:  </script>

我想我應該不用再解釋上面的 jQuery 程式內容,我用的方式相當淺顯。

 

最後來看看修改後的執行結果:

一開始的頁面

image

先不更改表單中的內容,點選「submit」執行

image

點選表格標題的「CompanyName」,會對資料的欄位「CompanyName」做 asc 的排序,

image

再點選一次「CompanyName」,則會對資料的欄位「CompanyName」做 desc 的排序,

image

點選 Pager 的分頁連結也不會影響排序欄位與排序類型,

image

點選其他的欄位標題做排序欄位的更換,則是對新點選的欄位做 asc 的排序處理,而分頁則會回到第一頁,

image

 

最後來一段操作的影片來做結尾,這一段影片會比較長一點,會把這個進階操作的各個分頁處理都執行一次。

 

操作影片

 

延伸閱讀

Dynamic LINQ + Entity Framework - Part.4:ASP.NET MVC 進階應用

ASP.NET MVC 3 - ViewBag 裡使用方法(Method)

 

以上

2 則留言:

  1. 您好
    SortColumnLink 的功能 是負責顯示 排序的link
    您原本的code會顯示出原始的columnName
    我想如果能直接顯示 Metadata的DisplayName會更加方便
    於是我找到下列資料可以參考
    Using an Associated Metadata Class outside Dynamic Data
    http://blogs.msdn.com/b/davidebb/archive/2009/07/24/using-an-associated-metadata-class-outside-dynamic-data.aspx

    實作也成功了

    回覆刪除

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。