使用jsGrid

by vivid 13. 六月 2018 11:59

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號: N180619601
出刊日期: 2018/6/13

本文將介紹如何在MVC 5的專案之中,整合「jsGrid」以表格的方式呈現從資料庫取回的資料,並且能夠根據不同欄位排序、設計資料分頁等功能。

「jsGrid」是一個前端的輕量Grid jQuery Plugin,以「jQuery」為基礎,支援表格資料的排序、分頁、新增、篩選、編輯、刪除等功能,詳細功能說明可以參考以下官網:「http://guriddo.net」。「jsGrid」是使用MIT授權條款的自由軟體,可免費使用於商業或個人用途。

以下以Step-by-Step方式說明如何在ASP.NET MVC 5專案中分別使用「jsGrid」來設計資料分頁網頁。

 

建立ASP.NET MVC 5專案

啟動Visual Studio 2017開發環境,從「File」-「New」-「Project」,在「New Project」對話盒中,確認視窗上方.NET Framework的目標版本為「.NET Framework 4.6.1以上」,選取左方「Installed」-「Templates」-「Visual C#」程式語言,從「Web」分類中,選取「ASP.NET Web Application (.NET Framework)」,設定專案名稱,如「jsGridDemo」、設定專案存放路徑,然後按下「OK」鍵,請參考下圖所示:

clip_image002

圖 1:建立ASP.NET MVC 5專案。

在「New ASP.NET Web Application」對話盒中選取「Empty」,勾選下方的「MVC」項目,然後按下「OK」按鈕建立專案,請參考下圖所示:

clip_image004

圖 2:選取「Empty」MVC專案。

安裝必要套件

接下來的步驟要整合「jQuery」與「jsGrid」套件,我們需要在專案中安裝以下版本的套件:

· jQuery: 3.3.1版。

· jsGrid:1.5.3版。

從Visual Studio 2017開發工具 -「Solution Explorer」視窗 - 專案名稱上方按滑鼠右鍵,從快捷選單選擇「Manage Nuget Packages」,開啟對話盒,接著選取視窗上方的「Browse」分頁,並在上方的文字方塊中輸入關鍵字「jQuery」進行篩選,下方便會列出可安裝的套件,選取其中的「jQuery」套件,在右方的下拉式清單方塊中,選取要使用的「3.3.1」版,然後按下「Install」按鈕進行安裝,請參考下圖所示:

clip_image006

圖 3:安裝「jQuery」套件。

下一步驟會看到安裝確認視窗,直接按「OK」按鈕,請參考下圖所示:

clip_image008

圖 4:確認安裝。

加入jsGrid相關檔案

接著手動從官網下載「jsGrid」相關檔案,再將必要檔案加入專案之中。從官網「http://js-grid.com」,選取「ASP.NET MVC」分類下的「Download jsGrid」按鈕進行下載,請參考下圖所示:

clip_image010

圖 5:下載「jsGrid」。

下載方式有許多種,我選擇下載「1.5.3.zip」檔案,請參考下圖所示:

clip_image012

圖 6:手動下載「jsGrid」。

解壓縮從官網下載的「jsgrid-1.5.3.zip」檔案,找到以下檔案,將之加入專案中的「Scripts」資料夾:

· jsgrid.min.js

· jsgrid-zh-tw.js

找到以下檔案,將之加入專案中的「Content」資料夾(需要自行建立此資料夾):

· jsgrid.min.css

· jsgrid-theme.min.css

 

建立ADO.NET實體資料模型

下一步是使用Visual Studio的功能來定義ADO.NET實體資料模型,然後利用Entity Framework Database First技術自動根據資料庫結構描述資訊來建立模型。在MVC的專案之中,通常將ADO.NET實體資料模型的相關程式置於「Models」資料夾之中。

從Visual Studio 2017開發工具 -「Solution Explorer」- 專案-「Models」資料夾上方按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」,開啟「Add New Item」對話盒。

在「Add New Item」對話盒選取「ADO.NET Entity Data Model」項目,設定名稱為「PubsModel」,請參考下圖所示:

clip_image014

圖 7:建立ADO.NET實體資料模型。

然後在「Entity Data Model Wizard」 視窗,選取「EF Designer from Database」項目,按下「Next」按鈕,請參考下圖所示:

clip_image016

圖 8:選取「EF Designer from Database」項目。

在「Choose Your Data Connection」的步驟視窗選擇連接到「Pubs」資料庫,然後按下「Next」按鈕,請參考下圖所示:

clip_image018

圖 9:連接到「Pubs」資料庫。

在 「Choose Your Version」 步驟,請選擇「Entity Framework 6.x」,按下「Next」按鈕,請參考下圖所示:

clip_image020

圖 10:選擇「Entity Framework 6.x」版本。

在 「Choose Your Database Objects and Settings」步驟 ,展開「Table」à「dbo」勾選「Authors」,並勾選下方的「Pluralize or singularize generated object names」。如下圖所示,並按下「Finish」按鈕完成 「Entity Data Model Wizard」 的設計步驟。

clip_image022

圖 11:勾選資料表。

選取Visual Studio 開發工具「Build」-「Build Solution」項目編譯目前的專案,確認程式碼能正確編譯。

設計控制器

從Visual Studio 2017開發工具 -「Solution Explorer」視窗- 專案 -「Controllers」資料夾上方按滑鼠右鍵,從快捷選單選擇「Add」- 「Controller」,開啟「Add Scaffold」對話盒。選取「MVC 5 Controller - Empty」,然後按下「Add」按鈕,請參考下圖所示:

clip_image024

圖 12:新增控制器。

在「Add Controller」對話盒中,設定控制器名稱為「HomeController」;然後按下「Add 」按鈕,Visual Studio 2017便會在「Controllers」資料夾下,新增HomeController.cs,包含控制器程式碼基本的程式碼,請參考下圖所示:

clip_image026

圖 13:新增HomeController控制器。

取回JSON資料

在新增的「HomeController.cs」檔案中加入程式碼。於「HomeController」類別中加入一個「GetData」方法可以從資料庫中查詢特定分頁的資料,然後回傳JSON格式資料供前端使用:

using jsGridDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace jsGridDemo.Controllers {
  public class HomeController : Controller {
    pubsEntities _db = new pubsEntities( );
    // GET: Home
    public ActionResult Index( ) {
      return View( );
    }
    public JsonResult GetData( int pageSize = 10 , string sortOrder = "asc" , string sortField = "au_id" , int pageIndex = 1 ) {
      IQueryable<author> authors = _db.authors;

      switch ( sortField ) {
        case "au_lname":
          authors = ( sortOrder == "asc" ) ? authors.OrderBy( a => a.au_lname ) : authors.OrderByDescending( a => a.au_lname );
          break;
        case "au_fname":
          authors = ( sortOrder == "asc" ) ? authors.OrderBy( a => a.au_fname ) : authors.OrderByDescending( a => a.au_fname );
          break;
        case "phone":
          authors = ( sortOrder == "asc" ) ? authors.OrderBy( a => a.phone ) : authors.OrderByDescending( a => a.phone );
          break;
        case "address":
          authors = ( sortOrder == "asc" ) ? authors.OrderBy( a => a.address ) : authors.OrderByDescending( a => a.address );
          break;
        case "city":
          authors = ( sortOrder == "asc" ) ? authors.OrderBy( a => a.city ) : authors.OrderByDescending( a => a.city );
          break;
        default:
          authors = ( sortOrder == "asc" ) ? authors.OrderBy( a => a.au_id ) : authors.OrderByDescending( a => a.au_id );
          break;
      }

      int itemsCount = authors.Count( );
      int totalPages = (int) Math.Ceiling( (float) itemsCount / (float) pageSize );
      var jsonData = new {
        data = authors.Skip( ( pageIndex - 1 ) * pageSize ).Take( pageSize ).ToList( ) ,
        itemsCount
      };

      return Json( jsonData , JsonRequestBehavior.AllowGet );
    }
  }
}

 

測試伺服端資料

選取Visual Studio開發工具,「Build」-「Build Solution」編譯目前的專案,確認程式碼能正確編譯。然後按CTRL+F5執行網站,忽略掉網頁出現的錯誤訊息,直接在Visual Studio自動啟動的瀏覽器,輸入以下網址查詢出10筆作者資料(請注意:埠號可能會依據實際上的操作而有所不同,如以下的「61267」,請修改為實際的埠號):

