表格渲染器,gridRender.js
/** * 表格渲染器 * * @param targetTableId 等待渲染的目标表格ID * @param data 数据(数组类型,且要求数组里面的每个数据均为同一类型的对象) * @param totalCount 表格总条数 */ function GridRender(targetTableId){ // 分页标示符(系统会自动搜索class=这个分页标示符的div,如果找到就把它渲染为分页栏) var pagingClassFlag = 'pagination'; // 渲染目标表格的Id this.targetTableId = targetTableId; // 需要渲染到表格的数据对象 this.data = null; // 渲染表格的列名数组(数组元素为字符串,且每个数组元素字符串必须与data的属性相对应) this.columnModelArr = null; // 定义本对象句柄 var gridSelf = this; // 是否有分页标记 this.hasPaging = isHasPaging(targetTableId); // 内置分页器 this.pager = (this.hasPaging==true) ? new Pager($('#' + this.targetTableId + ' div.' + pagingClassFlag),this.targetTableId) : null; if(this.pager!=null){ this.pager.showLoadingIcon(); } // 设置字段的默认值 this.defaultCellValueMap = {}; // 设置字段的默认单位 this.cellUnitMap = {}; // 开始渲染表格的行号(基于0开始的) this.startRenderRowNum = 1; // 渲染页面后触发回调函数 this.renderCallBackFun = null; // 自定义渲染表格的方法 this.customerRenderGridFunc = null; /** * 设置当前页码 */ this.setCurPageNum = function(curPageNum){ gridSelf.pager.setCurPageNum(curPageNum); } /** * 设置自定义渲染表格的方法 */ this.setCustomerRenderGridFunc = function(func){ gridSelf.customerRenderGridFunc = func; } /** * 设置渲染目标表格 */ this.setTargetTable = function(targetTableId){ gridSelf.targetTableId = targetTableId; } /** * 设置字段默认值 */ this.setCellDefaultValue = function(columnName,defaultValue){ gridSelf.defaultCellValueMap[columnName] = defaultValue; } /** * 设置字段单位 */ this.setCellUnit = function(columnName,unit){ gridSelf.cellUnitMap[columnName] = unit; } /** * 设置数据源 */ this.setData = function(data){ gridSelf.data = data; } /** * 设置表格渲染的起始行号(基于0开始的) */ this.setStartRenderRowNum = function(value){ gridSelf.startRenderRowNum = value; } /** * 设置列模型 参数为一个数组,数组里面可以是字符串(数据对象的属性名),也可以是一个用户自定义的回调函数, * 回调函数如下形式: * 表格渲染器会把当前行对象以及表格数据对象作为参数,传递给这个方法 * 所有该方法通常为这种形式, function xxx(row,data) * { * ...... * } */ this.setColumn = function(columnArr){ gridSelf.columnModelArr = columnArr; } /** * 复位 */ this.reset = function(){ cleanTable(gridSelf.targetTableId); gridSelf.pager.reset(); } /** * 停止分页器Loadding转动 */ this.hideLoadingIcon = function(){ if(gridSelf.hasPaging){ gridSelf.pager.hideLoadingIcon(); } } /** * 设置每页显示的条数 */ this.setPageSize = function(pageSize){ gridSelf.pager.setPageSize(pageSize); } /** * 设置点击分页按钮的回调函数 */ this.setPageCallbackFun = function(callBackFun){ gridSelf.pager.setPageCallbackFun(callBackFun); } /** * 设置表格渲染后的的回调函数 */ this.setRenderCallbackFun = function(callBackFun){ gridSelf.renderCallBackFun = callBackFun; } /** * 渲染表格数据(也可能会渲染分页器) */ this.render = function(data,totalCount,pageSize){ // 待渲染的数据 var tempData = data; // 表单总大小 var tempTotalCount = totalCount; var tempPageSize = pageSize; if(!totalCount){ if(data!=null && undefined != data.data) tempData = data.data; if(data!=null && undefined != data.totalCount) tempTotalCount = data.totalCount; if(data!=null && undefined != data.pageSize) tempPageSize = data.pageSize; } // 检查参数完整性 if(!checkParam(gridSelf.targetTableId,gridSelf.columnModelArr,tempData,tempTotalCount)) return null; gridSelf.data = tempData; // 去掉 loading图标 if(gridSelf.hasPaging){ gridSelf.pager.hideLoadingIcon(); } // 先删除原来的数据 cleanTable(gridSelf.targetTableId); // 插入数据到表格 // -- 如果用户自定义了渲染表格的方法,则调用 if(gridSelf.customerRenderGridFunc!=null){ gridSelf.customerRenderGridFunc(gridSelf); } // -- 否则使用默认的渲染方法 else{ insertData(gridSelf); } // 如果有分页,渲染分页栏 if(gridSelf.hasPaging){ gridSelf.pager.setTotalCount(tempTotalCount); // 如果需要改变每页大小 if(undefined != data.pageSize) gridSelf.pager.setPageSize(tempPageSize); // 渲染分页器 gridSelf.pager.render(); } // 根据经验,在渲染表格后再渲染一些可能出现的元素 afterRenderByExperience(); // 调用页面渲染后的回调函数 if(gridSelf.renderCallBackFun!=null){ gridSelf.renderCallBackFun(); } } // 页面渲染后为表格加上样式事件等 function afterRenderByExperience(){ $(".chk-detail").colorbox(); $(".chk-modify").colorbox(); } // 验证参数完整性 function checkParam(targetTableId,columnModelArr,data,totalCount){ if($('#' + targetTableId).length<1){ // openDialog('【GridRender】targetTableId参数设置错误!'); return false; } if(!checkArr(columnModelArr)){ openDialog('【GridRender】columnModelArr参数设置错误!'); return false; } if(data==undefined || data==null || data==''){ cleanTable(gridSelf.targetTableId); gridSelf.reset(); gridSelf.pager.showEmpty(); return false; } // 如果表格需要分页,totalCount和callBackFun参数是必要的 if(gridSelf.hasPaging){ if(undefined==totalCount){ openDialog('【GridRender】缺少参数totalCount!'); return false; } if(gridSelf.pager.callBackFun!=null && typeof gridSelf.pager.callBackFun != 'function'){ openDialog('【GridRender】callBackFun回调函数设置错误!'); return false; } } return true; } /** * 检查是否是数组(未使用) */ function checkArr(obj){ if(obj==null){ openDialog('【GridRender】参数传入错误!数组为空!'); return false; } if(typeof obj!='object' || !obj.length || obj.length<1){ openDialog('【GridRender】参数传入错误!参数不是数组!'); return false; } return true; } /** * 清除表格内容 */ function cleanTable(targetTableId){ var table = document.getElementById(targetTableId); var length = gridSelf.hasPaging ? table.rows.length-1 : table.rows.length; for(var i = gridSelf.startRenderRowNum; i < length; i++){ table.deleteRow(gridSelf.startRenderRowNum); } } // 先判断是否有分页 function isHasPaging(targetTableId){ return $('#' + targetTableId + ' div.' + pagingClassFlag).length > 0 ? true : false; } // 插入数据到表格 function insertData(gridSelf){ var data = gridSelf.data; var curTr = $('#' + gridSelf.targetTableId + ' tr')[gridSelf.startRenderRowNum -1]; for(var i=0;i < data.length;i++){ var tr = $('<tr/>').insertAfter(curTr); curTr = tr; for(var j=0;j < gridSelf.columnModelArr.length; j++){ var column = gridSelf.columnModelArr[j]; var value = ''; var title = ''; if(typeof column =='string'){ value = eval('data[' + i + '].' + column); // 如果值为空,设置为默认值 if(value==null && gridSelf.defaultCellValueMap[column]!=null) value = gridSelf.defaultCellValueMap[column]; // 如果值不为空,加上预先配置好的单位符号 if(value!=null && gridSelf.cellUnitMap[column]!=null) value += gridSelf.cellUnitMap[column]; title = value; } else if(typeof column =='function'){ value = column(data[i],data); } // 最后如果值为null,不要在页面上显示null,应显示为空 if(value==null) value = ''; if(title==null) title = ''; // 最后一个td加上last样式 if(j==gridSelf.columnModelArr.length-1) $('<td title="' + title + '" class="last">' + value + '</td>').appendTo(tr); else $('<td title="' + title + '">' + value + '</td>').appendTo(tr); } } } /********************************************************************************************************/ /** 以下是内置的分页器类 **/ /********************************************************************************************************/ /** * 内置分页器 * @param targetDiv 等待渲染为分页的div对象 * @param beLongTableId 所属表格的Id */ function Pager(targetDiv,beLongTableId){ // 等待渲染为分页的div对象 this.targetDiv = targetDiv; // 所属表格的Id this.beLongTableId = beLongTableId; // 记录的总数量 this.totalCount; // 每页显示的条数,默认20条 this.pageSize = 20; // 总页数 this.pageCount; // 当前页码 this.curPageNum = 1; // 点击分页码回调函数 this.callBackFun = null; // 保存当前分页句柄 var pagerObj = this; // 当前活动页码A标签 this.activeTagA; // loading提示 this.loadingTip; // 复位 this.reset = function(){ pagerObj.totalCount = 0; pagerObj.curPageNum = 1; } // 设置TotalCount值 this.setTotalCount = function(totalCount){ pagerObj.totalCount = totalCount; } // 设置pageSize值 this.setPageSize = function(pageSize){ pagerObj.pageSize = pageSize; } /** * 设置点击分页按钮的回调函数 */ this.setPageCallbackFun = function(callBackFun){ pagerObj.callBackFun = callBackFun; } /** * 设置当前页码 */ this.setCurPageNum = function(curPageNum){ pagerObj.curPageNum = curPageNum; } // 显示没内容的提示 this.showEmpty = function(){ pagerObj.hideLoadingIcon(); pagerObj.targetDiv[0].innerHTML = '<span class="err-msg">抱歉没有找到相关记录,请重新输入搜索条件</span>'; } // 显示loading提示 this.showLoadingIcon = function(){ if(pagerObj.loadingTip==null){ var img = document.createElement('img'); img.className = 'img-load'; img.src = MaMa100.basePath + '/images/ajaxLoading.gif'; pagerObj.targetDiv[0].parentNode.appendChild(img); pagerObj.loadingTip = img; } else{ pagerObj.loadingTip.style.display = ''; } } // 隐藏loading提示 this.hideLoadingIcon = function(){ if(pagerObj.loadingTip) pagerObj.loadingTip.style.display = 'none'; } // 渲染分页器 this.render = function(){ // 先清空原来的分页栏 pagerObj.targetDiv[0].innerHTML = ''; // 计算总页数 pagerObj.pageCount = computePageCount(pagerObj.totalCount,pagerObj.pageSize); var pageCount = pagerObj.pageCount; var html = ''; // 上一页 if(pagerObj.totalCount > 0 && pagerObj.curPageNum > 1) buildTagA('上一页','paging',(pagerObj.curPageNum - 1),true,false); // 首页 if(pagerObj.totalCount > 0) buildTagA('1','p01',1,false,(pagerObj.curPageNum==1?true:false)); // ... if(pagerObj.curPageNum > 4 && pageCount > 7) buildBlankTag(pagerObj.targetDiv); // 待渲染的页码数组 var pageNoArr = []; if(pagerObj.curPageNum <= 4){ pageNoArr = [2,3,4,5,6]; } else if(pagerObj.curPageNum >= (pageCount - 5)){ pageNoArr = [(pageCount-5),(pageCount-4),(pageCount-3),(pageCount-2),(pageCount-1)]; } else{ pageNoArr = [(pagerObj.curPageNum-2),(pagerObj.curPageNum-1),(pagerObj.curPageNum),(pagerObj.curPageNum+1),(pagerObj.curPageNum+2)]; } // 判断是否显示页码 for(var i=0;i<pageNoArr.length;i++){ var pageNo = pageNoArr[i]; if(isShowPageNo(pageNo,pageCount)) buildTagA(pageNo,'p01',pageNo,false,(pageNo==pagerObj.curPageNum)); } // ... if(pageCount >=8 && (pagerObj.curPageNum <= 4 || pagerObj.curPageNum < (pageCount - 5))){ buildBlankTag(pagerObj.targetDiv); } // 末页 if(pageCount > 1){ buildTagA(pageCount,'p01',pageCount,false,(pagerObj.curPageNum==pageCount?true:false)); } // 下一页 if(pagerObj.totalCount > pagerObj.pageSize && pagerObj.curPageNum < pageCount) buildTagA('下一页','paging',(pagerObj.curPageNum + 1),true,false); // 手输跳转按钮 if(pageCount > 1){ $('<label>转到</label>').appendTo(targetDiv); $('<input type="text" class="text-field" value="" />').appendTo(targetDiv); buildGoTag(pagerObj.targetDiv); } $('<label class="pagination-total-count"> 共' + pagerObj.totalCount + '条记录</label>').appendTo(targetDiv); } // 计算总页数 function computePageCount(totalCount,pageSize){ return Math.ceil(totalCount / pageSize); } // 是否显示页码 function isShowPageNo(pageNo,pageCount){ return (pageNo > 1 && pageNo < pageCount); } // 构造A标签 function buildTagA(name,className,pageNo,isSideTag,isActive){ var a = document.createElement('a'); a.href = '#'; a.className = isActive ? className + ' active' : className; // 是左右两侧标签(上一页\下一页)吗? if(isSideTag){ var span = document.createElement('span'); span.innerHTML = name; a.appendChild(span); }else{ a.id = generateTagID(pageNo); a.innerHTML = name; } // A标签点击事件 a.onclick = function(){ pageTagClickHandler(pageNo); return false; } $(a).appendTo(pagerObj.targetDiv); } // 点击分页页码事件处理 function pageTagClickHandler(pageNo){ // 显示loading图标 pagerObj.showLoadingIcon(); // 选中对应页码的tagA,并且去掉之前选中tagA的样式 $(pagerObj.activeTagA).removeClass('active'); $('#' + generateTagID(pageNo)).addClass('active'); pagerObj.activeTagA = $('#' + generateTagID(pageNo)); // 回调函数 var urlFragment = 'page.currentPage=' + pageNo; pagerObj.curPageNum = pageNo; pagerObj.callBackFun(urlFragment,pageNo); } // 生成tagA的id function generateTagID(pageNo){ return ('paggingTag_' + pagerObj.beLongTableId + '_' + pageNo); } // 构造...标签 function buildBlankTag(targetDiv){ var a = document.createElement('a'); a.href = '#'; a.innerHTML = '...'; a.onclick = function(){ return false; } $(a).appendTo(targetDiv); } // 构造确定跳转标签 function buildGoTag(targetDiv){ var input = document.createElement('input'); input.className = 'page-jump'; input.type = 'button'; input.value = '确定'; input.onclick = function(){ var inputPageNo = $('#' + pagerObj.beLongTableId + ' input.text-field'); if(isNaN(inputPageNo.val()) || inputPageNo.val() < 1 || inputPageNo.val() > pagerObj.pageCount){ inputPageNo.val(''); return; } pageTagClickHandler(parseInt(inputPageNo.val())); } $(input).appendTo(targetDiv); } } }
?
jsp页面调用
<script type="text/javascript"> var gridRender=null; function search(urlFragment){ if(gridRender==null){ gridRender = new GridRender('form1'); gridRender.setColumn(['calMonth','areaName','officeName','channelName','terminalCode','terminalName', 'numOfCustNew','numOfCustBk','rateOfBk','numOfBkY','rateOfBkY','numOfBkSms', 'numOfBkN','numOfAct','numOfAgY','rateOfAgY','numOfAgN','rateOfAgN','numOfCustAg', 'rateOfAg','numOfAgMilk','rateOfAgMilk','numOfCrossR','rateOfCrossR', 'numOfCrossNr','rateOfCrossNr','numOfCross','rateOfCross']); gridRender.startRenderRowNum=2;//设置渲染行从第三行开始 gridRender.setPageCallbackFun(freshTable); } var url = '<%=path%>/bgmSgReportRvActionsearch.action'; if(urlFragment){ url = url + '?' + urlFragment; }else{ gridRender.reset(); } $.ajax({ url: url, context: document.body, dataType : 'json', type : 'POST', data: $('#myForm').serialize(), success: function(list){ gridRender.render(list); } }); } function freshTable(urlFragment,pageNo){ search(urlFragment); } </script>
?
后台数据
//查询 public String search() throws Exception{ try { // 是否分页 boolean isPage = true; // 数据列 String[] columnArr = initColumnArr(); // 获取当前登录账号的门店 CrmTerminal crmTerminal = getLoginUser().getCrmTerminal(); // 查询数据 List<Object> list = service.getBgmSgReportRv201(crmTerminal,month,catorgory,terminalCode,page, isPage); printJSONPage(list, columnArr); } catch (Exception e) { e.printStackTrace(); printJSONResult("搜索数据失败", e.getMessage(), null); throw e; } return null; }
//数据列 ?private String[] initColumnArr() { ??String[] columnArr = {"calMonth","areaName","officeName","channelName","terminalCode","terminalName", ??????????????? "numOfCustNew","numOfCustBk","rateOfBk","numOfBkY","rateOfBkY","numOfBkSms", ??????????????? "numOfBkN","numOfAct","numOfAgY","rateOfAgY","numOfAgN","rateOfAgN","numOfCustAg", ??????????????? "rateOfAg","numOfAgMilk","rateOfAgMilk","numOfCrossR","rateOfCrossR", ??????????????? "numOfCrossNr","rateOfCrossNr","numOfCross","rateOfCross"}; ??return columnArr; ?}
?
protected void printJSONPage(List<Object> list, String[] columnArr) throws IOException { List<Map<String, Object>> result = parseListObjectArray(list, columnArr); printJSONPage(result); }
?
// 转换List<Object>为有属性名的List<map>(这个有点难描述.请原谅..) public List<Map<String, Object>> parseListObjectArray(List<Object> list, String[] columnArr) { List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(); if (list != null && list.size() > 0) { for (Object obj : list) { Object[] objArr = (Object[]) obj; Map<String, Object> row = new HashMap<String, Object>(); for (int i = 0; i < columnArr.length; i++) { row.put(columnArr[i], objArr[i]); } result.add(row); } } return result; }