網頁

2012年11月19日 星期一

MVC Themed App - 修改 jQuery Plugin「DataTables」顯示文字為正體中文

事情是這樣的,昨天有位朋友在「ASP.NET MVC 3 使用新的專案樣板–MVC Themed App」這篇文章提出問題,一開始給我的訊息是說修改 MVC Themed App 內建 T4 Templates 內容後會出現錯誤,原本想要顯示中文的地方卻是顯示為亂碼,以致於一開始我的回答是以解決 T4 Template 亂碼的方向,

image

但後來這位朋友給了一個比較明確的線索,

image

我想有使用過 jQuery.DataTables.js 的朋友應該知道要怎麼解決,不過我在這邊記錄怎麼解決置換中文顯示的方法。

 


DataTables

http://datatables.net/

先來稍微認識一下這個 DataTables 套件,是一個使用 jQuery library 前端外掛套件,提供一個簡單的設定方式就可以讓原來的 Table 有很多增強功能,而且重點是 …… 這個 Plugin 是免費的。

image

如果對這個 Plugin 有興趣或是想要知道它有什麼樣的功能,建議可以參考網站中的範例演示,

http://datatables.net/examples/

 

回到 MVC Themed App 這套 Project Template 上,相關的介紹可以參考「ASP.NET MVC 3 使用新的專案樣板–MVC Themed App」這篇文章,我這邊使用 MVC Themed App 的 Project Template 建立了一個 ASP.NET MVC 專案(這個 Project Template 只有支援 ASP.NET MVC 3),如下:

image

我這裡並沒有做什麼樣的修改,只有先加入資料庫使用「Northwind」的 ADO.NET 實體資料模型,

image

網站執行首頁

SNAGHTML4768e1

接著我們使用 MVC Themed App 的內建 T4 Template 來建立一個 List 頁面,

HomeController / ProductList

image

加入檢視

image

勾選「建立強型別檢視」並且在「模型類別」的下拉選單中選擇「Products (MVCThemedApp1.Models)」

image

接著選擇「Scaffold 樣板」中的「List」,

image

最後選擇「主版頁面」然後點選「加入」以完成整個加入檢視的步驟,

SNAGHTML5b5467

Views/ Home / ProductList.cshtml

@model IEnumerable<MVCThemedApp1.Models.Products>
 
@{
    ViewBag.Title = "ProductList";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
    <script src="@Url.Content("~/Scripts/jquery.dataTables.js")" type="text/javascript"></script>
    列表:
    <div id="block-tables" class="block">
        <div class="content">
            <div class="inner">
    <table id="datalist" class="table">
    <thead>
        <tr>
            <th></th>
            <th>
                ProductName
            </th>
            <th>
                SupplierID
            </th>
            <th>
                CategoryID
            </th>
            <th>
                QuantityPerUnit
            </th>
            <th>
                UnitPrice
            </th>
            <th>
                UnitsInStock
            </th>
            <th>
                UnitsOnOrder
            </th>
            <th>
                ReorderLevel
            </th>
            <th>
                Discontinued
            </th>
        </tr>
    </thead>
    <tbody>
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id=item.ProductID }) |
                @Html.ActionLink("Details", "Details", new { id=item.ProductID }) |
                @Html.ActionLink("Delete", "Delete", new { id=item.ProductID })
            </td>
            <td>
                @item.ProductName
            </td>
            <td>
                @item.SupplierID
            </td>
            <td>
                @item.CategoryID
            </td>
            <td>
                @item.QuantityPerUnit
            </td>
            <td>
                @String.Format("{0:F}", item.UnitPrice)
            </td>
            <td>
                @item.UnitsInStock
            </td>
            <td>
                @item.UnitsOnOrder
            </td>
            <td>
                @item.ReorderLevel
            </td>
            <td>
                @item.Discontinued
            </td>
        </tr>
    }
    </tbody>
    </table>
            </div>
        </div>
    </div>
    <script type="text/javascript">
        $(document).ready(function () {
            $('#datalist').dataTable({
                "sPaginationType": "full_numbers"
            });
        });
    </script>
    

重新建置專案,瀏覽 ProductList 的顯示結果,

image

這個 List Scaffold 的 T4 Template 是在專案的「CodeTemplates / AddView / CSHTML / List.tt」,

image

基本上這個 List.tt 主要是負責去產出 Table 內容,並且在這個 Templates 中去設定 dataTable 的內容,

