Bootstrap DataTables 服务端分页

在项目开发中,偶尔会遇到查询数据过大,超出JSON能够容纳的最大长度,Bootstrap DataTables就无法实现数据加载。此时就需要实现服务器分页功能。不想付费去购买.NET版的,就只有自己手动去完成了。
本篇是在上一篇代码基础上进行修改达到服务器分页效果。

1 结构分析

请求参数说明,做了一个简单的翻译

Parameter name Type Description
draw integer Datatables中拉取服务端数据次数
start integer 请求数据的开始行数
length integer 本次请求数据的多少行数
search[value] string 全局搜索值
search[regex] boolean 默认‘false’,正则表达式搜索
order[i][column] integer 排序的Column行号
order[i][dir] string 排序的Column字典集
columns[i][data] string 对应Column 第i个的Data,及在指定数据时的赋值字段
columns[i][name] string 对应 i 行的Column第i个的名称
columns[i][searchable] boolean 设置Column是否可搜索,
columns[i][orderable] boolean 是否可以排序
columns[i][search][value] string 搜索内容
columns[i][search][regex] boolean 是否正则表达式搜索

响应数据

Parameter name Type Description
draw integer Datatables中拉取服务端数据次数,说是防止XSS攻击
recordsTotal integer 未做删选前的返回总行数
recordsFiltered integer) 删选之后的总行数
data array 返回的data
error string 异常原因
Parameter name Type Description
DT_RowId string tr 的ID
DT_RowClass string tr 的 class
DT_RowData object 设置一个Data 集合,方便js事件时使用
DT_RowAttr object tr新增一个attributes

另外几个参数,可以加载到 tr Tag

Parameter name Type Description
DT_RowId string tr 的ID
DT_RowClass string tr 的 class
DT_RowData object 设置一个Data 集合,方便js事件时使用
DT_RowAttr object tr新增一个attributes

2 前端修改

根据上面的参数,前端需要修改的地方很少,就是在调用插件时新增一个参数 serverSide: true,其他需要的属性看情况使用

    function ShowTables(type) {
        var actionurl;
            actionurl = '@Url.Action("GetEmployeeAuthList", "Employee")';
        $('#example tbody').off('click');
        $('#example').DataTable().destroy();
        var dt = $('#example').DataTable({
            ajax: {
                type: 'post',
                url: actionurl,
                dataSrc: 'data',
                data: {
                    Site: $('#Site').val(),
                    Emplid: $('#Emplid').val(),
                    Chinam: $('#Chinam').val(),
                    Neweid: $('#Neweid').val(),
                    Depcod: $('#Depcod').val(),
                    DoorGroupID: $('#uDoorGroupID').val(),
                },
                error: function (xhr, status, error) {
                alert(xhr);
                }
            },
            columns: [
                {"data": "Site", "name":"公司别",searchable: false },
                { "data": "Emplid", "name": "工号" },
                { "data": "Chinam" ,"name":"姓名" },
                { "data": "Neweid", "name": "卡号" },
                { "data": "Depcod", "name": "Cost Center" },
                { "data": "DoorGroupName", "name": "权限" },
                { "data": "Status", "name":"状态",searchable: false },
                {
                    data: null,
                    className: "center",
                    render: function (data, type, row) {
                        return '<a href=""   id="' + data.Neweid + '"  class="fa fa-fw fa-lg fa-edit editor_edit"></a>';
                    }
                }
            ],
            select: true,
            serverSide: true,//支持服务端分页
            processing: true
        });
//添加行click事件
$('#example tbody').on('click', 'tr', function () {
                dt.$('tr.selected').removeClass('selected');
                $('#btnArea').attr('disabled', false);
                var rowData = dt.rows(this).data()[0].DT_RowData; //获取后台指定的DT_RowData数据
                alert(rowData.Emplid);
                //var doorGroupId = $(this).attr('id').split('_')[1];
                //var carid = $(this).attr('id').split('_')[2];
            }
        });
}

