EasyUI框架03——DataGrid - GroupView

1. 写在开头

         一直说要整理一下easyUI的内容的,一直也没时间,最近真的是忙的不可开交,今天正好遇到一个需求,关于datagrid的分组展示问题的,先记录一下,以后有空了在将其他内容补上。

        easyUI是曾经比较流行的一个前端框架了,现在很多老的项目都在使用它,作为一位老鸟,我们还是需要对它有一定的认知的,这样在维护一些陈旧的项目的时候,才不会手忙脚乱了!

2. DataGrid - GroupView

其本质上也是一个datagrid,用法与datagrid基本上一致,但是要使用它,需要先引入group_view.js文件

2.1 小demo

2.1.1 方式一:类方式1

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Basic PropertyGrid - jQuery EasyUI Demo</title>
	<link rel="stylesheet" type="text/css" href="./easyui.css">
	<link rel="stylesheet" type="text/css" href="./icon.css">
	<link rel="stylesheet" type="text/css" href="./demo.css">
	<script type="text/javascript" src="./jquery.min.js"></script>
	<script type="text/javascript" src="./jquery.easyui.min.js"></script>
	<script type="text/javascript" src="./group_view.js"></script>
</head>
<body>
	<h2>Basic PropertyGrid</h2>
	<p>Click on row to change each property value.</p>
	<div style="margin:20px 0;">
		<a href="javascript:void(0)" class="easyui-linkbutton" onclick="showGroup()">ShowGroup</a>
		<a href="javascript:void(0)" class="easyui-linkbutton" onclick="hideGroup()">HideGroup</a>
		<a href="javascript:void(0)" class="easyui-linkbutton" onclick="showHeader()">ShowHeader</a>
		<a href="javascript:void(0)" class="easyui-linkbutton" onclick="hideHeader()">HideHeader</a>
		<a href="javascript:void(0)" class="easyui-linkbutton" onclick="getChanges()">GetChanges</a>
	</div>
	<table id="pg" class="easyui-propertygrid" style="width:300px" data-options="
				url:'http://localhost:8080/easy',
				method:'get',
				showGroup:true,
				scrollbarSize:0
			">
	</table>
 
	<script type="text/javascript">
		function showGroup(){
			$('#pg').propertygrid({
				showGroup:true
			});
		}
		function hideGroup(){
			$('#pg').propertygrid({
				showGroup:false
			});
		}
		function showHeader(){
			$('#pg').propertygrid({
				showHeader:true
			});
		}
		function hideHeader(){
			$('#pg').propertygrid({
				showHeader:false
			});
		}
		function getChanges(){
			var s = '';
			var rows = $('#pg').propertygrid('getChanges');
			for(var i=0; i<rows.length; i++){
				s += rows[i].name + ':' + rows[i].value + ',';
			}
			alert(s)
		}
	</script>
</html>

效果图:

2.1.2 类方式2

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Basic PropertyGrid - jQuery EasyUI Demo</title>
	<link rel="stylesheet" type="text/css" href="./easyui.css">
	<link rel="stylesheet" type="text/css" href="./icon.css">
	<link rel="stylesheet" type="text/css" href="./demo.css">
	<script type="text/javascript" src="./jquery.min.js"></script>
	<script type="text/javascript" src="./jquery.easyui.min.js"></script>
	<script type="text/javascript" src="./group_view.js"></script>
</head>
<body>
	<h2>Customize Columns of PropertyGrid</h2>
	<p>The columns of PropertyGrid can be changed.</p>
	<div style="margin:20px 0;"></div>
	<table class="easyui-propertygrid" style="width:300px" data-options="
				url: 'http://localhost:8080/easy',
				method: 'get',
				showGroup: true,
				scrollbarSize: 0,
				columns: mycolumns
			">
	</table>
	<script>
		var mycolumns = [[
    			{field:'name',title:'MyName',width:100,sortable:true},
   		    {field:'value',title:'MyValue',width:100,resizable:false}
        ]];
	</script>
</body>
	
</html>

效果图:

2.2 方式二:js方式

