jqGrid 表格分组 grouping 使用汇总 动态展开收起分组 新增、删除、编辑行自动更新分组统计

凌炜
2023-12-01

  jqGrid表格自带group分组功能,包括表头Header分组和表格内容分组功能,本文讨论表格行如何实现分组统计;表格行新增、删除时如何自动更新分组统计;表格行汇总列单元格编辑室如何更新分组统计。

1、jqGrid grouping使用说明(用户手册)

1)启用分组

启用分组,包含2部分内容:

  • 设置grouping: true,配置groupingView(分组字段、排序规则、是否显示分组列、是否显示合计行groupSummary,默认展开还是收起等)
jQuery("#grid").jqGrid({
  grouping: true,
  groupingView : {
     groupField : ['name', 'invdate'],
     groupOrder : ['asc', 'desc']
  }
  ...
});
  • 设置colModel,合计类型summaryType
{name:'amount', formatter:'number', summaryType:'sum'},
2)grouping 相关选项、参数说明
PropertyTypeDescriptionDefault
groupFieldarray数组,分组字段,2个字段则2层分组,第1字段为第1层分组,第2字段为第二层分组empty
groupOrderarray数组,分组排序规则,[‘asc’, ‘desc’]表示第1分组升序,第二分组降序empty
groupTextarray数组,分组标题显示文本,如:[’{0}, 共{1}’],{0}表示分组字段值,{1}表示分组统计值。empty
groupColumnShowarrayShow/Hide the column on which we group. The value here should be a boolean true/false for the group level. If the grouping is enabled we set this value to true.empty
groupSummaryarrayEnable or disable the summary (footer) row of the current group level. If grouping is set the default value for the group is false.empty
groupSummaryPosarraySet the position of the summary row at current group level. Possible values - header or footer. If set to header the summary values are placed at the same row where the group values is. If footer is set additional row at end of the group level is build-ed and the summary values are placed herefooter
hideFirstGroupColbooleanIf set to true the values at first column are replaced with empty ones so that we have a pretty view. This usually is set ih the first column is a group columnfalse
showSummaryOnHidebooleanShow or hide the summary (footer) row when we collapse the group.false
groupCollapsebooleanDefines if the initially the grid should show or hide the detailed rows of the group.false
plusiconstringSet the icon from jQuery UI Theme Roller or Bootstrap that will be used if the grouped row is collapsed. The default is get from styleUI object property grouping for the CSS framework used
minusiconstringSet the icon from jQuery UI Theme Roller or Bootstrap that will be used if the grouped row is expanded. The default is get from styleUI object property grouping for the CSS framework used
isInTheSameGrouparrayThe elements of the array correspond to the number of the groups. Every element of this array is a function which should return true or false. In case if it return false the element will be added in the new group. Parameters passed to this function are : previous value, current value, group index, group objectnull
formatDisplayFieldarrayThe elements of the array correspond to the number of the groups. Every element of this array is a function which should return a value, which will be display the grouped value. Parameters passed to this function are: current value, source value, colModel option, group index and group object.null

支持的合计类型:summaryType

  • sum - apply the sum function to the current group value and return the result
  • count - apply the count function to the current group value and return the result
  • avg - apply the average function to the current group value and return the result
  • min - apply the min function to the current group value and return the result
  • max - apply the max function to the current group value and return the result
  • function - use custom function for calculations.
3)grouping 相关 方法
  • groupingToggle(string groupid)
    展开、收起指定分组

  • 动态定义分组 groupingGroupBy(mixed name, [object options])
    Perform a grouping by given name. The previous grouping is destroyed and new one is applied. A set of additional options can be set with the option parameter. The groupingView object is extended with the options parameter.
    可用此方法实现分组全部展开或收起。

2、Grouping Demo说明

1)html源码
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8" />
	<title>jgGrid-Group</title>
	<link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
	<link rel="stylesheet" href="https://cdn.bootcss.com/font-awesome/4.5.0/css/font-awesome.min.css" />
	<link rel="stylesheet" href="https://cdn.bootcss.com/jqueryui/1.11.0/jquery-ui.min.css" />
	<link rel="stylesheet" href="https://js.cybozu.cn/jqgrid/v5.3.1/css/ui.jqgrid.css" />
	<script src="https://cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
	<script src="https://js.cybozu.cn/jqgrid/v5.3.1/js/jquery.jqGrid.min.js"></script>
	<script src="https://js.cybozu.cn/jqgrid/v5.3.1/js/i18n/grid.locale-en.js"></script>
</head>
<body>
<div class="page-content container">
	<div class="page-body"> <!-- page-body -->
		<div class="panel panel-default" id="panel-orders">
			<div class="panel-heading">
				<h3 class="panel-title">jgGrid-Group 新增、删除行重新汇总计算
					<button type="button" class='btn btn-sm btn-default' onclick='addRow()'>新增车型2</button>
					<button type="button" class='btn btn-sm btn-default' onclick='doExpand()'>展开所有行</button>
					<button type="button" class='btn btn-sm btn-default' onclick='doCollapse()'>收起所有行</button></h3>
			</div>
			<table id="orders"></table>
		</div>
	</div>