3 请求参数处理

需要对请求参数进行解析,实现请求参数的实体类

    public class DataTableParms
    {
        public string draw { get; set; }
        public List<DataTableColumns> columns { get; set; } 
        public DataTableOrder order { get; set; }
        public string start { get; set; }
        public string length { get; set; }
        public DataTableSearch search { get; set; }
    }

    public class DataTableColumns
    {
        public string data { get; set; }
        public string name { get; set; }
        public string searchable { get; set; }
        public string orderable { get; set; }
        //public DataTableSearch search { get; set; }
    }

    public class DataTableSearch
    {
        public string  value { get; set; }
        public string regex { get; set; }
    }

    public class DataTableOrder
    {
        public string  column { get; set; }
        public string dir { get; set; }
    }

解析方法类,采用正则表达式和反射,取出HTTP中的数据进行解析

 public class BootStrapDataTable
    {
        public DataTableParms DeserializePostParms(HttpContextBase content)
        {
            DataTableParms dtParms = new DataTableParms();
            List<DataTableColumns> dtcList= new List<DataTableColumns>();
            DataTableSearch dtSearch = new DataTableSearch();
            DataTableOrder  dtOrder= new DataTableOrder();
            try
            {
                var request = HttpUtility.UrlDecode(content.Request.Form.ToString());
                if (!string.IsNullOrEmpty(request))
                {
                    foreach (var Properties in dtParms.GetType().GetProperties())
                    {
                        if (Properties.Name.Contains("columns"))
                        {
                            Regex indexRegex = new Regex(@"(?:^|/?|&)columns\[\d\]\[data\]=([^&]*)(?:&|$)");
                            var indexMatch = indexRegex.Matches(request.ToString());
                            int index = indexMatch.Count;

                            for (int i = 0; i < index; i++)
                            {
                                Regex columnsRegex =
                                    new Regex(string.Format(@"(?:^|/?|&)columns\[{0}\](\[([a-z]*)\])=([^&]*)(?:&|$)", i));
                                MatchCollection columnsMatch = columnsRegex.Matches(request.ToString());
                                DataTableColumns dtColumns = new DataTableColumns();

                                foreach (Match item in columnsMatch)
                                {
                                    if (item.Success)
                                    {
                                        if (item.Groups.Count == 4)
                                        {
                                            var objTemp = dtColumns.GetType()
                                                .GetProperties()
                                                .FirstOrDefault(w => w.Name.Contains(item.Groups[2].Value));
                                            if (objTemp != null)
                                            {
                                                objTemp.SetValue(dtColumns, item.Groups[3].Value);
                                            }
                                        }
                                    }
                                }
                                dtcList.Add(dtColumns);
                            }
                            continue;
                        }
                        if (Properties.Name.Contains("order"))
                        {
                            Regex orderRegex =
                                new Regex(string.Format(@"(?:^|/?|&)order\[0\]\[([a-z]*)\]=([^&]*)(?:&|$)"));
                            MatchCollection orderMatch = orderRegex.Matches(request.ToString());
                            foreach (Match item in orderMatch)
                            {
                                if (item.Success)
                                {
                                    var objTemp = dtOrder.GetType()
                                        .GetProperties()
                                        .FirstOrDefault(w => w.Name.Contains(item.Groups[1].Value));
                                    if (objTemp != null)
                                    {
                                        objTemp.SetValue(dtOrder, item.Groups[2].Value);
                                    }
                                }
                            }
                            continue;
                        }
                        if (Properties.Name.Contains("search"))
                        {
                            Regex orderRegex =
                                new Regex(string.Format(@"(?:^|/?|&)search\[([a-z]*)\]=([^&]*)(?:&|$)"));
                            MatchCollection orderMatch = orderRegex.Matches(request.ToString());
                            foreach (Match item in orderMatch)
                            {
                                if (item.Success)
                                {
                                    var objTemp = dtSearch.GetType()
                                        .GetProperties()
                                        .FirstOrDefault(w => w.Name.Contains(item.Groups[1].Value));
                                    if (objTemp != null)
                                    {
                                        objTemp.SetValue(dtSearch, item.Groups[2].Value);
                                    }
                                }
                            }
                            continue;
                        }

                        Regex urlRegex = new Regex(string.Format(@"(?:^|/?|&){0}=([^&]*)(?:&|$)", Properties.Name));
                        Match m = urlRegex.Match(request.ToString());
                        if (m.Success)
                        {
                            var objTemp = dtParms.GetType()
                                .GetProperties()
                                .FirstOrDefault(w => w.Name.Contains(Properties.Name));
                            if (objTemp != null)
                            {
                                objTemp.SetValue(dtParms, m.Groups[1].Value);
                            }
                        }
                    }
                }

                dtParms.columns = dtcList;
                dtParms.search = dtSearch;
                dtParms.order = dtOrder;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return dtParms;
        }
    }

4 服务端响应Data

新增一个基类 BaseDataTables

    public class BaseDataTables
    {
        public int draw { get; set; }//
        public int recordsTotal { get; set; }//行数
        public int recordsFiltered { get; set; } 
    }

在TEmployeeAuthList类中继承BaseDataTables

 public class TEmployeeAuthList:BaseDataTables
    {
        public List<TEmployeeAuth> data { get; set; }  
    }

修改TEmployeeAuth.cs 添加DT_RowId ,DT_RowData,需要看具体情况去实现DT_RowData

 public class TEmployeeAuth
    {
        public string DT_RowId { get { return Emplid.ToString() + "_" + DoorGroupID.ToString() + "_" + Neweid.ToString(); } }
        public TEmployeeAuth_RowData DT_RowData { get { return  new TEmployeeAuth_RowData()
        {
            DoorGroupID =this.DoorGroupID,
            Emplid = this.Emplid,
            Neweid = this.Neweid
        };} }
        public string Site { get; set; }
        public string Emplid { get; set; }
        public string Chinam { get; set; }
        public string Neweid { get; set; }
        public string Depcod { get; set; }
        public string DoorGroupID { get; set; }
        public string Status { get; set; }
        public string  DoorGroupName { get; set; }
    }

    public class TEmployeeAuth_RowData
    {
        public string Emplid { get; set; }
        public string DoorGroupID { get; set; }
        public string Neweid { get; set; }
    }

最后controller 中实现响应Action

        public JsonResult GetEmployeeAuthList(string Site, string Emplid, string Chinam, string NeweId, string Depcod, string DoorGroupID, int start, int length)
        {
          //解析参数
           DataTableParms dtParms= new DataTableParms();
            BootStrapDataTable objbd= new BootStrapDataTable();
            dtParms = objbd.DeserializePostParms(HttpContext);
            //声明返回值
            TEmployeeAuthList result= new TEmployeeAuthList();
            EmployeeBasic employee= new EmployeeBasic();
            ......略......
            return Json(result);
        }

以上就是自己实现的服务端分页功能,下一篇记一下自己实现 Bootstrap DataTables的 编辑 功能

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,837评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,551评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,417评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,448评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,524评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,554评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,569评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,316评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,766评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,077评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,240评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,912评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,560评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,176评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,425评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,114评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,114评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,647评论 18 139
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,747评论 1 92
  • 前不久假期回家,第一次见我妈对我歇斯底里。在我印象里,我妈从来都是温柔贤惠,善解人意,说难听点有点忍辱负重的那么一...
    深侯阅读 763评论 0 0
  • 再长的路,一步步也能走完,再短的路,不迈开双脚也无法到达。 人最可悲的是,有自由的思想,却没有冲破羁绊的勇气。 人...
    胜者为王王臣森阅读 246评论 0 0
  • 今天和一个新升一级还有一个新升总代聊天! 我问了同样一个问题,这么多学历,经历,阅历,人脉,资源都不如你的可以做成...
    谢丽姝阅读 334评论 1 0