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. 原來如此,我終於搞懂了,也知道怎麼做了,感謝你的仔細回答。

      刪除

提醒

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