</div>
<script type="text/javascript">
	var data = [], rowIds = [], goods_count = 0, out_count = 0;
	function getBills() {
		var rowCount = 10;
		for (var i = 0; i < rowCount; i ++) {
			data.push({
				id: i + 10,
				car_type: '车型' + ((i % 5) + 1),
				goods_id: i,
				goods_no: i + 1,
				goods_name: '零件名称' + rowCount + i,
				package_name: '包装器具' + rowCount + i,
				unit_name: '单位',
				snp: 0.89,
				box_count: rowCount + i,
				total_count: rowCount + i,
				goods_count: rowCount + i,
				out_count: rowCount + i,
				bill_no: 'BN0000000' + i,
				barcode: '1000000000' + i,
				flag:  i >= rowCount - 1 ? 1 : 0,
			})
		}
		$("#orders").jqGrid("clearGridData").jqGrid('setGridParam',{data: data || []}).trigger('reloadGrid');
	}
    function setSum(rowId, colName, countDiff) {
        var $tr = $('#' + rowId).nextAll('.jqfoot').first(), 
            $count = $tr.find('td[aria-describedby="orders_{0}"]'.replace('{0}', colName));
        $count.text(parseFloat($count.text()) + parseFloat(countDiff));
    }
    function oprRender(data, options, row) {
    	return "<button type='button' class='btn btn-primary btn-xs' οnclick='delRow(this)'>删除</button>"
    }
    function delRow(obj) {
    	var rowId = $(obj).closest('tr').attr('id');
    	if (confirm('确定要删除该行吗?')) {
    		$("#orders").jqGrid('delRowData', rowId);
    		$("#orders").jqGrid().trigger('reloadGrid');
    	}
    }
    function addRow() {
    	var row = {id: $.jgrid.randId(), car_type: "车型2", goods_no: '12003', goods_name: "12003", goods_count: 9, out_count: 8}
    	$("#orders").jqGrid('addRowData', row.id, row);
    	$("#orders").jqGrid().trigger('reloadGrid');
    }
    function doExpand() {
    	$("#orders").jqGrid('groupingGroupBy', 'car_type', {groupCollapse: false});
    }
    function doCollapse() {
    	$("#orders").jqGrid('groupingGroupBy', 'car_type', {groupCollapse: true});
    }
	$(function() {
		$("#orders").jqGrid({
			colModel: [
				{label: "车型", name: "id", width: 70, hidden:true},
				{label: "车型", name: "car_type", width: 70},
				{label: "零件号", name: "goods_no", width: 60},
				{label: "零件名称", name: "goods_name", width: 180},
				{label: "包装器具", name: "package_name", width: 70},
				{label: "单位", name: "unit_name", width: 40},
				{label: "装箱率", name: "snp", width: 50, sorttype: "number"},
				{label: "箱数", name: "box_count", width: 40, sorttype: "number"},
				{label: "需求数量", name: "goods_count", width: 70, summaryType: 'sum', editable: true, editrules:{rquired: true, number: true}},
				{label: "出库数量", name: "out_count", width: 70, sorttype: "number", summaryType: 'sum', editable: true, editrules:{rquired: true, number: true}},
				{label: "订单号", name: "bill_no", width: 120},
				{label: "操作", name: "oprRender", width: 120, formatter: oprRender}
			],
			datatype: 'local',
			rownumbers: true,
			height: 300,
			grouping: true,
	        groupingView: {
	            groupField: ["car_type",],
	            groupColumnShow: [false],
	            groupText: ["<b style='display: inline-block;width: 130px;'>{0}</b>"],
	            groupOrder: ["asc"],
	            groupSummary: [true],
	            groupCollapse: false
	        },
            beforeEditCell: function(rowId, cellname, value, iRow, iCol) {
                if (cellname == "goods_count") {
                	goods_count = value;
                } else if (cellname == "out_count") {
                	out_count = value;
                }
            },
	       	afterSaveCell: function(rowId, cellname, value, iRow, iCol) {
				if (cellname == "goods_count") {
					setSum(rowId, "goods_count", value - goods_count);
				} else if (cellname == "out_count") {
                    setSum(rowId, "out_count", value - out_count);
                }
	        },
			cellEdit: true,
			cellsubmit: 'clientArray'
		});
		getBills();
	});
</script>
</body>
</html>
2)代码说明
  • 新增行、删除行后都调用了jqGrid().trigger(‘reloadGrid’),否则不会重新进行合计汇总;
  • 修改单元格值时

先用beforeEditCell记录了单元格原值
后用afterSaveCell获取新值,比计算新旧值的差值, count_diff
调用setSum方法更新汇总统计行的统计值,新统计值 = 原统计值 + count_diff

  • 调用groupingGroupBy实现展开、收起分组
  • 为了避免删除行,调用jqGrid().trigger(‘reloadGrid’)后可能导致reload数据与删除行后的表格内容不一致问题,表格行数据都包含id属性且唯一。
 类似资料: