MVC5和Jquery Datatables1.10

風靈使發表於2019-01-16

HomeController.cs

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

namespace MVCDatatableApp.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public JsonResult DataHandler(DTParameters param)
        {
            try
            {
                var dtsource = new List<Customer>();
                using (var dc = new dataSetEntities())
                {
                    dtsource = dc.Customers.ToList();
                }

                var columnSearch = new List<string>();

                foreach (var col in param.Columns)
                {
                    columnSearch.Add(col.Search.Value);
                }

                var data = new ResultSet().GetResult(param.Search.Value, param.SortOrder, param.Start, param.Length,dtsource, columnSearch);
                var count = new ResultSet().Count(param.Search.Value, dtsource, columnSearch);
                var result = new DTResult<Customer>
                {
                    draw = param.Draw,
                    data = data,
                    recordsFiltered = count,
                    recordsTotal = count
                };
                return Json(result);
            }
            catch (Exception ex)
            {
                return Json(new {error = ex.Message});
            }
        }
    }
}

DatatablesViewModel.cs

using System.Collections.Generic;

namespace MVCDatatableApp.Models
{
    /// <summary>
    ///   完整的結果,如jQuery DataTables所理解的那樣。
    /// </summary>
    /// <typeparam name="T">每行的資料型別</typeparam>
    public class DTResult<T>
    {
        /// <summary>
        ///該物件是一個響應的draw計數器 - 來自作為資料請求的一部分傳送的draw引數。
        ///請注意,出於安全原因,強烈建議您將此引數轉換為整數,而不是簡單地回顯客戶端在draw引數中傳送的內容,以防止跨站點指令碼(XSS)攻擊。
        /// </summary>
        public int draw { get; set; }

        /// <summary>
        /// 過濾前的總記錄(即資料庫中的記錄總數)
        /// </summary>
        public int recordsTotal { get; set; }

        /// <summary>
        /// 過濾後的總記錄(即應用過濾後的記錄總數 - 不僅僅是為此頁面資料返回的記錄數)。
        /// </summary>
        public int recordsFiltered { get; set; }

        /// <summary>
        ///
        /// 要在表格中顯示的資料。
        /// 這是一個資料來源物件陣列,每行一個,將由DataTables使用。
        /// 請注意,可以使用ajaxDT選項的dataSrc屬性更改此引數的名稱。
        /// </summary>
        public List<T> data { get; set; }
    }

    /// <summary>
    ///  您可以傳送到jQuery DataTables以進行自動處理的其他列。
    /// </summary>
    public abstract class DTRow
    {
        /// <summary>
        ///  將dt-tag tr節點的ID屬性設定為此值
        /// </summary>
        public virtual string DT_RowId
        {
            get { return null; }
        }

        /// <summary>
        /// 將此類新增到dt-tag tr節點
        /// </summary>
        public virtual string DT_RowClass
        {
            get { return null; }
        }

        /// <summary> 
        /// 將此資料屬性新增到行的dt-tag tr節點,允許使用HTML5 data-*屬性將抽象資料新增到節點。
        /// 這使用jQuery  data()方法設定資料,然後也可以將其用於以後的檢索(例如在點選事件上)。
        /// </summary>
        public virtual object DT_RowData
        {
            get { return null; }
        }
    }

    /// <summary>
    /// jQuery DataTables在AJAX查詢中傳送的引數。
    /// </summary>
    public class DTParameters
    {
        /// <summary>
        /// Draw 計數器。
        /// DataTables使用它來確保從伺服器端處理請求返回的Ajax是由DataTables按順序繪製的(Ajax請求是非同步的,因此可以不按順序返回)。
        /// 這用作繪製返回引數的一部分(見下文)。
        /// </summary>
        public int Draw { get; set; }

        /// <summary>
        ///定義表中所有列的陣列
        /// </summary>
        public DTColumn[] Columns { get; set; }

        /// <summary> 
        ///定義排序列數的陣列 - 即,如果陣列長度為1,則執行單列排序,否則執行多列排序。
        /// </summary>
        public DTOrder[] Order { get; set; }

        /// <summary>
        ///分頁第一個記錄指示器。
        ///這是當前資料集的起始點(基於0索引 - 即0是第一個記錄)。
        /// </summary>
        public int Start { get; set; }

        /// <summary> 
        ///表可以在當前draw中顯示的記錄數。
        ///除非伺服器返回的記錄較少,否則預計返回的記錄數將等於此數。 
        ///請注意,這可以為-1表示應返回所有記錄(儘管這會消除伺服器端處理的任何好處!)
        /// </summary>
        public int Length { get; set; }

        /// <summary>
        /// 全域性搜尋值。要應用於所有searchable為true的列。
        /// </summary>
        public DTSearch Search { get; set; }

        /// <summary>
        ///自定義列,用於對第一個Order列進行進一步排序。
        /// </summary>
        public string SortOrder
        {
            get
            {
                return Columns != null && Order != null && Order.Length > 0
                    ? Columns[Order[0].Column].Data +
                      (Order[0].Dir == DTOrderDir.DESC ? " " + Order[0].Dir : string.Empty)
                    : null;
            }
        }
    }

    /// <summary>
    ///   一個jQuery DataTables列
    /// </summary>
    public class DTColumn
    {
        /// <summary>
        ///列的資料來源,由columns.data定義。
        /// </summary>
        public string Data { get; set; }

        /// <summary>
        ///列的名稱,由columns.name定義。
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        ///用於指示此列是否可搜尋(true)或不是(false)的標誌。 這由columns.searchable控制。
        /// </summary>
        public bool Searchable { get; set; }

        /// <summary>
        /// 用於指示此列是否可排序(true)或不是(false)的標誌。 這由columns.orderable控制。
        /// </summary>
        public bool Orderable { get; set; }

        /// <summary>
        ///   具體搜尋值
        /// </summary>
        public DTSearch Search { get; set; }
    }

    /// <summary>
    ///     An order, as sent by jQuery DataTables when doing AJAX queries.
    ///執行AJAX查詢時由jQuery DataTables傳送的排序。
    /// </summary>
    public class DTOrder
    {
        /// <summary>
        ///應該排序的列。
        ///這是對也提交給伺服器的列陣列的索引引用。
        /// </summary>
        public int Column { get; set; }

        /// <summary>
        ///排序此列的方向。
        ///它將是dt-string asc或dt-string desc,分別表示升序或降序。
        /// </summary>
        public DTOrderDir Dir { get; set; }
    }

    /// <summary>
    ///對jQuery DataTables的順序排序
    /// </summary>
    public enum DTOrderDir
    {
        ASC,
        DESC
    }

    /// <summary>
    ///搜尋,由jQuery DataTables在執行AJAX查詢時傳送。
    /// </summary>
    public class DTSearch
    {
        /// <summary>
        ///全域性搜尋值。 要應用於所有可搜尋為true的列。
        /// </summary>
        public string Value { get; set; }

        /// <summary> 
        ///如果全域性過濾器應被視為高階搜尋的正規表示式,則返回true,否則返回false。
        ///請注意,通常伺服器端處理指令碼不會在大型資料集上執行正規表示式搜尋,但在技術上可以並且由您的指令碼自行決定。
        /// </summary>
        public bool Regex { get; set; }
    }
}

ResultSet.cs

using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;
using MVCDatatableApp.Models;

//對於SortBy方法
namespace MVCDatatableApp
{
    public class ResultSet
    {
        public List<Customer> GetResult(string search, string sortOrder, int start, int length, List<Customer> dtResult,
            List<string> columnFilters)
        {
            return FilterResult(search, dtResult, columnFilters).SortBy(sortOrder).Skip(start).Take(length).ToList();
        }

        public int Count(string search, List<Customer> dtResult, List<string> columnFilters)
        {
            return FilterResult(search, dtResult, columnFilters).Count();
        }