<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<title>Basic PropertyGrid - jQuery EasyUI Demo</title>
	<link rel="stylesheet" type="text/css" href="./easyui.css">
	<link rel="stylesheet" type="text/css" href="./icon.css">
	<link rel="stylesheet" type="text/css" href="./demo.css">
	<script type="text/javascript" src="./jquery.min.js"></script>
	<script type="text/javascript" src="./jquery.easyui.min.js"></script>
	<script type="text/javascript" src="./group_view.js"></script>
	<style>
		.datagrid-group {
		    height: 28px;
		    overflow: hidden;
		    font-weight: bold;
		    border-bottom: 1px solid #ccc;
		    white-space: nowrap;
		    word-break: normal;
		    background-color: pink;
		}	
	</style>
	<script>
		$(function(){
			$('#tt').datagrid({
			    title:'DataGrid - GroupView',
			    width:500,
			    height:600,
			    rownumbers:true,
			    remoteSort:false,
			    nowrap:false,
			    fitColumns:true,
			    scrollbarSize:0,
			    url:'http://localhost:8080/easy',
			    columns:[[
			        {field:'name',title:'Product ID',width:400,sortable:true},
			        {field:'value',title:'List Price',width:100,align:'right',sortable:true}
			    ]],
			    groupField:'group',
			    view: groupview,
			    pagination:true,
			    groupFormatter:function(value, rows){
			    		var count = 0;
			    		rows.forEach(item => {
			    			if(item != null){
			    					count += parseInt(item.value);
			    			}	
			    		});
			    	  var html = "<table width='500px'><tr>";
			    	  html += "<th width='400px' style='align:left;'>Total</th>" ;
			    	  html += "<th width='100px' style='align:right;'>"+ count +"</th>" ;
			    	  html += "</tr></table>";
			        return html;
			    },
			    groupStyler: function(value,rows){
						if (value == 'RP-LI-02'){
							return 'background-color:#6293BB;color:#fff;'; // return inline style
							// the function can return predefined css class and inline style
							// return {class:'r1', style:{'color:#fff'}};	
						}
					},
					onLoadSuccess:function(data){
						$("#tt").datagrid("collapseGroup");	
						//$('#tt').datagrid('collapseGroup');
						//collapseGroup&nbsp;折叠一个分组&nbsp;
					},
					onClickRow:function(rowIndex, rowData){
							console.log(JSON.stringify(rowData));
					}
			});
		});
			
	</script>
</head>

<body>
	<table id="tt"></table>
</body>
</html>

效果图:

2.1.3 数据格式

{"total":7,"rows":[
	{"name":"Name","value":"Bill Smith","group":"ID Settings","editor":"text"},
	{"name":"Address","value":"","group":"ID Settings","editor":"text"},
	{"name":"Age","value":"40","group":"ID Settings","editor":"numberbox"},
	{"name":"Birthday","value":"01/02/2012","group":"ID Settings","editor":"datebox"},
	{"name":"SSN","value":"123-456-7890","group":"ID Settings","editor":"text"},
	{"name":"Email","value":"bill@gmail.com","group":"Marketing Settings","editor":{
		"type":"validatebox",
		"options":{
			"validType":"email"
		}
	}},
	{"name":"FrequentBuyer","value":"false","group":"Marketing Settings","editor":{
		"type":"checkbox",
		"options":{
			"on":true,
			"off":false
		}
	}}
]}

3. 注意

group_view.js在我们下载的easyUI中是没有的,需要我们自己去下载,这里我将源码贴出来

$.extend($.fn.datagrid.defaults, {
	groupHeight: 28,
	expanderWidth: 30,
	groupSortOrder: null,	// 'asc','desc'
	groupStyler: function(value,rows){return ''},
	groupSorter: function(g1,g2){
		var a = g1.value;
		var b = g2.value;
		return a==b ? 0 : (a>b?1:-1);
	}
});

var groupview = $.extend({}, $.fn.datagrid.defaults.view, {
	render: function(target, container, frozen){
		var table = [];
		var groups = this.groups;
		for(var i=0; i<groups.length; i++){
			table.push(this.renderGroup.call(this, target, i, groups[i], frozen));
		}
		$(container).html(table.join(''));
	},
	
	renderGroup: function(target, groupIndex, group, frozen){
		var state = $.data(target, 'datagrid');
		var opts = state.options;
		var fields = $(target).datagrid('getColumnFields', frozen);
		var hasFrozen = opts.frozenColumns && opts.frozenColumns.length;

		if (frozen){
			if (!(opts.rownumbers || hasFrozen)){
				return '';
			}
		}
		
		var table = [];

		var css = opts.groupStyler.call(target, group.value, group.rows);
		var cs = parseCss(css, 'datagrid-group');
		table.push('<div group-index=' + groupIndex + ' ' + cs + '>');
		if ((frozen && (opts.rownumbers || opts.frozenColumns.length)) ||
				(!frozen && !(opts.rownumbers || opts.frozenColumns.length))){
			table.push('<span class="datagrid-group-expander">');
			table.push('<span class="datagrid-row-expander datagrid-row-collapse">&nbsp;</span>');
			table.push('</span>');
		}
		if ((frozen && hasFrozen) || (!frozen)){
			table.push('<span class="datagrid-group-title">');
			table.push(opts.groupFormatter.call(target, group.value, group.rows));
			table.push('</span>');
		}
		table.push('</div>');

		var groupRows = $.extend([], group.rows);
		if (opts.groupFooter){
			var footerRow = opts.groupFooter.call(target, group.value, group.rows);
			if (footerRow){
				footerRow._group_footer = true;
				groupRows.push(footerRow);
			}
		}
		
		table.push('<table class="datagrid-btable" cellspacing="0" cellpadding="0" border="0"><tbody>');
		var index = group.startIndex;
		for(var j=0; j<groupRows.length; j++) {
			var css = opts.rowStyler ? opts.rowStyler.call(target, index, groupRows[j]) : '';
			var classValue = '';
			var styleValue = '';
			if (typeof css == 'string'){
				styleValue = css;
			} else if (css){
				classValue = css['class'] || '';
				styleValue = css['style'] || '';
			}
			
			var cls = 'class="datagrid-row ' + (index % 2 && opts.striped ? 'datagrid-row-alt ' : ' ') + classValue + '"';
			if (groupRows[j]._group_footer){
				cls = 'class="datagrid-group-footer"';
				styleValue = 'height:'+(opts.editorHeight+1)+'px';
			}
			var style = styleValue ? 'style="' + styleValue + '"' : '';
			var rowId = state.rowIdPrefix + '-' + (frozen?1:2) + '-' + index;
			table.push('<tr id="' + rowId + '" datagrid-row-index="' + index + '" ' + cls + ' ' + style + '>');
			table.push(this.renderRow.call(this, target, fields, frozen, index, groupRows[j]));
			table.push('</tr>');
			index++;
		}
		table.push('</tbody></table>');
		return table.join('');

		function parseCss(css, cls){
			var classValue = '';
			var styleValue = '';
			if (typeof css == 'string'){
				styleValue = css;
			} else if (css){
				classValue = css['class'] || '';
				styleValue = css['style'] || '';
			}
			return 'class="' + cls + (classValue ? ' '+classValue : '') + '" ' +
					'style="' + styleValue + '"';
		}
	},
	
	bindEvents: function(target){
		var state = $.data(target, 'datagrid');
		var dc = state.dc;
		var body = dc.body1.add(dc.body2);
		var clickHandler = ($.data(body[0],'events')||$._data(body[0],'events')).click[0].handler;
		body.unbind('click').bind('click', function(e){
			var tt = $(e.target);
			var expander = tt.closest('span.datagrid-row-expander');
			if (expander.length){
				var gindex = expander.closest('div.datagrid-group').attr('group-index');
				if (expander.hasClass('datagrid-row-collapse')){
					$(target).datagrid('collapseGroup', gindex);
				} else {
					$(target).datagrid('expandGroup', gindex);
				}
			} else {
				clickHandler(e);
			}
			// e.stopPropagation();
		});
	},
	
	onBeforeRender: function(target, rows){
		var state = $.data(target, 'datagrid');
		var opts = state.options;
		
		initCss();
		
		var groups = [];
		for(var i=0; i<rows.length; i++){
			var row = rows[i];
			var group = getGroup(row[opts.groupField]);
			if (!group){
				group = {
					value: row[opts.groupField],
					rows: [row]
				};
				groups.push(group);
			} else {
				group.rows.push(row);
			}
		}
		if (opts.groupSortOrder){
			groups.sort(function(a, b){
				var r = opts.groupSorter.call(target, a, b);
				return r * (opts.groupSortOrder=='asc'?1:-1);
			});
		}
		
		
		var index = 0;
		var newRows = [];
		for(var i=0; i<groups.length; i++){
			var group = groups[i];
			group.startIndex = index;
			index += group.rows.length;
			newRows = newRows.concat(group.rows);
		}

		state.data.rows = newRows;
		this.groups = groups;
		
		var that = this;
		setTimeout(function(){
			that.bindEvents(target);
		},0);
		
		function getGroup(value){
			for(var i=0; i<groups.length; i++){
				var group = groups[i];
				if (group.value == value){
					return group;
				}
			}
			return null;
		}
		function initCss(){
			if (!$('#datagrid-group-style').length){
				$('head').append(
					'<style id="datagrid-group-style">' +
					'.datagrid-group{height:'+opts.groupHeight+'px;overflow:hidden;font-weight:bold;border-bottom:1px solid #ccc;white-space:nowrap;word-break:normal;}' +
					'.datagrid-group-title,.datagrid-group-expander{display:inline-block;vertical-align:bottom;height:100%;line-height:'+opts.groupHeight+'px;padding:0 4px;}' +
					'.datagrid-group-title{position:relative;}' +
					'.datagrid-group-expander{width:'+opts.expanderWidth+'px;text-align:center;padding:0}' +
					'.datagrid-row-expander{margin:'+Math.floor((opts.groupHeight-16)/2)+'px 0;display:inline-block;width:16px;height:16px;cursor:pointer}' +
					'.datagrid-group-footer .datagrid-cell-rownumber{display:none}' +
					'</style>'
				);
			}
		}
	},
	onAfterRender: function(target){
		$.fn.datagrid.defaults.view.onAfterRender.call(this, target);

		var view = this;
		var state = $.data(target, 'datagrid');
		var opts = state.options;
		if (!state.onResizeColumn){
			state.onResizeColumn = opts.onResizeColumn;
		}
		if (!state.onResize){
			state.onResize = opts.onResize;
		}
		opts.onResizeColumn = function(field, width){
			view.resizeGroup(target);
			state.onResizeColumn.call(target, field, width);
		}
		opts.onResize = function(width, height){
			view.resizeGroup(target);		
			state.onResize.call($(target).datagrid('getPanel')[0], width, height);
		}
		view.resizeGroup(target);
	}
});

