JAVA_树状表格分页(layUI、treeTable.js)

效果图展示(PS:本人很懒,刚开始想在网上随意找一个就用,后来发现好像PHP的不少,JAVA的树状表格大多数跟我开始写的一样没有分页,导致数据量过大后加载过于缓慢被客户吐糟,最后没找到合适的就自己写了一个简单的demo,不嫌弃的话可以自己再改改样式)

准备:layUItreeTable.js

代码展示:

<input id="total" type="hidden" value="${total }">
	<table class="layui-table layui-form" id="tree-table" lay-size="sm"></table>
	<div id="pageDemo"></div>
	
	<script type="text/javascript">
		$(function(){
	           $.ajax({
				url :'tSDepartController.do?getDataNew',
				data : {
					'curr' : 1,
					'limit' : 10
				},
				type : 'post',
				dataType : 'json',
				success : function(data){
					test(data);
				}
			})            
		})
		
		function test(data){
			layui.config({
				base: 'plug-in/test/',
			})
			layui.use(['laypage', 'treeTable', 'layer', 'code', 'form'],function(){
				var o = layui.$,
					form = layui.form,
					laypage = layui.laypage,
					layer = layui.layer,
					treeTable = layui.treeTable;
				var	re = treeTable.render({
					elem: '#tree-table',
					data: data,
					icon_key: 'departname',
					is_checkbox: true,
					end: function(e){
						form.render();
					}
					,cols: [
						{
							key: 'departname',
							title: '机构名称',
							width: '1500px',
							align: 'left',
						},
						{
							key: 'description',
							title: '机构描述',
							width: '1000px',
							align: 'center',
						},
						{
							key: 'parentdepartid',
							title: '父ID',
							width: '100px',
							align: 'left',
						},
						{
							key: 'orgCode',
							title: '机构编码',
							width: '100px',
							align: 'center',
						},
						{
							key: 'orgType',
							title: '机构类型',
							width: '100px',
							align: 'center',
						},
						{
							key: 'mobile',
							title: '电话',
							width: '300px',
							align: 'center',
						},
						{
							key: 'fax',
							title: '传真',
							width: '300px',
							align: 'center',
						},
						{
							key: 'address',
							title: '地址',
							width: '1000px',
							align: 'left',
						},
						{
							title: '标记',
							width: '100px',
							align: 'center',
							template: function(item){
								return '<input type="checkbox" name="close" lay-skin="switch" lay-text="ON|OFF">';
							}
						}
					]
				});
				
				// 监听checkbox选择
				treeTable.on('tree(box)',function(data){
					layer.msg(JSON.stringify(data));
				})
				
			});
		}
		
		layui.use(['laypage', 'layer'],function(){
			var laypage = layui.laypage
				,layer = layui.layer;
			
			var total = $('#total').val();
			
			//分页
			laypage.render({
				elem: 'pageDemo'
				,count: total
				,limit: 10
				,skin: '#1E9FFF'
				,layout: ['count', 'prev', 'page', 'next', 'limit', 'skip']
				,jump: function(obj, first){
					if(!first){
						$.ajax({
							url :'tSDepartController.do?getDataNew',
							data : {
								'curr' : obj.curr,
								'limit' : obj.limit
							},
							type : 'post',
							dataType : 'json',
							success : function(data){
								test(data);
							}
						});
					}
				}
			});
		})
	</script>
@RequestMapping(params = "list")
public ModelAndView list(HttpServletRequest request) {
		int total = 0;// 一级机构总数
		// 获取一级机构总数
        String sql_total = "select count(1) total from t_s_depart where org_type = '1'";
        List<Map<String, Object>> list_total =  systemService.findForJdbc(sql_total);
        if(!ListUtils.isNullOrEmpty(list_total)){
        	for (Map<String, Object> map : list_total) {
        		total = Integer.parseInt(map.get("total")==null?"0":map.get("total").toString());
			}
        }
        request.setAttribute("total", total);
        
		return new ModelAndView("com/szerp/department/tSDepartListNew");
	}
	
@RequestMapping(params = "getDataNew")
@ResponseBody
public List<TSDepartEntity> getDataNew(HttpServletRequest request, HttpServletResponse response) throws IOException{
		int page = request.getParameter("curr")==null?1:Integer.parseInt(request.getParameter("curr").toString());
		int limit = request.getParameter("limit")==null?1:Integer.parseInt(request.getParameter("limit").toString());
		
		// 分页数据
        String sql_data = "select id,departname,description,parentdepartid,org_code,org_type,mobile,fax,address,depart_order from (select rownum num,d.* from t_s_depart d where d.org_type = '1') where num > "+((page-1)*limit)+" and num <= "+(page*limit);
        List<Map<String, Object>> list_data = systemService.findForJdbc(sql_data);
        List<TSDepartEntity> listDepart = new ArrayList<TSDepartEntity>();
        String ids = "";
        if(!ListUtils.isNullOrEmpty(list_data)){
        	for (Map<String, Object> map : list_data) {
        		ids = ids + "'" + (map.get("ID")==null?"":map.get("ID").toString()) + "',";
        		
        		TSDepartEntity tSDepart = new TSDepartEntity();
        		tSDepart.setId(map.get("ID")==null?"":map.get("ID").toString());
        		tSDepart.setDepartname(map.get("DEPARTNAME")==null?"":map.get("DEPARTNAME").toString());
        		tSDepart.setDescription(map.get("DESCRIPTION")==null?"":map.get("DESCRIPTION").toString());
        		tSDepart.setParentdepartid(map.get("PARENTDEPARTID")==null?"":map.get("PARENTDEPARTID").toString());
        		tSDepart.setOrgCode(map.get("ORG_CODE")==null?"":map.get("ORG_CODE").toString());
        		tSDepart.setOrgType(map.get("ORG_TYPE")==null?"":map.get("ORG_TYPE").toString());
        		tSDepart.setMobile(map.get("MOBILE")==null?"":map.get("MOBILE").toString());
        		tSDepart.setFax(map.get("FAX")==null?"":map.get("FAX").toString());
        		tSDepart.setAddress(map.get("ADDRESS")==null?"":map.get("ADDRESS").toString());
        		tSDepart.setDepartOrder(map.get("DEPART_ORDER")==null?"":map.get("DEPART_ORDER").toString());
        		listDepart.add(tSDepart);
    		}
        }
        ids = "("+ids.substring(0, ids.length()-1)+")";
        
        String sql = "select id,departname,description,parentdepartid,org_code,org_type,mobile,fax,address,depart_order from t_s_depart where parentdepartid in"+ids;
        List<Map<String, Object>> list_data2 = systemService.findForJdbc(sql);
        if(!ListUtils.isNullOrEmpty(list_data2)){
        	return getNext(listDepart, list_data2, ids);
        }
        
		return listDepart;
	}
	
	public List<TSDepartEntity> getNext(List<TSDepartEntity> listDepart, List<Map<String, Object>> list_data2, String ids){
    	String ids_ = "";
		for (Map<String, Object> map : list_data2) {
			ids_ = ids_ + "'" + (map.get("ID")==null?"":map.get("ID").toString()) + "',";
			
    		TSDepartEntity tSDepart = new TSDepartEntity();
    		tSDepart.setId(map.get("ID")==null?"":map.get("ID").toString());
    		tSDepart.setDepartname(map.get("DEPARTNAME")==null?"":map.get("DEPARTNAME").toString());
    		tSDepart.setDescription(map.get("DESCRIPTION")==null?"":map.get("DESCRIPTION").toString());
    		tSDepart.setParentdepartid(map.get("PARENTDEPARTID")==null?"":map.get("PARENTDEPARTID").toString());
    		tSDepart.setOrgCode(map.get("ORG_CODE")==null?"":map.get("ORG_CODE").toString());
    		tSDepart.setOrgType(map.get("ORG_TYPE")==null?"":map.get("ORG_TYPE").toString());
    		tSDepart.setMobile(map.get("MOBILE")==null?"":map.get("MOBILE").toString());
    		tSDepart.setFax(map.get("FAX")==null?"":map.get("FAX").toString());
    		tSDepart.setAddress(map.get("ADDRESS")==null?"":map.get("ADDRESS").toString());
    		tSDepart.setDepartOrder(map.get("DEPART_ORDER")==null?"":map.get("DEPART_ORDER").toString());
    		listDepart.add(tSDepart);
    	}
		ids_ = "("+ids_.substring(0, ids_.length()-1)+")";
		
		String sql = "select id,departname,description,parentdepartid,org_code,org_type,mobile,fax,address,depart_order from t_s_depart where parentdepartid in"+ids_;
	    List<Map<String, Object>> list = systemService.findForJdbc(sql);
	    if(!ListUtils.isNullOrEmpty(list)){
	    	getNext(listDepart, list, ids_);
	    }   
		
        return listDepart;
	}