image

 

jQuery.DataTables.js

image

一開始就有說過 MVC Themed App 預設使用 DataTables 套件來置換一般 Table 的樣式並添加 Table 的功能,但是 DataTables 預設的顯示文字為英文,在 jQuery.dataTables.js 中是預先設定好的,設定的內容就在程式的 Line 967 ~ 987,

image

這邊的預設顯示文字內容可不要直接動手去改它,要是直接去修改的話,最後在頁面上的顯示就會出現亂碼,

例如我把分頁列的顯示文字直接修改為以下的內容,

image

執行後的列表頁面,在分頁列的顯示文字就會變成亂碼而不是我們所修改的文字,

image

難道就無法去修改顯示的文字內容嗎?

其實是可以的,只不過不可以直接去修改 jquery.datatales.js 的內容,有關如何修改的方法在 DataTables 的網站上都有詳細的說明,

「DataTables > Plug-ins > Internationalisation 」

http://datatables.net/plug-ins/i18n

image

在「Internationalisation 」的頁面裡有提供了多種的語言,可以有多種語言的文字顯示,當然其中有包含「正體中文 Chinese (traditional)」,

image

{
    "sProcessing":   "處理中...",
    "sLengthMenu":   "顯示 _MENU_ 項結果",
    "sZeroRecords":  "沒有匹配結果",
    "sInfo":         "顯示第 _START_ 至 _END_ 項結果,共 _TOTAL_ 項",
    "sInfoEmpty":    "顯示第 0 至 0 項結果,共 0 項",
    "sInfoFiltered": "(從 _MAX_ 項結果過濾)",
    "sInfoPostFix":  "",
    "sSearch":       "搜索:",
    "sUrl":          "",
    "oPaginate": {
        "sFirst":    "首頁",
        "sPrevious": "上頁",
        "sNext":     "下頁",
        "sLast":     "尾頁"
    }
}

我們把上面的語言文字顯示內容複製並另存為「dataTables.Chinese.traditional.txt

image

接著回到 ProductList.cshtml 檔案(記得先把之前曾經對 jquery.datatables.js 修改的地方給恢復原狀),將頁面中設定 dataTables 的地方增加顯示語言文字檔的指定,

image

$(document).ready(function () {
    $('#datalist').dataTable({
        "sPaginationType": "full_numbers",
        "oLanguage": {
            "sUrl": "/Scripts/dataTables.Chinese.traditional.txt"
        }
    });
});

修改好之後就存檔並重新整理瀏覽器的頁面,就可以看到不只是分頁列的顯示文字,其餘功能的顯示文字都是正體中文了,

image

 

如果每建立一個 List 頁面就要去修改頁面中的 dataTables 設定的話就太累人了,所以一勞永逸的做法就是直接修改 List 的 Code Template 內容,這樣一來後續所建立的 List 頁面就不需要去手動增加顯示文字檔的指定了。

 

開啟 Code Template - List.tt,移到 Line 133 的地方,

image

我們把剛才所增加的顯示文字語言檔的指令給加進去,

image

現在我們新增一個 List 頁面,建立的步驟在前面已經說明過了,這邊就不再重複說明,

image

CustomerList.cshtml,這邊的顯示文字語言檔的指定是由 Code Template 建立的,

image

顯示結果,

image

 


jQuery Plugin - DataTables 是個相當不錯的前端套件,提供以及支援的功能也相當多,ASP.NET MVC 所開發的網站專案中,在前端的資料列表顯示可以將 DataTables 列入選項之一。

 

以上