$.extend($.fn.datagrid.methods, {
	groups:function(jq){
		return jq.datagrid('options').view.groups;
	},
    expandGroup:function(jq, groupIndex){
        return jq.each(function(){
        	var opts = $(this).datagrid('options');
            var view = $.data(this, 'datagrid').dc.view;
            var group = view.find(groupIndex!=undefined ? 'div.datagrid-group[group-index="'+groupIndex+'"]' : 'div.datagrid-group');
            var expander = group.find('span.datagrid-row-expander');
            if (expander.hasClass('datagrid-row-expand')){
                expander.removeClass('datagrid-row-expand').addClass('datagrid-row-collapse');
                group.next('table').show();
            }
            $(this).datagrid('fixRowHeight');
            if (opts.onExpandGroup){
            	opts.onExpandGroup.call(this, groupIndex);
            }
        });
    },
    collapseGroup:function(jq, groupIndex){
        return jq.each(function(){
        	var opts = $(this).datagrid('options');
            var view = $.data(this, 'datagrid').dc.view;
            var group = view.find(groupIndex!=undefined ? 'div.datagrid-group[group-index="'+groupIndex+'"]' : 'div.datagrid-group');
            var expander = group.find('span.datagrid-row-expander');
            if (expander.hasClass('datagrid-row-collapse')){
                expander.removeClass('datagrid-row-collapse').addClass('datagrid-row-expand');
                group.next('table').hide();
            }
            $(this).datagrid('fixRowHeight');
            if (opts.onCollapseGroup){
            	opts.onCollapseGroup.call(this, groupIndex);
            }
        });
    },
    scrollToGroup: function(jq, groupIndex){
    	return jq.each(function(){
			var state = $.data(this, 'datagrid');
			var dc = state.dc;
			var grow = dc.body2.children('div.datagrid-group[group-index="'+groupIndex+'"]');
			if (grow.length){
				var groupHeight = grow.outerHeight();
				var headerHeight = dc.view2.children('div.datagrid-header')._outerHeight();
				var frozenHeight = dc.body2.outerHeight(true) - dc.body2.outerHeight();
				var top = grow.position().top - headerHeight - frozenHeight;
				if (top < 0){
					dc.body2.scrollTop(dc.body2.scrollTop() + top);
				} else if (top + groupHeight > dc.body2.height() - 18){
					dc.body2.scrollTop(dc.body2.scrollTop() + top + groupHeight - dc.body2.height() + 18);
				}
			}
    	});
    },
    refreshGroupTitle: function(jq, groupIndex){
    	return jq.each(function(){
    		var opts = $(this).datagrid('options');
    		opts.view.refreshGroupTitle(this, groupIndex)
    	})
    }
});