treeTable.js代码如下:

layui.define(['jquery'], function(exports) {
	var MOD_NAME = 'treeTable',
		o = layui.jquery,
		tree = function() {};
	tree.prototype.config = function() {
		return {
			top_value: 0,
			primary_key: 'id',
			parent_key: 'parentdepartid',
			hide_class: 'layui-hide',
			icon: {
				open: 'layui-icon layui-icon-triangle-d',
				close: 'layui-icon layui-icon-triangle-r',
				left: 16,
			},
			cols: [],
			checked: {},
			is_click_icon: false,
			is_checkbox: false,
			is_cache: true,
		};
	}
	tree.prototype.template = function(e) {
		var t = this,
			level = [],
			tbody = '',
			is_table = o('table' + e.elem).length || !(e.is_click_icon = true),
			checkbox = e.is_checkbox ? '<div class="layui-unselect layui-form-checkbox cbx" lay-skin="primary"><i class="layui-icon layui-icon-ok"></i></div>' : '',
			checked = checkbox ? checkbox.replace('cbx', 'cbx layui-form-checked') : '',
			thead = checkbox && '<th style="width:28px;">' + (o.inArray(e.top_value, e.checked.data) > -1 ? checked : checkbox) + '</th>';
		o.each(t.data(e, e.data), function(idx, item) {
			var tr = '',
				is_checked = false,
				hide_class = (item[e.parent_key] == e.top_value) || (item[e.parent_key] == t.cache(e, item[e.parent_key])) ? '' : e.hide_class;
			// 设置每行数据层级
			item.level = level[item[e.primary_key]] = item[e.parent_key] != e.top_value ? (level[item[e.parent_key]] + 1) : 0;
			// 设置是否为最后一级
			item.is_end = !e.childs[item[e.primary_key]];
			o.each(e.cols, function(index, obj) {
				var style = '';
				obj.width && (style += 'width:' + obj.width + ';'), obj.align && (style += 'text-align:' + obj.align + ';'), style && (style = 'style="' + style + '"');
				// 标记设置行checkbox选中
				if(e.is_checkbox && e.checked && o.inArray(item[e.checked.key], e.checked.data) > -1) {
					is_checked = true;
				}
				// 第一次遍历头部的时候拼接表格头部
				idx || (thead += '<th ' + style + '>' + obj.title + '</th>');
				// 指定列加入开启、关闭小图标
				var icon = (obj.key == e.icon_key && !item.is_end) ? '<i class="' + (t.cache(e, item[e.primary_key]) ? e.icon.open : e.icon.close) + '"></i>' : '<span></span>';
				// 指定列小图标按照层级向后位移
				var left = (obj.key == e.icon_key ? level[item[e.primary_key]] * e.icon.left + 'px' : '');
				icon = icon.replace('>', ' style="margin-left:' + left + ';">');
				// 拼接行
				tr += '<td ' + style + (left ? 'data-down' : '') + '>' + icon + (is_table ? '' : (is_checked ? checked : checkbox)) + (obj.template ? obj.template(item) : item[obj.key]) + '</td>';
			});
			var box = is_table ? o(is_checked ? checked : checkbox).wrap('<td style="width:28px;">').parent().prop('outerHTML') : '';
			tbody += '<tr class="' + hide_class + '" data-id="' + item[e.primary_key] + '" data-parentdepartid="' + item[e.parent_key] + '">' + box + tr + '</tr>';
		});
		// 处理表树和树的赋值模板
		var table = is_table ? '<thead><tr data-id="' + e.top_value + '">' + thead + '</tr></thead><tbody>' + tbody + '</tbody>' : tbody.replace(/<tr/g, '<ul').replace(/tr>/g, 'ul>').replace(/<td/g, '<li').replace(/td>/g, 'li>');
		// 确认点击图标或点击列触发展开关闭
		var click_btn = e.is_click_icon ? '[data-down] i:not(.layui-icon-ok)' : '[data-down]';
		// 模板渲染并处理点击展开收起等功能
		o(e.elem).html(table).off('click', click_btn).on('click', click_btn, function() {
			var tr = o(this).parents('[data-id]'),
				td = tr.find('[data-down]'),
				id = tr.data('id'),
				parentdepartid = tr.data('parentdepartid'),
				is_open = (td.find('i:not(.layui-icon-ok)').attr('class') == e.icon.close);
			if(is_open) {
				// 展开子级(子级出现、更改图标)
				td.find('i:not(.layui-icon-ok)').attr('class', e.icon.open);
				td.parents(e.elem).find('[data-parentdepartid=' + id + ']').removeClass(e.hide_class);
				t.cache(e, id, true);
			} else {
				// 关闭子级(更改图标、隐藏所有子孙级)
				td.find('i:not(.layui-icon-ok)').attr('class', e.icon.close);
				t.childs_hide(e, id);
			}
			// 设置监听展开关闭
			layui.event.call(this, MOD_NAME, 'tree(flex)', {
				elem: this,
				item: e.childs[parentdepartid][id],
				table: e.elem,
				is_open: is_open,
			})
		}).off('click', '.cbx').on('click', '.cbx', function() {
			var is_checked = o(this).toggleClass('layui-form-checked').hasClass('layui-form-checked'),
				tr = o(this).parents('[data-id]'),
				id = tr.data('id'),
				parentdepartid = tr.data('parentdepartid');
			t.childs_checkbox(e, id, is_checked);
			t.parents_checkbox(e, parentdepartid);
			// 设置监听checkbox选择
			layui.event.call(this, MOD_NAME, 'tree(box)', {
				elem: this,
				item: parentdepartid === undefined ? {} : e.childs[parentdepartid][id],
				table: e.elem,
				is_checked: is_checked,
			})
		}).off('click', '[lay-filter]').on('click', '[lay-filter]', function() {
			var tr = o(this).parents('[data-id]'),
				id = tr.data('id'),
				parentdepartid = tr.data('parentdepartid'),
				filter = o(this).attr("lay-filter");
			return layui.event.call(this, MOD_NAME, 'tree(' + filter + ')', {
				elem: this,
				item: e.childs[parentdepartid][id],
			})
		});
		e.end && e.end(e);
	};
	// 同级全部选中父级选中/同级全部取消取消父级
	tree.prototype.parents_checkbox = function(e, parentdepartid) {
		var po = o(e.elem).find('[data-parentdepartid=' + parentdepartid + ']'),
			co = o(e.elem).find('[data-id=' + parentdepartid + ']'),
			len = o(e.elem).find('[data-parentdepartid=' + parentdepartid + '] .cbx.layui-form-checked').length;
		if(po.length == len || len == 0) {
			var parentdepartid = co.data('parentdepartid');
			len ? co.find('.cbx').addClass('layui-form-checked') : co.find('.cbx').removeClass('layui-form-checked');
			parentdepartid === undefined || this.parents_checkbox(e, parentdepartid);
		}
	};
	// 子级反选
	tree.prototype.childs_checkbox = function(e, id, is_checked) {
		var t = this;
		o(e.elem).find('[data-parentdepartid=' + id + ']').each(function() {
			var checkbox = o(this).find('.cbx');
			is_checked ? checkbox.addClass('layui-form-checked') : checkbox.removeClass('layui-form-checked');
			t.childs_checkbox(e, o(this).data('id'), is_checked);
		})
	};
	// 点击收起循环隐藏子级元素
	tree.prototype.childs_hide = function(e, id) {
		var t = this;
		t.cache(e, id, false);
		o(e.elem).find('[data-parentdepartid=' + id + ']:not(.' + e.hide_class + ')').each(function() {
			var td = o(this).find('[data-down]'),
				i = td.find('i:not(.layui-icon-ok)');
			// 关闭更换小图标
			i.length && i.attr('class', e.icon.close);
			// 隐藏子级
			td.parents(e.elem).find('[data-parentdepartid=' + id + ']').addClass(e.hide_class);
			t.childs_hide(e, o(this).data('id'))
		});
	};
	// 重新组合数据,父子级关系跟随
	tree.prototype.data = function(e) {
		var lists = [],
			childs = [];
		o.each(e.data, function(idx, item) {
			lists[item[e.primary_key]] = item;
			if(!childs[item[e.parent_key]]) {
				childs[item[e.parent_key]] = [];
			}
			childs[item[e.parent_key]][item[e.primary_key]] = item;
		});
		e.childs = childs;
		return this.tree_data(e, lists, e.top_value, []);
	};
	tree.prototype.tree_data = function(e, lists, parentdepartid, data) {
		var t = this;
		if(lists[parentdepartid]) {
			data.push(lists[parentdepartid]);
			delete lists[parentdepartid]
		}
		o.each(e.data, function(index, item) {
			if(item[e.parent_key] == parentdepartid) {
				data.concat(t.tree_data(e, lists, item[e.primary_key], data))
			}
		});
		return data;
	};
	tree.prototype.render = function(e) {
		var t = this;
		e = o.extend(t.config(), e);
		if(e.url) {
			o.get(e.url, function(res) {
				e.data = res;
				t.template(e);
			})
		} else {
			t.template(e);
		}
		return e;
	};
	// 获取已选值集合
	tree.prototype.checked = function(e) {
		var ids = [];
		o(e.elem).find('.cbx.layui-form-checked').each(function() {
			var id = o(this).parents('[data-id]').data('id');
			ids.push(id);
		})
		return ids;
	};
	// 全部展开
	tree.prototype.openAll = function(e) {
		var t = this;
		o.each(e.data, function(idx, item) {
			item[e.primary_key] && t.cache(e, item[e.primary_key], true);
		})
		t.render(e);
	}
	// 全部关闭
	tree.prototype.closeAll = function(e) {
		localStorage.setItem(e.elem.substr(1), '');
		this.render(e);
	}
	tree.prototype.on = function(events, callback) {
		return layui.onevent.call(this, MOD_NAME, events, callback)
	};
	// 存储折叠状态
	tree.prototype.cache = function(e, val, option) {
		if(!e.is_cache) {
			return false;
		}
		var t = this,
			name = e.elem.substr(1),
			val = val.toString(),
			cache = localStorage.getItem(name) ? localStorage.getItem(name).split(',') : [],
			index = o.inArray(val, cache);
		if(option === undefined) {
			return index == -1 ? false : val
		}
		if(option && index == -1) {
			cache.push(val)
		}
		if(!option && index > -1) {
			cache.splice(index, 1)
		}
		localStorage.setItem(name, cache.join(','));
	};
	var tree = new tree();
	exports(MOD_NAME, tree)
});