10 則留言:

  1. 亂入一下,如果真的要在 jQuery.dataTables.js 修改,那可以試試看,"另存新檔(encoding 改成 utf-8)",看看可不可以成功!

    回覆刪除
  2. 補充一下,用記事本去另存..

    回覆刪除
    回覆
    1. 直接修改 jQuery.dataTables.js 的內容並且以 UTF-8 來存檔是可以的,
      這也是我一開始跟這位朋友所說的方式,
      但因為 DataTables 有提供語言檔,所以就不採用直接修改 jQuery.DataTables.js 內容的方式,
      採用載入語言檔的方式是因為這樣可以保留彈性,
      尤其是當有可能碰上多語系網站開發的時候,保留彈性的作法才不會搞死自己。

      刪除
  3. 新手入門,正在測試選用Table前端套件,請問這個DataTables和MvcPaging有何異同 ?

    回覆刪除
    回覆
    1. 啊?兩個是不一樣的東西,怎麼能夠拿來做比較呢?
      DataTables 是一個 jQuery Plugins, 將資料以 Table 方式呈現,並且有自帶的 Pagenation 功能。
      而 MvcPaging 是一個用在 ASP.NET MVC 的分頁功能的 Helper,
      所以兩者是完全不同的功能,而且使用的地方也不同,
      前者是前端的 jQuery 使用,後者是 ASP.NET MVC 伺服器端程式與 View 的使用,
      所以要搞清楚呀~

      刪除
    2. 35 Amazing jQuery Tables | jQuery4u
      http://www.jquery4u.com/plugins/30-amazing-jquery-tables/

      上面的連結給你參考,至於那一個比較好以及有什麼不同等,這就要你自己評估。

      刪除
    3. 還是搞不清楚 ... 功能上,因為都有"分頁"這相同的功能,你卻說完全不同
      若使用的地方不同,是否可撘配一起使用,我現在的理解是:

      後端若沒有分頁,是把所有資料丟給前端 DataTables 將資料以 Table 方式呈現,並且有自帶的 Pagenation 功能。
      後端若用 MvcPaging 分頁,是只帶當頁的資料給前端呈現,所以前端就不用再分頁了是嗎 ?

      如果我理解太離譜,我只有把兩個都實際操作一遍,也許就懂了 ^^

      刪除
    4. 你一開始所問的問題就很讓人摸不著頭緒「請問這個DataTables和MvcPaging有何異同 ?」
      我的回答說這兩個東西是不同的所以不能比較,之後你的回答讓我覺得你開始的問題就問錯了。

      資料的分頁不一定需要 MvcPaging 才能處理,一般使用 LINQ 的 Skip 與 Take 就可達到取得分頁資料的結果,使用 MvcPaging 是可以幫我處理一些其他的分頁資料。
      MvcPaging 是個 ASP.NET MVC 的 Helper,他可以在前端產出 Pager,可以減少程式人員需要處理前端分頁顯示的操作,例如計算頁數、資料數量、產收多少頁碼等。

      jQuery DataTables 是個前端套件,有自帶分頁功能,這需要在前端的 javascript 裡去處理。

      你所說的後端如果用 MvcPaging 分頁,然後前端依然使用 DataTables,是可以達到取得分頁資料,但是前端 DataTables 的 Pagenation 就沒有功用了,以這一篇文章的分頁資料顯示,是把全部的資料都 render 到前端 HTML 裡,然後 DataTables 再去處理分頁,所以每一次的分頁都不會再向後端取得資料,但是這樣的作法在大量資料上就不是很適當,因為需要一次把所有的資料 render 到 HTML 上,如果資料有成千上萬筆的話就不是很好。

      而 DataTables 還有很多種的分頁資料處理方式,你可以參考 DataTables 官網上的 Examples 與 API 說明
      https://datatables.net/examples/

      我不會建議你將 DataTables 與 MvcPaging 混用,在我看來你只是想要前端的 Table 顯示樣式與 DataTables 一樣,但是分頁想要用 Mvcpaging 來處理。

      我會建議你,先搞懂什麼是前端、什麼是後端,然後了解 MvcPaging 怎麼用、能做什麼處理再說,而使用 DataTables 的話,也是需要看一遍他的 Examples 與 API,如此才會知道怎麼讓分頁資料在後端處理後在由前端顯示,而不是一開始就用相當不清處理的問題來問 DataTables 與 MvcPaging 有什麼不同,要問就要問重點,而且要提問要清楚。

      最後,當然你可以將 DataTables 與 Mvcpaging 搭配使用,只是這樣的作法就完全忽略了 DataTables 的特點,只是單純地使用外觀與樣式而已,至於怎麼做,我沒有研究過,請自行 Google.

      刪除
    5. ASP.NET MVC 與 DataTables 相關文章參考:
      http://www.datatables.net/examples/server_side/post.html

      CodeProject
      http://www.codeproject.com/Articles/155422/jQuery-DataTables-and-ASP-NET-MVC-Integration-Part1
      文章裡還有其他五篇系列文章連結

      刪除
    6. 原來如此,我終於搞懂了,也知道怎麼做了,感謝你的仔細回答。

      刪除