bootstraptable是一款很好用的表格插件,自己浅浅的使用了一下,插件的属性事件就不再赘述,附上官网网址:
使用bootstrap记得引用bootstrap.js和jquery.js,官网有介绍。
下面是效果图:
下面是工程里使用的一段代码,主要是记录下服务端分页和自定义查询:
这是放表的地方,定义一个div里面放个table就行,别忘了加id:
<div class="example" style="padding-top: 20px;">
<table id="table_list"></table>
</div>
这是表上面的自定义查询框,用了bootstrap的折叠层,隐藏过多的查询框:
<div class="container" style="padding-left: 0px;margin-left: 0px;">
<button type="button" class="btn btn-info btn-xs" data-toggle="collapse" data-target="#demo">查询项</button>
<div id="demo" class="collapse">
<div class="table-responsive">
<form action="/admin/export" method="post">
<table class="table">
<tr>
<th><span>得分:</span><input type="text" name="score" id="score" placeholder="格式: 60-80 或: 60" onchange="valiValue('score',$.trim($('#score').val()))"></th>
<th><span>日期:</span><input type="text" name="time_send" id="time_send" placeholder="格式: 20170101-20170201 或:20180427235959" onchange="valiValue('time_send',$.trim($('#time_send').val()))"></th>
</tr>
<tr>
<th><span>姓名:</span><input type="text" name="name" id="name" placeholder="格式: 张xx" onchange="valiValue('name',$.trim($('#name').val()))"></th>
<th><span>邮箱:</span><input type="text" name="email" id="email" placeholder="格式: [email protected]" onchange="valiValue('email',$.trim($('#email').val()))"></th>
</tr>
<tr>
<th><span>状态:</span><input type="text" name="status" id="status" placeholder="格式: 未/已发送 或: 未/已" onchange="valiValue('status',$.trim($('#status').val()))"></th>
<th><span>电话:</span><input type="text" name="phone" id="phone" placeholder="格式: xxxxxxxxxxx" onchange="valiValue('phone',$.trim($('#phone').val()))"></th>
</tr>
<tr>
<th><input type="button" class="btn btn-success btn-xs" id="eventquery" value="开始查询"></th>
<th><input type="submit" class="btn btn-success btn-xs" value="开始导出" /></th>
</tr>
</table>
</form>
</div>
</div>
</div>
加载表的js代码:
$("#table_list").bootstrapTable({
method: "POST",
contentType: "application/x-www-form-urlencoded", //这句话是必须的,否则会出现问题,比如数据传不到后台等
url: "${pageContext.request.contextPath}/admin/user/list",
pagination: true,
pageSize: 10,
pageNumber: 1,
pageList: [5, 10, 15, 20, 25],
sidePagination: 'server', //有client和server两种,server是后台分页,适用于表格数据很大时,client是前台分页,不用赘述
queryParamsType: 'undefined', //这个和queryParams我用来做自定义查询,当然bootstraptable自带的查询也很好用,如果有特殊的查询需求就需要自定义。如果用到自带查询,添加search属性,设置为true
queryParams: queryParams,
columns: [{
title: "Id",
field: "uid",
sortable: true
},{
title: "用户名", //表格的表头文字
field: "name" //对应后台传来的json
},{
title: "邮箱",
field: "email"
},{
title: "电话",
field: "phone"
},{
title: "状态",
field: "status",
formatter: isSendEmail //这一列对应的函数,发挥的空间很大
},{
title: "发送邮件时间",
field: "timeSend",
sortable: true,
formatter: function (value, row, index) { //formatter也可以这样写
return changeDateFormat(value);
}
},{
title: "得分",
field: "score"
},{
title: "操作",
field: "empty",
formatter: empty
}],
onLoadSuccess: function(data){ //很有用的一个属性,是在表格加载成功时可以执行的动作,我在这用来显示我从后台加载过来的数据是否准确,以便排错
/* alert(JSON.stringify(data)); */
}
});
});
在用前台分页查询是,后台传的json对象不需要有rows和total属性,传一个表格内容的json数组就行了。而使用后台分页时就需要传这两个属性了,total是表格行数,rows是表格的行内容,可以是个json数组。
queryParamsType: 'undefined', //这个和queryParams我用来做自定义查询,当然bootstraptable自带的查询也很好用,如果有特殊的查询需求就需要自定义。如果用到自带查询,添加search属性,设置为true
queryParams: queryParams,
function queryParams(params) {
var sta=$.trim($("#status").val());
var stat = "";
if(sta == "未发送" || sta == "未")
{
stat = 1;
}else if(sta == "已发送" || sta == "已"){
stat = 0;
}
/* alert("name:"+$("#name").val()+";"+"score:"+$("#score").val()+";"+"time_send:"+$("#time_send").val()+";"+"email:"+$("#email").val()+";"+"status:"+stat+";"+"phone:"+$("#phone").val()+";"); */
var param = {
searchScope: "name:"+$.trim($("#name").val())+";"
+"score:"+$.trim($("#score").val())+";"
+"time_send:"+$.trim($("#time_send").val())+";"
+"email:"+$.trim($("#email").val())+";"
+"status:"+$.trim(stat)+";"+"phone:"
+$.trim($("#phone").val())+";",
pageNumber: params.pageNumber,
pageSize: params.pageSize
};
return param;
}
queryParams的函数里你可以传递给后台额外的参数,要后台分页的话得传递pageNumber和pageSize,即当前的页数和页的大小用作后台分页。我还传了搜索框的信息回去,以供搜索。
后台:
这是用作分页的工具类,数据库是mysql:
public class PageTool {
private Integer pagesize; //页面大小
private Integer pageno; //当前页
private Integer startrow; //起始行
private long totalpage; //总页数
private long totalcount; //总条数
public PageTool() {
}
public PageTool(Integer pageSize, Integer pageNo, long totalCount) {
this.pagesize = pageSize; //页面大小
this.pageno = pageNo; //当前页
this.totalcount = totalCount; //计算总条数
this.setStartrow(pageNo, pageSize); //计算起始行
this.setTotalpage(totalCount, pageSize); //计算总页数
}
public Integer getPagesize() {
return pagesize;
}
public void setPagesize(Integer pagesize) {
this.pagesize = pagesize;
}
public Integer getPageno() {
return pageno;
}
public void setPageno(Integer pageno) {
this.pageno = pageno;
}
public Integer getStartrow() {
return startrow;
}
public void setStartrow(Integer pageNo,Integer pageSize) {
this.startrow = (pageNo-1)*pageSize;
}
public long getTotalpage() {
return totalpage;
}
public void setTotalpage(long totalCount,Integer pageSize) {
this.totalpage = totalCount%pageSize==0?totalCount/pageSize:totalCount/pageSize+1;
}
public long getTotalcount() {
return totalcount;
}
public void setTotalcount(long totalcount) {
this.totalcount = totalcount;
}
}
dao层用的是hibernate,因为查询分数和日期时我想用60-80这种来表示查询一个区间,就写了一个hql语句生成类,否则dao层就要加好几个方法。有点简陋,但好在可以满足使用,filed是表名,condition是需要查询的字段名和值的字符串,用来处理我前台传过来的参数"name:"+$.trim($("#name").val())+";"+"score:"+$.trim($("#score").val())+";"+"time_send:"+$.trim($("#time_send").val())+";"+"email:"+$.trim($("#email").val())+";"+"status:"+$.trim(stat)+";"+"phone:"+$.trim($("#phone").val())+";" 。 即“name:xxx;score:xxx;time_send:xxx ...”
public class SqlCondition {
private String filed;
private String condition;
public String getFiled() {
return filed;
}
public void setFiled(String filed) {
this.filed = " from "+filed;
}
public String getCondition() {
return condition;
}
public void setCondition(String searchScope) {
String tmp = " where ";
StringBuilder strb = new StringBuilder(tmp);
Map<String,String[]> conMap = analysis(searchScope);
if(conMap.size()>0){
for(Map.Entry<String,String[]> con :conMap.entrySet()){
String[] value = con.getValue();
if(con.getValue().length == 0){
continue;
}else if(con.getValue().length >1){
strb.insert(strb.length(),con.getKey()+" BETWEEN "+"\'"+con.getValue()[0]+"\'"+" AND "+"\'"+con.getValue()[1]+"\'"+" AND ");
}else{
strb.insert(strb.length(),con.getKey()+" = "+"\'"+con.getValue()[0]+"\'"+" AND ");
}
}
}
if(strb.toString().equals(tmp)){
this.condition = "";
}else{
this.condition = strb.subSequence(0, strb.length()-4).toString();}
}
public static Map<String,String[]> analysis(String str){
Map<String,String[]> con= new HashMap<String, String[]>();
String[] strTmp = str.split(";");
for(int i=0;i<strTmp.length;i++){
String[] str1 = strTmp[i].split(":");
if(str1.length>=2 && str1[1].contains("-")){
String[] str2 = str1[1].split("-");
con.put(str1[0], str2);
}else if(str1.length>=2 && !(str1[1].contains("-")) ){
String[] str3 = {str1[1]};
con.put(str1[0],str3 );
}else{
String[] str3 = {};
con.put(str1[0],str3 );
}
}
return con;
}
}
controller:
@RequestMapping("/admin/user/list")
public void tableList(HttpServletRequest req,HttpServletResponse res) throws IOException{
int pageSize = Integer.parseInt(req.getParameter("pageSize"));
int pageNumber = Integer.parseInt(req.getParameter("pageNumber"));
String searchScope = req.getParameter("searchScope");
SqlCondition condition = new SqlCondition();
condition.setFiled("Member");
condition.setCondition(searchScope);
Long total = memberService.totalRecord(condition);
PageTool page = new PageTool(pageSize, pageNumber, total);
List<Member> memberList = memberService.findMemberByPage(condition,page);
JSONObject ob = new JSONObject();
ob.put("rows", memberList);
ob.put("total", total);
String dataStr = JSONObject.fromObject(ob).toString();
res.setHeader("Content-type", "text/html;charset=utf-8");
res.getWriter().write(dataStr);
}
dao:
public List<Member> findPageByCondition(SqlCondition condition, PageTool page){
String hql = "";
List<Member> list = new ArrayList<Member>();
Session session = getSession();
Query querypage = null;
hql = condition.getFiled()+condition.getCondition();
if(page == null){
querypage = session.createQuery(hql);
list=querypage.list();
}else{
querypage = session.createQuery(hql);
//查询最大记录数的数据
querypage.setMaxResults(page.getPagesize());
//确定查询起点
querypage.setFirstResult(page.getStartrow());
//分页查询
list=querypage.list();
}
return list;
}
public Long totalRecord(SqlCondition condition){
String hql = "";
Session session = getSession();
Query queryObject = null;
hql="select count(*) "+condition.getFiled()+condition.getCondition();
queryObject = session.createQuery(hql);
long total = (Long) queryObject.uniqueResult();
return total;
}
初次使用时遇到很多问题,很多也在网上搜索了资料,比如后台接受不到传的参,这个问题解决方法:contentType: "application/x-www-form-urlencoded",首先这句话得加,queryParamsType: 'undefined',再就检查这个属性的值是什么,‘limit’的话要传的参数是不同的,官网有介绍。
动手前先思考,哈哈 ———— Hello_Old_Luo