Jquery DataTable服务端分页的最佳实现

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Datatable-serverSide 自行封装请求参数和返回数据例子</title>
    <!-- Bootstrap -->
    <link rel="stylesheet" href="asset/lib/bootstrap-2.3.2/css/bootstrap.min.css" media="screen">
    <link rel="stylesheet" href="asset/lib/bootstrap-2.3.2/css/bootstrap-responsive.min.css" media="screen">
    <!-- FontAwesome -->
    <link rel="stylesheet" href="asset/lib/font-awesome-4.2.0/css/font-awesome.min.css">
    <!-- DataTables CSS start-->
    <link rel="stylesheet" href="asset/lib/dataTables-1.10.7/plugins/integration/bootstrap/2/dataTables.bootstrap.css">
    <link rel="stylesheet"
          href="asset/lib/dataTables-1.10.7/plugins/integration/font-awesome/dataTables.fontAwesome.css">
    <!-- DataTables CSS end-->

    <link rel="stylesheet" href="asset/css/user-manage.css">
</head>
<body>
<div class="container-fluid">
    <div class="row-fluid">
        <div class="span12" id="content">
            <div class="row-fluid">
                <div class="navbar" id="breadcrumb">
                    <div class="navbar-inner">
                        <ul class="breadcrumb">
                            <li>
                                <a href="#">首页</a>
                                <span class="divider">/</span>
                            </li>
                            <li class="active">用户管理</li>
                        </ul>
                    </div>
                </div>
            </div>
            <div class="row-fluid">
                <div class="span12">
                    <div class="btn-toolbar">
                        <div class="pull-right">
                            <div class="input-append">
                                <input type="text" placeholder="模糊查询" id="fuzzy-search">
                                <div class="btn-group">
                                    <button type="button" class="btn" id="btn-simple-search"><i
                                            class="fa fa-search"></i></button>
                                    <button type="button" class="btn" title="高级查询" id="toggle-advanced-search">
                                        <i class="fa fa-angle-double-down"></i>
                                    </button>
                                </div>
                            </div>
                        </div>
                        <button type="button" class="btn btn-primary" id="btn-add"><i class="fa fa-plus"></i> 添加
                        </button>
                        <button type="button" class="btn btn-danger" id="btn-del"><i class="fa fa-remove"></i> 批量删除
                        </button>
                    </div>
                </div>
            </div>
            <div class="row-fluid" style="display:none;" id="div-advanced-search">
                <form class="form-inline well">
                    <span>姓名:</span>
                    <input type="text" class="input-medium" placeholder="姓名" id="name-search">
                    <span>职位:</span>
                    <input type="text" class="input-medium" placeholder="职位" id="position-search">
                    <span>工作地点:</span>
                    <input type="text" class="input-medium" placeholder="工作地点" id="office-search">
                    <span>编号:</span>
                    <input type="text" class="input-medium" placeholder="编号" id="extn-search">
                    <span>在线状态:</span>
                    <select class="input-small" id="status-search">
                        <option value="">全部</option>
                        <option value="1">在线</option>
                        <option value="0">离线</option>
                    </select>
                    <select class="input-small" id="role-search">
                        <option value="">全部</option>
                        <option value="1">管理员</option>
                        <option value="0">操作员</option>
                    </select>
                    <button type="button" class="btn" id="btn-advanced-search"><i class="fa fa-search"></i> 查询</button>
                </form>
            </div>
            <div class="block info-block" id="user-view">
                <div class="navbar navbar-inner block-header">
                    <div class="block-title">用户详情</div>
                    <div class="header-buttons">
                        <button type="button" class="btn btn-primary" id="btn-view-edit">修改</button>
                    </div>
                </div>
                <div class="block-content info-content clearfix">
                    <div class="row-fluid">
                        <div class="span4">
                            <label class="prop-name">编号:</label>
                            <div class="prop-value" id="extn-view"></div>
                        </div>
                        <div class="span4">
                            <label class="prop-name">姓名:</label>
                            <div class="prop-value" id="name-view"></div>
                        </div>
                        <div class="span4">
                            <label class="prop-name">角色:</label>
                            <div class="prop-value" id="role-view"></div>
                        </div>
                    </div>
                    <div class="row-fluid">
                        <div class="span4">
                            <label class="prop-name">职位:</label>
                            <div class="prop-value" id="position-view"></div>
                        </div>
                        <div class="span4">
                            <label class="prop-name">薪水:</label>
                            <div class="prop-value" id="salary-view"></div>
                        </div>
                        <div class="span4">
                            <label class="prop-name">状态:</label>
                            <div class="prop-value" id="status-view"></div>
                        </div>
                    </div>
                    <div class="row-fluid">
                        <div class="span4">
                            <label class="prop-name">入职时间:</label>
                            <div class="prop-value" id="start-date-view"></div>
                        </div>
                        <div class="span8">
                            <label class="prop-name">办公地点:</label>
                            <div class="prop-value" id="office-view"></div>
                        </div>
                    </div>
                    <div class="row-fluid">
                        <div class="span12">
                            <label class="prop-name">备注:</label>
                            <div class="prop-value"></div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="block info-block" id="user-add" style="display:none;">
                <div class="navbar navbar-inner block-header">
                    <div class="block-title">添加账户</div>
                    <div class="header-buttons">
                        <button type="button" class="btn btn-primary" id="btn-save-add">确定添加</button>
                        <button type="button" class="btn btn-cancel">取消</button>
                    </div>
                </div>
                <div class="block-content info-content clearfix">
                    <form id="form-add">
                        <div class="control-group">
                            <label class="control-label" for="extn-add"><span
                                    class="red-asterisk">*</span>编号:</label>
                            <div class="controls">
                                <input type="text" id="extn-add" name="extn-add">
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="name-add"><span
                                    class="red-asterisk">*</span>姓名:</label>
                            <div class="controls">
                                <input type="text" id="name-add" name="name-add">
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="role-add">角色:</label>
                            <div class="controls">
                                <select id="role-add" name="role-add">
                                    <option value="1" selected>管理员</option>
                                    <option value="0">操作员</option>
                                </select>
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="position-add">职位:</label>
                            <div class="controls">
                                <input type="text" id="position-add" name="position-add">
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="salary-add">薪水:</label>
                            <div class="controls">
                                <input type="text" id="salary-add" name="salary-add">
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="start-date-add">入职时间:</label>
                            <div class="controls">
                                <input type="text" id="start-date-add" name="start-date-add">
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="office-add">办公地点:</label>
                            <div class="controls">
                                <input type="text" class="xlarge" id="office-add" name="office-add">
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="remark-add">备注:</label>
                            <div class="controls">
                                <input type="text" class="xxxlarge" id="remark-add" name="remark-add">
                            </div>
                        </div>
                    </form>
                </div>
            </div>
            <div class="block info-block" id="user-edit" style="display:none;">
                <div class="navbar navbar-inner block-header">
                    <div class="block-title">修改账户:<span id="title-edit"></span></div>
                    <div class="header-buttons">
                        <button type="button" class="btn btn-primary" id="btn-save-edit">保存更改</button>
                        <button type="button" class="btn btn-cancel">取消</button>
                    </div>
                </div>
                <div class="block-content info-content clearfix">
                    <form id="form-edit">
                        <div class="control-group">
                            <label class="control-label" for="extn-edit"><span
                                    class="red-asterisk">*</span>编号:</label>
                            <div class="controls">
                                <input type="text" id="extn-edit" name="extn-edit">
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="name-edit"><span
                                    class="red-asterisk">*</span>姓名:</label>
                            <div class="controls">
                                <input type="text" id="name-edit" name="name-edit">
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="role-edit">角色:</label>
                            <div class="controls">
                                <select id="role-edit" name="role-edit">
                                    <option value="1" selected>管理员</option>
                                    <option value="0">操作员</option>
                                </select>
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="position-edit">职位:</label>
                            <div class="controls">
                                <input type="text" id="position-edit" name="position-edit">
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="salary-edit">薪水:</label>
                            <div class="controls">
                                <input type="text" id="salary-edit" name="salary-edit">
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="start-date-edit">入职时间:</label>
                            <div class="controls">
                                <input type="text" id="start-date-edit" name="start-date-edit">
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="office-edit">办公地点:</label>
                            <div class="controls">
                                <input type="text" class="xlarge" id="office-edit" name="office-edit">
                            </div>
                        </div>
                        <div class="control-group">
                            <label class="control-label" for="remark-edit">备注:</label>
                            <div class="controls">
                                <input type="text" class="xxxlarge" id="remark-edit" name="remark-edit">
                            </div>
                        </div>
                    </form>
                </div>
            </div>
            <div class="row-fluid">
                <div class="span12" id="div-table-container">
                    <table class="table table-striped table-bordered table-hover table-condensed" id="table-user"
                           cellspacing="0" width="100%">
                        <thead>
                        <tr>
                            <th>
                                <input type="checkbox" name="cb-check-all">
                            </th>
                            <th>姓名</th>
                            <th>职位</th>
                            <th>状态</th>
                            <th>入职时间</th>
                            <th>操作</th>
                        </tr>
                        </thead>
                        <tbody>
                        </tbody>
                        <tfoot>
                        <tr>
                            <th>
                                <input type="checkbox" name="cb-check-all">
                            </th>
                            <th>姓名</th>
                            <th>职位</th>
                            <th>状态</th>
                            <th>入职时间</th>
                            <th>操作</th>
                        </tr>
                        </tfoot>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