        private IQueryable<Customer> FilterResult(string search, List<Customer> dtResult, List<string> columnFilters)
        {
            var results = dtResult.AsQueryable();

            results =
                results.Where(
                    p =>
                        (search == null || p.Name != null && p.Name.ToLower().Contains(search.ToLower()) ||
                         p.City != null && p.City.ToLower().Contains(search.ToLower()) ||
                         p.Postal != null && p.Postal.ToLower().Contains(search.ToLower()) ||
                         p.Email != null && p.Email.ToLower().Contains(search.ToLower()) ||
                         p.Company != null && p.Company.ToLower().Contains(search.ToLower()) ||
                         p.Account != null && p.Account.ToLower().Contains(search.ToLower()) ||
                         p.CreditCard != null && p.CreditCard.ToLower().Contains(search.ToLower()))
                        &&
                        (columnFilters[0] == null ||
                         (p.Name != null && p.Name.ToLower().Contains(columnFilters[0].ToLower())))
                        &&
                        (columnFilters[1] == null ||
                         (p.City != null && p.City.ToLower().Contains(columnFilters[1].ToLower())))
                        &&
                        (columnFilters[2] == null ||
                         (p.Postal != null && p.Postal.ToLower().Contains(columnFilters[2].ToLower())))
                        &&
                        (columnFilters[3] == null ||
                         (p.Email != null && p.Email.ToLower().Contains(columnFilters[3].ToLower())))
                        &&
                        (columnFilters[4] == null ||
                         (p.Company != null && p.Company.ToLower().Contains(columnFilters[4].ToLower())))
                        &&
                        (columnFilters[5] == null ||
                         (p.Account != null && p.Account.ToLower().Contains(columnFilters[5].ToLower())))
                        &&
                        (columnFilters[6] == null ||
                         (p.CreditCard != null && p.CreditCard.ToLower().Contains(columnFilters[6].ToLower())))
                    );

            return results;
        }
    }
}

Index.cshtml

@{
    ViewBag.Title = "Home Page";
}
@model IEnumerable<MVCDatatableApp.Models.Customer>

<!doctype html>
<html>
<head>
    <title>@ViewBag.Title - MVC Datatables App</title>
</head>

<body>
<div class="container">
    <h3>Customer Report</h3>

    <div class="span12">
        <table class="table table-striped" id="datatab">
            <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.City)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Postal)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Email)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Company)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Account)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.CreditCard)
                </th>
            </tr>
            </thead>
            <tbody></tbody>
            <tfoot>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Name)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.City)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Postal)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Email)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Company)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Account)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.CreditCard)
                </th>
            </tr>
            </tfoot>
        </table>
    </div>
</div>
</body>

</html>

_Layout.cshtml

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            @Html.ActionLink("MVC 5 jQuery Datatables 1.10+ App", "Index", "Home", null, new {@class = "navbar-brand"})
        </div>
    </div>
</div>
<div class="container body-content">
    @RenderBody()
    <hr/>
    <footer>
        <p>
            &copy; @DateTime.Now.Year
        </p>
    </footer>
</div>

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", false)
</body>
</html>

index.js

$(document).ready(function() {

    $("#datatab tfoot th").each(function() {
        $(this).html('<input type="text" />');
    });

    var oTable = $("#datatab").DataTable({
           "language": 
           {
            "sProcessing": "處理中...",
            "sLengthMenu": "顯示 _MENU_ 項結果",
            "sZeroRecords": "沒有匹配結果",
            "sInfo": "顯示第 _START_ 至 _END_ 項結果,共 _TOTAL_ 項",
            "sInfoEmpty": "顯示第 0 至 0 項結果,共 0 項",
            "sInfoFiltered": "(由 _MAX_ 項結果過濾)",
            "sInfoPostFix": "",
            "sSearch": "搜尋:",
            "sUrl": "",
            "sEmptyTable": "表中資料為空",
            "sLoadingRecords": "載入中...",
            "sInfoThousands": ",",
            "oPaginate": {
                "sFirst": "首頁",
                "sPrevious": "上頁",
                "sNext": "下頁",
                "sLast": "末頁"
            },
            "oAria": {
                "sSortAscending": ": 以升序排列此列",
                "sSortDescending": ": 以降序排列此列"
            }
        },
        "serverSide": true,
        "ajax": {
            "type": "POST",
            "url": "/Home/DataHandler",
            "contentType": "application/json; charset=utf-8",
            'data': function(data) { return data = JSON.stringify(data); }
        },
        "dom": "frtiS",
        "scrollY": 500,
        "scrollX": true,
        "scrollCollapse": true,
        "scroller": {
            loadingIndicator: false //其中scrollY表示:定義一個高度,當列表內容超過這個高度時,顯示垂直滾動條。
            //scroller表示開啟滾動翻頁。
        },
        "processing": true,
        "paging": true,
        "deferRender": true,
        "columns": [
            { "data": "Name" },
            { "data": "City" },
            { "data": "Postal" },
            { "data": "Email" },
            { "data": "Company" },
            { "data": "Account" },
            { "data": "CreditCard" }
        ],
        "order": [0, "asc"]

    });

    oTable.columns().every(function() {
        var that = this;

        $("input", this.footer()).on("keyup change", function() {
            that.search(this.value).draw();
        });
    });

});

結果

在這裡插入圖片描述

相關文章