当前位置: 代码迷 >> JavaScript >> js打包表格渲染器(带分页功能)
  详细解决方案

js打包表格渲染器(带分页功能)

热度:450   发布时间:2012-06-26 10:04:13.0
js封装表格渲染器(带分页功能)
表格渲染器,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;
	}
  相关解决方案