<script src="asset/lib/json2.js"></script>
<!-- JQuery -->
<script src="asset/lib/jquery-1.11.3.min.js"></script>
<!-- Bootstrap -->
<script src="asset/lib/bootstrap-2.3.2/js/bootstrap.min.js"></script>
<!-- SpinJS-->
<script src="asset/lib/spin-2.1.0/jquery.spin.merge.js"></script>
<!-- lhgdialog -->
<script src="asset/lib/lhgdialog-4.2.0/lhgdialog.js?skin=bootstrap2"></script>
<!-- DataTables JS-->
<script src="asset/lib/dataTables-1.10.7/media/js/jquery.dataTables.js"></script>
<script src="asset/lib/dataTables-1.10.7/plugins/integration/bootstrap/2/dataTables.bootstrap.js"></script>
<!-- DataTables JS end-->
<script src="asset/js/constant.js"></script>
<script src="asset/js/user-manage.js"></script>
</body>
</html>
constant.js
/*常量*/
var CONSTANT = {
    DATA_TABLES: {
        DEFAULT_OPTION: { //DataTables初始化选项
            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": "末页",
                    "sJump": "跳转"
                },
                "oAria": {
                    "sSortAscending": ": 以升序排列此列",
                    "sSortDescending": ": 以降序排列此列"
                }
            },
            autoWidth: false,	//禁用自动调整列宽
            stripeClasses: ["odd", "even"],//为奇偶行加上样式,兼容不支持CSS伪类的场合
            order: [],			//取消默认排序查询,否则复选框一列会出现小箭头
            processing: false,	//隐藏加载提示,自行处理
            serverSide: true,	//启用服务器端分页
            searching: false	//禁用原生搜索
        },
        COLUMN: {
            CHECKBOX: {	//复选框单元格
                className: "td-checkbox",
                orderable: false,
                width: "30px",
                data: null,
                render: function (data, type, row, meta) {
                    return '<input type="checkbox" class="iCheck">';
                }
            }
        },
        RENDER: {	//常用render可以抽取出来,如日期时间、头像等
            ELLIPSIS: function (data, type, row, meta) {
                data = data || "";
                return '<span title="' + data + '">' + data + '</span>';
            }
        }
    }
};

