最近做的项目是完全前后端分离的,后端小哥提供数据和接口,我负责写html和js,使用了adminLTE这个模板,不想用这个的可以自己把控件手动添加上去。 本文主要记录了对datatable的行进行数据填充、增、删、改这四项功能。 四个url,分别是:
{homePath}/continents //获取 所有大洲 方法 get
{homePath}/addContinent //添加 大洲 方法 post ,参数 name="大洲英文名",chineseName='大洲中文名'
{homePath}/editContinent //编辑大洲 方法 post,参数 id="大洲id", name="大洲英文名",chineseName='大洲中文名'
{homePath}/delContinent // 删除大洲 方法 post,参数 id="大洲id"
效果图:
html:
<!DOCTYPE HTML >
<html lang="zh-CN">
<head>
<title>datatable示例</title>
<meta http-equiv="content-type" content="text/html" charset="UTF-8"/>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"/>
<link rel="stylesheet" href="res/lib/adminLTE/bootstrap/css/bootstrap.min.css"/>
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css"/>
<!-- Ionicons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css"/>
<script type="text/javascript" src="res/lib/adminLTE/plugins/jQuery/jquery-2.2.3.min.js"></script>
<!-- Bootstrap 3.3.6 -->
<script type="text/javascript" src="res/lib/adminLTE/bootstrap/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css"
href="res/lib/adminLTE/plugins/datatables/media/css/dataTables.bootstrap.min.css"/>
<link rel="stylesheet" type="text/css"
href="res/lib/adminLTE/plugins/datatables/extensions/FixedColumns/css/fixedColumns.bootstrap.min.css"/>
<link rel="stylesheet" type="text/css"
href="res/lib/adminLTE/plugins/datatables/extensions/ColReorder/css/colReorder.bootstrap.min.css"/>
<link rel="stylesheet" type="text/css"
href="res/lib/adminLTE/plugins/datatables/extensions/Select/css/select.bootstrap.min.css"/>
<link rel="stylesheet" type="text/css"
href="res/lib/adminLTE/plugins/datatables/extensions/Buttons/css/buttons.bootstrap.min.css"/>
<link rel="stylesheet" type="text/css"
href="res/lib/adminLTE/plugins/datetimepicker/bootstrap-datetimepicker.min.css"/>
<script type="text/javascript"
src="res/lib/adminLTE/plugins/datatables/media/js/jquery.dataTables.min.js"
></script>
<script type="text/javascript"
src="res/lib/adminLTE/plugins/datatables/media/js/dataTables.bootstrap.min.js"></script>
<script type="text/javascript"
src="res/lib/adminLTE/plugins/datatables/extensions/FixedColumns/js/dataTables.fixedColumns.min.js"></script>
<script type="text/javascript"
src="res/lib/adminLTE/plugins/datatables/extensions/ColReorder/js/dataTables.colReorder.min.js"></script>
<script type="text/javascript"
src="res/lib/adminLTE/plugins/datatables/extensions/Select/js/dataTables.select.min.js"></script>
<script type="text/javascript"
src="res/lib/adminLTE/plugins/datatables/extensions/Buttons/js/buttons.html5.min.js"></script>
<script type="text/javascript"
src="res/lib/adminLTE/plugins/datatables/extensions/Buttons/js/dataTables.buttons.min.js"></script>
<script type="text/javascript"
src="res/lib/adminLTE/plugins/datatables/extensions/Buttons/js/buttons.bootstrap.min.js"></script>
<script type="text/javascript"
src="res/lib/ourjs/jquery.bootstrap.min.js"></script>
<script type="text/javascript"
src="res/lib/adminLTE/plugins/slimScroll/jquery.slimscroll.min.js"></script>
<script type="text/javascript"
src="res/lib/adminLTE/plugins/fastclick/fastclick.min.js"></script>
<script type="text/javascript" src="res/lib/jquery.validate.min.js"></script>
<script type="text/javascript" src="res/js/res/continent.js"></script>
</head>
<body class="hold-transition skin-blue sidebar-mini sidebar-collapse">
<div class="wrapper">
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<!-- Main content -->
<section class="content">
<!-- 被装饰页面(如:主页)-->
<div class="box box-primary tableBox hidden">
<div class="box-header">
<h3 class="box-title">大洲 管理</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
</button>
</div>
</div>
<!-- /.box-header -->
<div class="box-body">
<table id="continentManageTable" class="table table-bordered table-hover" width="100%"
>
<thead>
<tr>
<th class="text-center text-nowrap">序号</th>
<th class="text-center text-nowrap">英文名</th>
<th class="text-center text-nowrap">中文名</th>
<th class="text-center text-nowrap">创建时间</th>
<th class="text-center text-nowrap">修改时间</th>
<th class="text-center text-nowrap"> 状态 </th>
</tr>
</thead>
<tbody></tbody>
<tfoot>
<tr>
<th class="text-center text-nowrap">序号</th>
<th class="text-center text-nowrap">英文名</th>
<th class="text-center text-nowrap">中文名</th>
<th class="text-center text-nowrap">创建时间</th>
<th class="text-center text-nowrap">修改时间</th>
<th class="text-center text-nowrap"> 状态 </th>
</tr>
</tfoot>
</table>
</div><!-- /.box-body -->
</div><!-- /.box -->
<div class="modal fade" id="continentManageEditDialog" role="dialog" aria-labelledby="编辑对话框">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">×</span></button>
<h4 class="modal-title" id="continentManageEditDialogTitle"></h4>
</div>
<div class="modal-body">
<form id="continentManageEditorForm">
<div class="form-group name">
<label for="nameEditor">英文名</label>
<font color="red" class="requiredStar">*</font>
<input id="nameEditor" type="text" name="name" class="form-control editor"
data-toggle="popover" data-placement="top"
data-content="请输入英文名"
/>
</div>
<div class="form-group chineseName">
<label for="chineseNaneEditor">中文名</label>
<font color="red" class="requiredStar">*</font>
<input id="chineseNameEditor" type="text" name="chineseName" class="form-control editor"
data-toggle="popover" data-placement="top"
data-content="请输入中文名"
/>
</div>
</form>
</div>
<div class="modal-footer">
<button id="editorFormCancel" type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button id="editorFormSubmit" type="button" class="btn btn-primary" form="continentManageEditorForm">保存
</button>
</div>
</div>
</div>
</div>
</section>
<!-- /.content -->
</div>
<!-- /.content-wrapper -->
</div>
<!-- ./wrapper -->
</body>
</html>
js:
function Params() {
//this.content = "json";
//这里的params一般用于上传数据,若需要,可以带上一些默认的属性
}
window.addEventListener("load", function () {
continentManageTableBox.init();//初始化表格
});
const continentManageTableBox = {
_url_: null,
_tableBox_: null,
_params_: null,
_overlayDiv_: null,
_draw_: 0,
_dataTable_: null,
_language_: {
processing: "萌萌加载中",
emptyTable: "没有搜索到符合的结果",
zeroRecord: "没有匹配的结果",
paginate: {
first: "首页",
last: "尾页",
previous: "上一页",
next: "下一页"
},
select: {
rows: "%d 行已选择"
},
info: "显示 _START_ 至 _END_ 共 _TOTAL_ 行",
lengthMenu: "每页显示 _MENU_ 行",
search: "过滤:"
},
//列渲染开始,数量与html的table中的列数量保持一致
_columns_: [
{
"searchable": false,
//"title":"序号",
"className": "rowNum text-nowrap text-right",
"data": function (row, type, val, meta) {
var cellData;
switch (type) {
case 'display':
cellData = meta.row + 1;
break;
case 'set':
case'filter':
default :
}
return cellData;
},
"defaultContent": "--",
"name": "rowNum",
"orderable": false,
"type": "num"
},
{
"searchable": false,
//"title":"name",
"className": "name text-nowrap text-center",
"data": function (row, type, val, meta) {
var cellData;
switch (type) {
case 'display':
cellData = row.name == "" ? null: row.name;
break;
case 'set':
row.name = val;
break;
case'filter':
default :
}
return cellData;
},
"defaultContent": "--",
"name": "name",
"orderable": false,
"type": "string"
},
{
"searchable": false,
//"title":"中文名",
"className": "chineseName text-nowrap text-center",
"data": function (row, type, val, meta) {
var cellData;
switch (type) {
case 'display':
cellData = row.chineseName == "" ? null : row.chineseName;
break;
case 'set':
row.chineseName = val;
break;
case'filter':
default :
}
return cellData;
},
"defaultContent": "--",
"name": "chineseName",
"orderable": false,
"type": "string"
},
{
"searchable": false,
//"title":"创建时间",
"className": "createTime text-nowrap text-center",
"data": function (row, type, val, meta) {
var cellData;
switch (type) {
case 'display':
cellData = row.createTime;
break;
case 'set':
row.createTime = val;
break;
case'filter':
default :
}
return cellData;
},
"defaultContent": "--",
"name": "createTime",
"orderable": false,
"type": "string"
},
{
"searchable": false,
//"title":"更新时间",
"className": "updateTime text-nowrap text-center",
"data": function (row, type, val, meta) {
var cellData;
switch (type) {
case 'display':
cellData = row.updateTime;
break;
case 'set':
row.updateTime = val;
break;
case'filter':
default :
}
return cellData;
},
"defaultContent": "--",
"name": "updateTime",
"orderable": false,
"type": "date"
},
{
"searchable": false,
//"title":"状态",
"className": "status text-nowrap text-center",
"data": function (row, type, val, meta) {
var cellData;
switch (type) {
case 'display':
switch (row.status) {
case 'e':
cellData = "<span class='label label-default'>编辑中</span>";
break;
case 'E':
cellData = "<span class='label label-danger'>错误</span>";
break;
case 's':
default:
cellData = "<span class='label label-primary'>同步</span>";
break;
}
break;
case 'set':
row.status = val;
break;
case'filter':
default :
}
return cellData;
},
"defaultContent": "",
"name": "state",
"orderable": false,
"type": "html"
}
],
init: function () {
var _this;
_this = this;
this._tableBox_ = document.querySelector("div.box.tableBox");
var url = "http://192.168.0.210:2004/RoamingManage/admin/position/continents";
this.refresh(url, new Params());//获取所有大洲的数据,渲染表格
},
initDataTable: function () {
var _this;
_this = this;
$.fn.dataTable.ext.errMode = 'none';
this._dataTable_ = $("#continentManageTable").DataTable({
serverSide: true,
info: true,
dom: 'lBrtip',
scrollX: true,
bLengthChange:false, //关闭每页显示多少条数据
bPaginate: false, //翻页功能
bInfo: false,//页脚信息
/* scrollY: "50vh",*/
autoWidth: false,
searching: false,
columns: _this._columns_,
language: _this._language_,
rowId: "id",
processing: true,
scrollCollapse: true,
colReorder: {
fixedColumnsLeft: 2,
fixedColumnsRight: 1
},
buttons: [
{
className: "btn btn-danger Del disabled",
text: "删除",
action: function (e, dt, node, config) {
continentManageTableEventHandler.buttonDelete(e, dt, node, config);
}
}, {
className: "btn btn-primary Edit disabled",
text: "编辑",
action: function (e, dt, node, config) {
continentManageTableEventHandler.buttonEdit(e, dt, node, config);
}
}, {
className: "btn btn-primary Add",
text: "添加",
action: function (e, dt, node, config) {
continentManageTableEventHandler.buttonAdd(e, dt, node, config);
}
}
],
keys: false,
select: true,
fixedColumns: {
leftColumns: 2,
rightColumns: 1
},
pagingType: "full_numbers",
ordering: false,
ajax: {
url: _this._url_,
data: function (data, settings) {
_this._data_(data, settings);
},
dataSrc: "data"
}
});
this._dataTable_.on("select", function (e, dt, type, indexes) {
continentManageTableEventHandler.select(e, dt, type, indexes);
});
this._dataTable_.on("deselect", function (e, dt, type, indexes) {
continentManageTableEventHandler.deselect(e, dt, type, indexes);
});
continentManageTableEventHandler.init(this._dataTable_);
},
_data_: function (data, settings) {
var first, max;
for (var key in data) {
switch (key) {
case "start":
first = data[key];
break;
case "length":
max = data[key];
break;
case "":
}
delete data[key];
}
data.page = first / max + 1;
data.rows = max;
$.extend(data, this._params_);
},
refresh: function (url, params) {
// 先执行
this._url_ = url;
this._params_ = params;
if (this._dataTable_ == null) {
this.initDataTable();
} else {
this._dataTable_.ajax.url(this._url_).load();
}
this.showTableBox();
},
showTableBox: function () {
if (this._tableBox_.classList.contains("hidden")) {
this._tableBox_.classList.remove("hidden");
}
},
hideTableBox: function () {
if (!this._tableBox_.classList.contains("hidden")) {
this._tableBox_.classList.add("hidden");
}
},
getDataTable: function () {
return this._dataTable_;
}
};
const continentManageTableEventHandler = {
_dataTable_: null,
_tableBox_: null,
_table_: null,
init: function (dataTable) {
var table, _this;
this._dataTable_ = dataTable;
this._tableBox_ = document.querySelector("div.box.tableBox");
this._table_ = this._tableBox_.querySelector("table.table");
_this = this;
this._table_.addEventListener("keydown", function (event) {
_this.deleteKey(event);
});
},
buttonAdd: function (e, dt, node, config) {
continentManageTableEditor.dialogEditor(dt, "add");
},
buttonDelete: function (e, dt, node, config) {
var rowDatas, params, callBack;
rowDatas = dt.rows({selected: true}).data();
if (rowDatas.length != 1) {
return;
}
//
this._doDel_(rowDatas);
},
deleteKey: function (event) {
if (event.which == 46 || event.keyCode == 46) {
var rowDatas = this._dataTable_.rows({selected: true}).data();
if (rowDatas.length != 1) {
return;
}
this._doDel_(rowDatas);
}
},
_doDel_: function (rowDatas) {
var params, callBack, _this;
params = new Params();
params["id"] = rowDatas[0].id;
params["name"] = rowDatas[0].name;
_this = this;
callBack = function (data) {
$.messager.alert(data.message);
if (data.status === true) {
// 刷新当前页
_this._dataTable_.ajax.reload(null, false);
}
};
console.dir($.messager.model);
$.messager.confirm("删除", "确定要删除[" + params.name + "]这个大洲吗?"
, function () {
$.post("http://192.168.0.210:2004/RoamingManage/admin/position" + "/delContinent", params, callBack, "json");
});
},
buttonEdit: function (e, dt, node, config) {
if (dt.rows({selected: true}).count() == 1) {
continentManageTableEditor.dialogEditor(dt, "edit")
}
},
select: function (e, dt, type, indexes) {
var count, delBtn, editBtn;
count = dt.rows({selected: true}).count();
delBtn = this._tableBox_.querySelector(".btn.Del");
// del edit 分开 判断 ,因为以后 del 可能可多个
if (count == 1) {
delBtn.classList.remove("disabled");
/* this._table_.setAttribute("tabindex",0);
this._table_.focus();*/
} else if (count != 1) {
delBtn.classList.add("disabled");
/* this._table_.setAttribute("tabindex",undefined);
this._table_.blur();*/
}
editBtn = this._tableBox_.querySelector(".btn.Edit");
if (count == 1) {
editBtn.classList.remove("disabled");
} else if (count != 1) {
editBtn.classList.add("disabled");
}
//addBtn = this._tableBox_.querySelector(".bun.Add");
},
deselect: function (e, dt, type, indexes) {
this.select(e, dt, type, indexes);
}
};
const continentManageTableEditor = {
_dialogDiv_: null,
_dialogEditor_: null,
_initDialogEditor_: function () {
var _this, e;
_this = this;
this._dialogDiv_ = document.querySelector("#continentManageEditDialog");
this._dialogEditor_ = $("#continentManageEditDialog").modal({
show: false,
keyboard: true,
backdrop: "static"
});
// 提交按钮
e = document.querySelector("#editorFormSubmit");
e.addEventListener("click", function () {
_this.save(this);
});
},
/**
*
* @param dt dataTable 对象
* @param type [add,edit]
*/
dialogEditor: function (dt, type) {
if (this._dialogEditor_ == null) {
this._initDialogEditor_();
}
switch (type) {
case 'edit':
var row, rowData;
row = dt.row({selected: true});
rowData = row.data();
this._initForEdit_(row.index(), rowData);
break;
case 'add':
default:
this._initForAdd_();
}
this._dialogEditorProtected_(false);
this._dialogEditor_.modal("show");
},
_initForEdit_: function (rowIndex, rowData) {
var group, form, e;
this._dialogDiv_.querySelector("#continentManageEditDialogTitle").innerHTML = "编辑大洲[" +rowData.name+ rowData.chineseName + "]";
form = this._dialogDiv_.querySelector("#continentManageEditorForm");
form.setAttribute("data-editType", "edit");
form.setAttribute("data-rowIndex", rowIndex);
form.setAttribute("data-id",rowData.id);
form.setAttribute("data-name", rowData.name);
form.setAttribute("data-chineseName",rowData.chineseName);
e = form.querySelector("input[name='name']");
e.value = rowData.name;
e = form.querySelector("input[name='chineseName']");
e.value = rowData.chineseName;
group = this._dialogDiv_.querySelector("div.form-group.name");
group.classList.remove("hidden");
group.classList.add("show");
},
_initForAdd_: function () {
var group, form, e;
this._dialogDiv_.querySelector("#continentManageEditDialogTitle").innerHTML = "添加大洲";
form = this._dialogDiv_.querySelector("#continentManageEditorForm");
form.setAttribute("data-editType", "add");
form.setAttribute("data-rowIndex", null);
form.setAttribute("data-name", null);
e = form.querySelector("input[name='name']");
e.value = "";
e = form.querySelector("input[name='chineseName']");
e.value = "";
group = this._dialogDiv_.querySelector("div.form-group.name");
group.classList.remove("hidden");
group.classList.add("show");
},
/**
*
* @param isProtected Boolean
* @private
*/
_dialogEditorProtected_: function (isProtected) {
var submitBtn, cancelBtn, editorArray, editor, disabled;
submitBtn = document.querySelector("#editorFormSubmit");
cancelBtn = document.querySelector("#editorFormCancel");
cancelBtn.disabled = isProtected;
submitBtn.disabled = isProtected;
if (isProtected) {
cancelBtn.classList.add("disabled");
submitBtn.classList.add("disabled");
} else {
cancelBtn.classList.remove("disabled");
submitBtn.classList.remove("disabled");
}
editorArray = submitBtn.form.querySelectorAll(".editor");
for (var i = 0; i < editorArray.length; i++) {
editor = editorArray[i];
if (isProtected) {
editor.classList.add("disabled");
} else {
editor.classList.remove("disabled");
}
editor.disabled = isProtected;
}
},
save: function (btn) {
this._dialogEditorProtected_(true);
var form, editorArray, i, editor, value, params, callBack, editType, url, _this;
form = btn.form;
editorArray = form.querySelectorAll(".editor");
params = new Params();
editType = form.getAttribute("data-editType");
if (editType == "edit") {
params.id = form.getAttribute("data-id");
params.name = form.getAttribute("data-name");
params.chineseName = form.getAttribute("data-chineseName");
}
for (i = 0; i < editorArray.length; i++) {
editor = editorArray[i];
if (editor.classList.contains("validate")
&& editor.getAttribute("data-validate") == "error") {
this._dialogEditorProtected_(false);
return;
}
if (editor.name == "name" && editType == "name") {
continue;
}
value = editor.getAttribute("data-value");
if (value != null && value != "") {
params[editor.name] = editor.value;;
} else {
params[editor.name] = editor.value;
}
}
//console.log(params);
_this = this;
callBack = editType == "edit" ? function (data) {
_this._editCallBack_(data);
} : function (data) {
_this._addCallBack_(data);
};
url = editType == "edit" ? "/editContinent" : "/addContinent";
console.log(params);
$.post("http://192.168.0.210:2004/RoamingManage/admin/position" + url, params, callBack, "json");
},
_editCallBack_: function (data) {
//console.log(data);//false
var message, form;
form = this._dialogDiv_.querySelector("#continentManageEditorForm");
this._dialogEditor_.modal("hide");
if (data.status) {
var row, rowIndex;
rowIndex = parseInt(form.getAttribute("data-rowIndex"));
// 加入状态信息
data.data.status = 's';
row = continentManageTableBox.getDataTable().row(rowIndex);
row.data(data.data);
$.messager.popup(data.message);
} else {
message = data.message;
if (data.validateDetail != null) {
message += "<br/>";
for (var key in data.validateDetail) {
message += key + " : " + data.validateDetail[key];
message += "<br/>";
}
}
$.messager.alert(message);
}
this._dialogEditorProtected_(false);
},
_addCallBack_: function (data) {
var message;
this._dialogEditor_.modal("hide");
if (data.status) {
message = data.message + "(已刷新本页),<strong class='text-danger'>新数据 不一定显示在本页</strong>";
message += "<br/>";
for (var key in data.data) {
message += key + " : " + data.data[key];
message += "<br/>";
}
$.messager.alert(message);
} else {
message = data.message;
if (data.validateDetail != null) {
message += "<br/>";
for (var key in data.validateDetail) {
message += key + " : " + data.validateDetail[key];
message += "<br/>";
}
}
$.messager.alert(message);
}
this._dialogEditorProtected_(false);
continentManageTableBox.getDataTable().draw(false);
}
};