$.extend(groupview, {
	refreshGroupTitle: function(target, groupIndex){
		var state = $.data(target, 'datagrid');
		var opts = state.options;
		var dc = state.dc;
		var group = this.groups[groupIndex];
		var span = dc.body1.add(dc.body2).children('div.datagrid-group[group-index=' + groupIndex + ']').find('span.datagrid-group-title');
		span.html(opts.groupFormatter.call(target, group.value, group.rows));
	},
	resizeGroup: function(target, groupIndex){
		var state = $.data(target, 'datagrid');
		var dc = state.dc;
		var ht = dc.header2.find('table');
		var fr = ht.find('tr.datagrid-filter-row');
		// var fr = ht.find('tr.datagrid-filter-row').hide();
		// var ww = ht.width();
		var ww = dc.body2.children('table.datagrid-btable:first').width();
		if (groupIndex == undefined){
			var groupHeader = dc.body2.children('div.datagrid-group');
		} else {
			var groupHeader = dc.body2.children('div.datagrid-group[group-index=' + groupIndex + ']');
		}
		groupHeader._outerWidth(ww);
		var opts = state.options;
		if (opts.frozenColumns && opts.frozenColumns.length){
			var width = dc.view1.width() - opts.expanderWidth;
			var isRtl = dc.view1.css('direction').toLowerCase()=='rtl';
			groupHeader.find('.datagrid-group-title').css(isRtl?'right':'left', -width+'px');
		}
		if (fr.length){
			if (opts.showFilterBar){
				fr.show();
			}
		}
		// fr.show();
	},

	insertRow: function(target, index, row){
		var state = $.data(target, 'datagrid');
		var opts = state.options;
		var dc = state.dc;
		var group = null;
		var groupIndex;
		
		if (!state.data.rows.length){
			$(target).datagrid('loadData', [row]);
			return;
		}
		
		for(var i=0; i<this.groups.length; i++){
			if (this.groups[i].value == row[opts.groupField]){
				group = this.groups[i];
				groupIndex = i;
				break;
			}
		}
		if (group){
			if (index == undefined || index == null){
				index = state.data.rows.length;
			}
			if (index < group.startIndex){
				index = group.startIndex;
			} else if (index > group.startIndex + group.rows.length){
				index = group.startIndex + group.rows.length;
			}
			$.fn.datagrid.defaults.view.insertRow.call(this, target, index, row);
			
			if (index >= group.startIndex + group.rows.length){
				_moveTr(index, true);
				_moveTr(index, false);
			}
			group.rows.splice(index - group.startIndex, 0, row);
		} else {
			group = {
				value: row[opts.groupField],
				rows: [row],
				startIndex: state.data.rows.length
			}
			groupIndex = this.groups.length;
			dc.body1.append(this.renderGroup.call(this, target, groupIndex, group, true));
			dc.body2.append(this.renderGroup.call(this, target, groupIndex, group, false));
			this.groups.push(group);
			state.data.rows.push(row);
		}

		this.setGroupIndex(target);
		this.refreshGroupTitle(target, groupIndex);
		this.resizeGroup(target);
		
		function _moveTr(index,frozen){
			var serno = frozen?1:2;
			var prevTr = opts.finder.getTr(target, index-1, 'body', serno);
			var tr = opts.finder.getTr(target, index, 'body', serno);
			tr.insertAfter(prevTr);
		}
	},
	
	updateRow: function(target, index, row){
		var opts = $.data(target, 'datagrid').options;
		$.fn.datagrid.defaults.view.updateRow.call(this, target, index, row);
		var tb = opts.finder.getTr(target, index, 'body', 2).closest('table.datagrid-btable');
		var groupIndex = parseInt(tb.prev().attr('group-index'));
		this.refreshGroupTitle(target, groupIndex);
	},
	
	deleteRow: function(target, index){
		var state = $.data(target, 'datagrid');
		var opts = state.options;
		var dc = state.dc;
		var body = dc.body1.add(dc.body2);
		
		var tb = opts.finder.getTr(target, index, 'body', 2).closest('table.datagrid-btable');
		var groupIndex = parseInt(tb.prev().attr('group-index'));
		
		$.fn.datagrid.defaults.view.deleteRow.call(this, target, index);
		
		var group = this.groups[groupIndex];
		if (group.rows.length > 1){
			group.rows.splice(index-group.startIndex, 1);
			this.refreshGroupTitle(target, groupIndex);
		} else {
			body.children('div.datagrid-group[group-index='+groupIndex+']').remove();
			for(var i=groupIndex+1; i<this.groups.length; i++){
				body.children('div.datagrid-group[group-index='+i+']').attr('group-index', i-1);
			}
			this.groups.splice(groupIndex, 1);
		}
		
		this.setGroupIndex(target);
	},

	setGroupIndex: function(target){
		var index = 0;
		for(var i=0; i<this.groups.length; i++){
			var group = this.groups[i];
			group.startIndex = index;
			index += group.rows.length;
		}
	}
});

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值