userManage.js
$(function () {
    var $wrapper = $('#div-table-container');
    var $table = $('#table-user');

    var _table = $table.dataTable($.extend(true, {}, CONSTANT.DATA_TABLES.DEFAULT_OPTION, {
        ajax: function (data, callback, settings) {//ajax配置为function,手动调用异步查询
            //手动控制遮罩
            $wrapper.spinModal();
            //封装请求参数
            var param = userManage.getQueryCondition(data);
            $.ajax({
                type: "GET",
                url: "datasource.php",
                cache: false,	//禁用缓存
                data: param,	//传入已封装的参数
                dataType: "json",
                success: function (result) {
                    //setTimeout仅为测试遮罩效果
                    setTimeout(function () {
                        //异常判断与处理
                        if (result.errorCode) {
                            $.dialog.alert("查询失败。错误码:" + result.errorCode);
                            return;
                        }

                        //封装返回数据,这里仅演示了修改属性名
                        var returnData = {};
                        returnData.draw = data.draw;//这里直接自行返回了draw计数器,应该由后台返回
                        returnData.recordsTotal = result.total;
                        returnData.recordsFiltered = result.total;//后台不实现过滤功能,每次查询均视作全部结果
                        returnData.data = result.pageData;
                        //关闭遮罩
                        $wrapper.spinModal(false);
                        //调用DataTables提供的callback方法,代表数据已封装完成并传回DataTables进行渲染
                        //此时的数据需确保正确无误,异常判断应在执行此回调前自行处理完毕
                        callback(returnData);
                    }, 200);
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    $.dialog.alert("查询失败");
                    $wrapper.spinModal(false);
                }
            });
        },
        columns: [
            CONSTANT.DATA_TABLES.COLUMN.CHECKBOX,
            {
                className: "ellipsis",	//文字过长时用省略号显示,CSS实现
                data: "name",
                render: CONSTANT.DATA_TABLES.RENDER.ELLIPSIS,//会显示省略号的列,需要用title属性实现划过时显示全部文本的效果
            },
            {
                className: "ellipsis",
                data: "position",
                render: CONSTANT.DATA_TABLES.RENDER.ELLIPSIS,
                //固定列宽,但至少留下一个活动列不要固定宽度,让表格自行调整。不要将所有列都指定列宽,否则页面伸缩时所有列都会随之按比例伸缩。
                //切记设置table样式为table-layout:fixed; 否则列宽不会强制为指定宽度,也不会出现省略号。
                width: "80px"
            },
            {
                data: "status",
                width: "80px",
                render: function (data, type, row, meta) {
                    return '<i class="fa fa-male"></i> ' + (data ? "在线" : "离线");
                }
            },
            {
                data: "start_date",
                width: "80px"
            },
            {
                className: "td-operation",
                data: null,
                defaultContent: "",
                orderable: false,
                width: "120px"
            }
        ],
        "createdRow": function (row, data, index) {
            //行渲染回调,在这里可以对该行dom元素进行任何操作
            //给当前行加样式
            if (data.role) {
                $(row).addClass("info");
            }
            //给当前行某列加样式
            $('td', row).eq(3).addClass(data.status ? "text-success" : "text-error");
            //不使用render,改用jquery文档操作呈现单元格
            var $btnEdit = $('<button type="button" class="btn btn-small btn-primary btn-edit">修改</button>');
            var $btnDel = $('<button type="button" class="btn btn-small btn-danger btn-del">删除</button>');
            $('td', row).eq(5).append($btnEdit).append($btnDel);

        },
        "drawCallback": function (settings) {
            //渲染完毕后的回调
            //清空全选状态
            $(":checkbox[name='cb-check-all']", $wrapper).prop('checked', false);
            //默认选中第一行
            $("tbody tr", $table).eq(0).click();
        }
    })).api();//此处需调用api()方法,否则返回的是JQuery对象而不是DataTables的API对象

    $("#btn-add").click(function () {
        userManage.addItemInit();
    });

    $("#btn-del").click(function () {
        var arrItemId = [];
        $("tbody :checkbox:checked", $table).each(function (i) {
            var item = _table.row($(this).closest('tr')).data();
            arrItemId.push(item);
        });
        userManage.deleteItem(arrItemId);
    });

    $("#btn-simple-search").click(function () {
        userManage.fuzzySearch = true;

        //reload效果与draw(true)或者draw()类似,draw(false)则可在获取新数据的同时停留在当前页码,可自行试验
//		_table.ajax.reload();
//		_table.draw(false);
        _table.draw();
    });

    $("#btn-advanced-search").click(function () {
        userManage.fuzzySearch = false;
        _table.draw();
    });

    $("#btn-save-add").click(function () {
        userManage.addItemSubmit();
    });

    $("#btn-save-edit").click(function () {
        userManage.editItemSubmit();
    });

    //行点击事件
    $("tbody", $table).on("click", "tr", function (event) {
        $(this).addClass("active").siblings().removeClass("active");
        //获取该行对应的数据
        var item = _table.row($(this).closest('tr')).data();
        userManage.currentItem = item;
        userManage.showItemDetail(item);
    });

    $table.on("change", ":checkbox", function () {
        if ($(this).is("[name='cb-check-all']")) {
            //全选
            $(":checkbox", $table).prop("checked", $(this).prop("checked"));
        } else {
            //一般复选
            var checkbox = $("tbody :checkbox", $table);
            $(":checkbox[name='cb-check-all']", $table).prop('checked', checkbox.length == checkbox.filter(':checked').length);
        }
    }).on("click", ".td-checkbox", function (event) {
        //点击单元格即点击复选框
        !$(event.target).is(":checkbox") && $(":checkbox", this).trigger("click");
    }).on("click", ".btn-edit", function () {
        //点击编辑按钮
        var item = _table.row($(this).closest('tr')).data();
        $(this).closest('tr').addClass("active").siblings().removeClass("active");
        userManage.currentItem = item;
        userManage.editItemInit(item);
    }).on("click", ".btn-del", function () {
        //点击删除按钮
        var item = _table.row($(this).closest('tr')).data();
        $(this).closest('tr').addClass("active").siblings().removeClass("active");
        userManage.deleteItem([item]);
    });

    $("#toggle-advanced-search").click(function () {
        $("i", this).toggleClass("fa-angle-double-down fa-angle-double-up");
        $("#div-advanced-search").slideToggle("fast");
    });

    $("#btn-info-content-collapse").click(function () {
        $("i", this).toggleClass("fa-minus fa-plus");
        $("span", this).toggle();
        $("#user-view .info-content").slideToggle("fast");
    });

    $("#btn-view-edit").click(function () {
        userManage.editItemInit(userManage.currentItem);
    });

    $(".btn-cancel").click(function () {
        userManage.showItemDetail(userManage.currentItem);
    });
});

