1.适用情况
中文官网的介绍
Datatables是一款jquery表格插件。它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能。
分页,即时搜索和排序
几乎支持任何数据源:DOM, javascript, Ajax 和 服务器处理
支持不同主题 DataTables, jQuery UI, Bootstrap, Foundation
各式各样的扩展: Editor, TableTools, FixedColumns ……
丰富多样的option和强大的API
支持国际化
超过2900+个单元测试
免费开源 ( MIT license )! 商业支持
更多特性请到官网查看
所以为什么使用它代替普通的自定义表格不言而喻了
2.前台的表格大多数情况需要做到即时搜索以提高交互性
问题来了,ajax交互,官网例子如下
初始化:
$('#example').DataTable( {
serverSide: true,
ajax: {
url: '/data-source',
type: 'POST'
}
} );
服务器返回json数据(json数据这里不多说,官网很详细),先来看一下官网的服务器请求参数:
这张参数表是关键,请求参数和返回参数必须规范,而且名称必须一致,第一次适用的时候就是因为没有仔细阅读官网文档,导致后台数据一致无法载入到表格
3.后台用的是jfinal框架,很实用,适合快速开发
逻辑代码:
public void getPatientList(){
int start = getParaToInt("start");//数据库查询起始位置
String searchValue = getPara("search[value]");//搜索框传入的值
String draw = getPara("draw");//原值返回给ajax
int length = getParaToInt("length");//数据库查询分页长度
List<User> resultList = new ArrayList<>();
List<User> userList = new ArrayList<>();
String sql = "";//数据库查询语句
if(searchValue != null && !"".equals(searchValue.trim())){
sql = "select "
+ "m.patient_id as patient_id,"
+ "m.hospital_id as hospital_id,"
+ "p.name as name,"
+ "p.tel as tel,"
+ "p.age as age,"
+ "p.sex as sex,"
+ "p.address as address,"
+ "i.url as imageUrl,i.uuid as imageName"
+ " from medical_record m"
+ " left join patient_info p on m.patient_id = p.id"//数据库关联查询
+ " left join images i on p.image_id = i.id"
+ " limit "+start+","+length;
}else{
sql = "select "
+ "m.patient_id as patient_id,"
+ "m.hospital_id as hospital_id,"
+ "p.name as name,"
+ "p.tel as tel,"
+ "p.age as age,"
+ "p.sex as sex,"
+ "p.address as address,"
+ "i.url as imageUrl,i.uuid as imageName"
+ " from medical_record m"
+ " left join patient_info p on m.patient_id = p.id"
+ " left join images i on p.image_id = i.id"
+ " limit "+start+","+length;
}
userList = MedicalRecord.dao.find(sql);
for(User item : userList){//此处是为了去除重复内容对象,所以在开始new了两个List对象
if(!resultList.contains(item)){
resultList.add(item);
}
}
int recordsTotal = Integer.valueOf(Db.queryLong("select count(*) from users ");
Map<String, Object> data = new HashMap<String, Object>();
data.put("draw", Integer.valueOf(draw));
data.put("data", resultList);
data.put("iTotalRecords", resultList.size());//返回的应该是查询结果过滤后的数目
data.put("iTotalDisplayRecords", resultList.size());//不经过分页查询符合条件记录总数
data.put("error", null);
renderJson(data);
}
4.需要注意的是draw必须原值返回,data参数名根据前台初始化时columns内的数组对象决定,iTotalRecords和iTotalDisplayRecords分别为过滤和过滤前的记录总数,error为错误信息,如果未出现异常情况下对其赋值传给前台,那么网页每次刷新的时候都会提示一个error信息,所以这个应该在捕获异常的时候抛出去,这里就不举出详细例子
下面附上完整的前台初始化代码以及效果
var lang = {
"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" : ": 以降序排列此列"
}
};
var patientListTable=$("#patientListTable").dataTable({
language : lang,
paging : true,
bLengthChange : false,//限制每页显示8条记录,
lengthMenu :8,
pagingType : "full_numbers",//分页样式
searchable : true,//开启搜索框
ordering : false,//不启用列排序
serverSide : true,//开启服务器模式
ajax : {//ajax部分
url : '/doctor/getPatientList',
type : 'POST'
},
columns : [ {data:null},
{data:'name'},
{data:'tel'},
{data:'age'},
{data:'sex'},
{data:'address'},
{data:'identity'},
{data:'email'}],
columnDefs : [
{
"data" : null,
"bSortable" : false,
"targets" : 0,
"width" : "30px",
"sClass" : "text-center"//设置css样式
},
{
"data" : null,
"bSortable" : false,
"targets" : 3,
"width" : "30px",
"sClass" : "text-center"
},
{
"data" : null,
"bSortable" : false,
"targets" : 4,
"width" : "30px",
"sClass" : "text-center"
}
],
fnDrawCallback : function() {//表格绘制完成以后回调函数
this.api().column(0).nodes().each(function(cell,i) {//添加序号
cell.innerHTML = i + 1;
});
this.api().column(4).nodes().each(function(cell,i) {
if(cell.innerHTML==0){//数据库性别用的是0/1表示,这里进行以下转换
cell.innerHTML = "男";
}else{
cell.innerHTML = "女";
}
});
}
});
效果图
索引列通常采用回调函数去处理比较方便,this.api().column(0).nodes().each()取得第一列的td单元,each遍历进行处理
还有一个非常需要的事项,对行进行监听:
patientListTable.on(“dblclick”,”tr”,function(){});//双击时间