更改父级ID字段时,别忘记treeTable.js中也要一同更改哦(以上展示代码为初版demo,若需使用建议优化,还有不要跟我一样不是正式发行版代码就不写备注

 

Layui是一款轻量级前端框架,用于快速开发网页界面。而Treetable.jsLayui中的一款插件,用于在表格中展示树状结构的数据。 要下载并使用Treetable.js,首先需要访问Layui官网(https://www.layui.com/)。在官网的首页或者插件市场中,都可以找到Treetable.js的下载链接。 点击下载链接后,会跳转到官方的GitHub仓库页面。在这个页面中,可以找到Treetable.js的源代码和文档。 有两种方式可以下载Treetable.js,一种是直接点击页面右上方的绿色按钮“Code”,然后选择“Download ZIP”将整个插件的源代码打包下载到本地。另一种方式是通过Git工具,克隆整个仓库到本地。 下载完成后,解压缩ZIP文件或者打开克隆的本地仓库目录,可以找到Treetable.js的核心文件和示例代码。 将核心文件中的treetable.jstreetable.css两个文件拷贝到项目中的对应目录,如Layui项目的layui/lay/modules/treetable目录下。 接下来,在HTML文件中引入Treetable.js的核心文件,方式可以是将其直接写入HTML的script和link标签中,也可以使用模块化的方式进行引入。 最后,在HTML文件中的JavaScript代码中,使用layui.use方法加载Treetable模块,然后通过Treetable.render方法来渲染表格,并传入对应的配置参数。 至此,Treetable.js插件的下载以及使用就完成了。可以根据具体需求自定义配置参数,来展示树状结构的数据。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值