http://localhost:61267/home/getdata

若沒有問題瀏覽器會收到以下JSON格式的資料:

{

"data":

[

{ "au_id": "172-32-1176", "au_lname": "White", "au_fname": "Johnson", "phone": "408 496-7223", "address": "10932 Bigge Rd.", "city": "Menlo Park", "state": "CA", "zip": "94025", "contract": true },

{ "au_id": "213-46-8915", "au_lname": "Green", "au_fname": "Marjorie", "phone": "415 986-7020", "address": "309 63rd St. #411", "city": "Oakland", "state": "CA", "zip": "94618", "contract": true },

{ "au_id": "238-95-7766", "au_lname": "Carson", "au_fname": "Cheryl", "phone": "415 548-7723", "address": "589 Darwin Ln.", "city": "Berkeley", "state": "CA", "zip": "94705", "contract": true },

{ "au_id": "267-41-2394", "au_lname": "O\u0027Leary", "au_fname": "Michael", "phone": "408 286-2428", "address": "22 Cleveland Av. #14", "city": "San Jose", "state": "CA", "zip": "95128", "contract": true },

{ "au_id": "274-80-9391", "au_lname": "Straight", "au_fname": "Dean", "phone": "415 834-2919", "address": "5420 College Av.", "city": "Oakland", "state": "CA", "zip": "94609", "contract": true },

{ "au_id": "341-22-1782", "au_lname": "Smith", "au_fname": "Meander", "phone": "913 843-0462", "address": "10 Mississippi Dr.", "city": "Lawrence", "state": "KS", "zip": "66044", "contract": false },

{ "au_id": "409-56-7008", "au_lname": "Bennet", "au_fname": "Abraham", "phone": "415 658-9932", "address": "6223 Bateman St.", "city": "Berkeley", "state": "CA", "zip": "94705", "contract": true },

{ "au_id": "427-17-2319", "au_lname": "Dull", "au_fname": "Ann", "phone": "415 836-7128", "address": "3410 Blonde St.", "city": "Palo Alto", "state": "CA", "zip": "94301", "contract": true },

{ "au_id": "472-27-2349", "au_lname": "Gringlesby", "au_fname": "Burt", "phone": "707 938-6445", "address": "PO Box 792", "city": "Covelo", "state": "CA", "zip": "95428", "contract": true },

{ "au_id": "486-29-1786", "au_lname": "Locksley", "au_fname": "Charlene", "phone": "415 585-4620", "address": "18 Broadway Av.", "city": "San Francisco", "state": "CA", "zip": "94130", "contract": true }

] ,

"itemsCount": 23

}

這個範例程式的執行結果參考如下:

clip_image028

圖 14:取回第一頁作者資料。

建立Index檢視

建立「Index」檢視。將游標停留在「HomeController」控制器程式設計畫面「Index」方法之中,按滑鼠右鍵,從快捷選單選取「Add View」,請參考下圖所示:

clip_image030

圖 15:建立Index檢視。

在「Add View」對話盒中,設定以下項目:

· View name:「Index」。

· Template:「Empty (without model)」。

· 清除勾選所有核取方塊。

然後按下「Add」按鈕,請參考下圖所示:

clip_image032

圖 16:建立Index檢視。

設計Index檢視

在「Index.cshtml」檔案中加入以下程式碼:

@{
  Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name = "viewport" content = "width=device-width" />
    <title> Index </title>
    <link href = "~/Content/jsgrid.min.css" rel = "stylesheet" />
    <link href = "~/Content/jsgrid-theme.min.css" rel = "stylesheet" />
</head>
<body>
    <h2> jsGrid Demo </h2>
    <div style = "margin-left:20px">
        <div id = "jsGrid"></div>
    </div>
    <script src = "~/Scripts/jquery-3.3.1.min.js"> </script>
    <script src = "~/Scripts/jsgrid.min.js"> </script>
    <script src = "~/Scripts/jsgrid-zh-tw.js"> </script>
    <script>
        $(function () {
            jsGrid.locale("zh-tw");
            fillData();
        });

        function fillData() {
            $("#jsGrid").jsGrid({
                width: "100%",
                height: "400px",
                autoload: true,
                sorting: true,
                paging: true,
                pageLoading: true,
                pageSize: 10,
                pageIndex: 1,
                controller: {
                    loadData: function (filter) {
                        var d = $.Deferred();
                        return $.ajax({
                            type: "GET",
                            async: true,
                            url: "/Home/GetData/",
                            data: `pageSize=${filter.pageSize}&pageIndex=${filter.pageIndex}&sortField=${filter.sortField}&sortOrder=${filter.sortOrder}`,
                            dataType: "json",
                            contentType: "application/json; charset=utf-8",
                        }).done(function (response) {
                            d.resolve(response);
                            }).fail(function (e) {
                                console.log("error: " + e.responseText);
                                console.log(e.status);
                            });
                    }
                },

                fields: [
                    { title : "編號", name : "au_id", type : "text", width : 50 },
                    { title : "作者姓氏", name : "au_lname", type : "text", width : 50 },
                    { title : "作者名稱", name : "au_fname", type : "text", width : 50 },
                    { title : "電話號碼", name : "phone", type : "text", width : 50 },
                    { title : "地址", name : "address", type : "text", width : 100 },
                    { title : "城市", name : "city", type : "text", width : 50 }
                ]
            });
        }
    </script>
</body>
</html>

 

這個網頁執行時會利用jQuery送出AJAX請求,叫用伺服端的「/Home/Index」方法從資料庫取回JSON資料,將資料提供給「jsGrid」顯示

最後,選取Visual Studio 開發工具「Build」-「Build Solution」項目編譯目前的專案,確認程式碼能正確編譯。

在Visual Studio開發工具,按CTRL+F5執行網站首頁(請注意:埠號可能會依據實際上的操作而有所不同,請修改為實際的埠號),然後在瀏覽器輸入以下URL:

http://localhost:61267/Home/Index

這個範例程式的執行結果參考如下:

clip_image034

圖 17:整合「jsGrid」網頁。

篩選功能

「jsGrid」預設有支援每個欄位的篩選功能,篩選的動作可以在用戶端執行。這與筆者想要的操作方式不相同,筆者想要從伺服端先根據條件把滿足條件的資料回來。修改「HomeController」類別中「GetData」方法,加入一個「search」參數,可以從資料庫中查詢滿「au_fname」欄位足篩選條件的特定分頁之資料,回傳JSON格式資料供前端使用:

using jsGridDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace jsGridDemo.Controllers {
  public class HomeController : Controller {
    pubsEntities _db = new pubsEntities( );
    // GET: Home
    public ActionResult Index( ) {
      return View( );
    }
    public JsonResult GetData( int pageSize = 10 , string sortOrder = "asc" , string sortField = "au_id" , int pageIndex = 1 , string search = null ) {
      IQueryable<author> authors = _db.authors;

      if ( !string.IsNullOrEmpty( search ) ) {
        authors = authors.Where( a => a.au_fname.ToUpper( ).Contains( search.ToUpper( ) ) );
      }

      switch ( sortField ) {
        case "au_lname":
          authors = ( sortOrder == "asc" ) ? authors.OrderBy( a => a.au_lname ) : authors.OrderByDescending( a => a.au_lname );
          break;
        case "au_fname":
          authors = ( sortOrder == "asc" ) ? authors.OrderBy( a => a.au_fname ) : authors.OrderByDescending( a => a.au_fname );
          break;
        case "phone":
          authors = ( sortOrder == "asc" ) ? authors.OrderBy( a => a.phone ) : authors.OrderByDescending( a => a.phone );
          break;
        case "address":
          authors = ( sortOrder == "asc" ) ? authors.OrderBy( a => a.address ) : authors.OrderByDescending( a => a.address );
          break;
        case "city":
          authors = ( sortOrder == "asc" ) ? authors.OrderBy( a => a.city ) : authors.OrderByDescending( a => a.city );
          break;
        default:
          authors = ( sortOrder == "asc" ) ? authors.OrderBy( a => a.au_id ) : authors.OrderByDescending( a => a.au_id );
          break;
      }

      int itemsCount = authors.Count( );
      int totalPages = (int) Math.Ceiling( (float) itemsCount / (float) pageSize );
      var jsonData = new {
        data = authors.Skip( ( pageIndex - 1 ) * pageSize ).Take( pageSize ).ToList( ) ,
        itemsCount
      };

      return Json( jsonData , JsonRequestBehavior.AllowGet );
    }
  }
}

 

修改「Index」檢視程式碼,加入一個文字方塊讓使用者輸入篩選條件,利用「searchBtn」的「Click」事件送出ajax查詢,並於「data」參數設定篩選條件「&search=${searchStr}」

@{
  Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name = "viewport" content = "width=device-width" />
    <title>Index</title>
    <link href = "~/Content/jsgrid.min.css" rel = "stylesheet" />
    <link href = "~/Content/jsgrid-theme.min.css" rel = "stylesheet" />
</head>
<body>
    <h2> jsGrid Demo </h2>
    作者名稱 : <input type = "text" id = "search" name = "search" />
    <input type = "button" id = "searchBtn" value = "Search" />
    <br />
    <br />
    <div style = "margin-left:20px">
        <div id = "jsGrid"> </div>
    </div>
    <script src = "~/Scripts/jquery-3.3.1.min.js"> </script>
    <script src = "~/Scripts/jsgrid.min.js"> </script>
    <script src = "~/Scripts/jsgrid-zh-tw.js"> </script>
    <script>
        $(function () {
            jsGrid.locale("zh-tw");
            fillData();
            $("#searchBtn").click(function () {
                fillData();
            });
        });

        function fillData() {
            $("#jsGrid").jsGrid({
                width: "100%",
                height: "400px",
                autoload: true,
                sorting: true,
                paging: true,
                pageLoading: true,
                pageSize: 10,
                pageIndex: 1,
                controller: {
                    loadData: function (filter) {
                        var d = $.Deferred();
                        let searchStr = $("#search").val();
                        return $.ajax({
                            type: "GET",
                            async: true,
                            url: "/Home/GetData/",
                            data: `pageSize=${filter.pageSize}&pageIndex=${filter.pageIndex}&sortField=${filter.sortField}&sortOrder=${filter.sortOrder}&search=${searchStr}`,
                            dataType: "json",
                            contentType: "application/json; charset=utf-8",
                        }).done(function (response) {
                            d.resolve(response);
                        }).fail(function (e) {
                            console.log("error: " + e.responseText);
                            console.log(e.status);
                        });
                    }
                },

                fields: [
                    { title: "編號", name: "au_id", type: "text", width: 50 },
                    { title: "作者姓氏", name: "au_lname", type: "text", width: 50 },
                    { title: "作者名稱", name: "au_fname", type: "text", width: 50 },
                    { title: "電話號碼", name: "phone", type: "text", width: 50 },
                    { title: "地址", name: "address", type: "text", width: 100 },
                    { title: "城市", name: "city", type: "text", width: 50 }
                ]
            });
        }
    </script>
</body>
</html>

 

最後,選取Visual Studio 開發工具「Build」-「Build Solution」項目編譯目前的專案,確認程式碼能正確編譯。

在Visual Studio開發工具,按CTRL+F5執行網站首頁(請注意:埠號可能會依據實際上的操作而有所不同,請修改為實際的埠號),然後在瀏覽器輸入以下URL:

http://localhost:61267/Home/Index

這個範例程式的執行結果參考如下:

clip_image036

圖 18:篩選資料。

總結

最後整理「jsGrid」提供功能清單如下:

· 根據欄位進行資料排序、分頁、搜尋、篩選功能。

· 根據特定分頁載入資料。

· 提供多種欄位,包含text、numeric、select、checkbox。

· 支援新增、修改、刪除資料。

· 批次刪除多筆資料。

· 支援新增、修改資料驗證

· 支援多種資料來源,包含OData、REST服務。

· 支援多國語言。

· 使用拖曳排序資料橫列。

· 利用樣版(itemTemplate)客製化欄位顯示。

Tags:

.NET Magazine國際中文電子雜誌 | ASP.NET MVC | JavaScript | 許薰尹Vivid Hsu

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List