var userManage = {
    currentItem: null,
    fuzzySearch: true,
    getQueryCondition: function (data) {
        var param = {};
        //组装排序参数
        if (data.order && data.order.length && data.order[0]) {
            switch (data.order[0].column) {
                case 1:
                    param.orderColumn = "name";
                    break;
                case 2:
                    param.orderColumn = "position";
                    break;
                case 3:
                    param.orderColumn = "status";
                    break;
                case 4:
                    param.orderColumn = "start_date";
                    break;
                default:
                    param.orderColumn = "name";
                    break;
            }
            param.orderDir = data.order[0].dir;
        }
        //组装查询参数
        param.fuzzySearch = userManage.fuzzySearch;
        if (userManage.fuzzySearch) {
            param.fuzzy = $("#fuzzy-search").val();
        } else {
            param.name = $("#name-search").val();
            param.position = $("#position-search").val();
            param.office = $("#office-search").val();
            param.extn = $("#extn-search").val();
            param.status = $("#status-search").val();
            param.role = $("#role-search").val();
        }
        //组装分页参数
        param.startIndex = data.start;
        param.pageSize = data.length;

        param.draw = data.draw;

        return param;
    },
    showItemDetail: function (item) {
        $("#user-view").show().siblings(".info-block").hide();
        if (!item) {
            $("#user-view .prop-value").text("");
            return;
        }
        $("#name-view").text(item.name);
        $("#position-view").text(item.position);
        $("#salary-view").text(item.salary);
        $("#start-date-view").text(item.start_date);
        $("#office-view").text(item.office);
        $("#extn-view").text(item.extn);
        $("#role-view").text(item.role ? "管理员" : "操作员");
        $("#status-view").text(item.status ? "在线" : "离线");
    },
    addItemInit: function () {
        $("#form-add")[0].reset();

        $("#user-add").show().siblings(".info-block").hide();
    },
    editItemInit: function (item) {
        if (!item) {
            return;
        }
        $("#form-edit")[0].reset();
        $("#title-edit").text(item.name);
        $("#name-edit").val(item.name);
        $("#position-edit").val(item.position);
        $("#salary-edit").val(item.salary);
        $("#start-date-edit").val(item.start_date);
        $("#office-edit").val(item.office);
        $("#extn-edit").val(item.extn);
        $("#role-edit").val(item.role);
        $("#user-edit").show().siblings(".info-block").hide();
    },
    addItemSubmit: function () {
        $.dialog.tips('保存当前添加用户');
    },
    editItemSubmit: function () {
        $.dialog.tips('保存当前编辑用户');
    },
    deleteItem: function (selectedItems) {
        var message;
        if (selectedItems && selectedItems.length) {
            if (selectedItems.length == 1) {
                message = "确定要删除 '" + selectedItems[0].name + "' 吗?";

            } else {
                message = "确定要删除选中的" + selectedItems.length + "项记录吗?";
            }
            $.dialog.confirmDanger(message, function () {
                $.dialog.tips('执行删除操作');
            });
        } else {
            $.dialog.tips('请先选中要操作的行');
        }
    }
};

转载于:https://my.oschina.net/xjt2014/blog/758126

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值