DataViews supports using the group footer as the group summary row.
Set the location option in the group footer settings to top or bottom to show the footer at the top or bottom.
In this demo, the group footer is at the top, and it adds together the data in each column in that group.
This also works with subgroups, and shows above the rows in the group when the group is expanded.
Try changing the footer location with the drop down menu above the grid and see how it changes the position when the groups are expanded.
<!DOCTYPE html>
<html lang="en">
<head>
<base href="/dataviewsjs/demos/en/sample/Features/Grouping/FooterLocation/purejs/" />
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="keywords" content="grouping, footer, location, top" />
<meta name="description" content="DataViews supports using the group footer as the group summary row." />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Footer Location | Features | MESCIUS DataViewsJS JavaScript Demos</title>
<link href="/dataviewsjs/demos/node_modules/normalize.css/normalize.css" rel="stylesheet" type="text/css" />
<link href="/dataviewsjs/demos/static/css/base.css" rel="stylesheet" type="text/css" />
<link href="/dataviewsjs/demos/static/dataviews/gc.dataviews.core.min.css" rel="stylesheet" type="text/css" />
<link href="/dataviewsjs/demos/static/dataviews/gc.dataviews.grid.min.css" rel="stylesheet" type="text/css" />
<link href="styles.css" rel="stylesheet" type="text/css" />
<script src="/dataviewsjs/demos/static/js/app-polyfills.min.js" type="text/javascript"></script>
<script type="text/javascript">
window.process = {
env: {
NODE_ENV: 'production',
USE_NPM: false,
USE_CDN: false,
SITE_ROOT: '/dataviewsjs/demos',
FRAMEWORK: 'purejs',
DVJS_LICENSE_KEY:
'E348418822993781#B0EWvwY4dNNVQqJHUDpFROVWe5ZWNYFlVQFmRsJWRht4Z6lDO4Vla7YUaXhEWxd7Z5YXMuRnY7tWTQRHSlVnaYlXNhlEOpdkZ0FHWYJ5QKd6VXN5aR3ieGhUav9kZTBXWahkYBhEVutmZ72CbjdlZvV5TVdGdiplQsZXe95kUmNmZVF5cJ3mcypWNyx4UydESE3UblxGZyE7KQ94R4BjbUxUewsiaoREMxRDNllWREV6Voh4Q4dDZPRjWrIzUJl4TERXcQZWMHp4Sp9WaMZzN5o6StJmVDJXcwIVVmR6UMVGOlxUW8RmTxZDZTJWVN5GZqJHZuVDMkVGSW3WdxNzKCdDdSB7TzY7cqlnMU5GVyNzNP9WMyhDRvEEOFdkQORDM4dFVlFFWqFWSyMjNQJiOiMlIsISQyIkQ9YjQxIiOigkIsUTM7YjNxYTM0IicfJye&Qf35VfikFVVljI0IyQiwiIxYHITp4c7VWaWFGdhRkI0IiTis7W0ICZyBlIsIiNxUTN6ADI8EDMxMjMwIjI0ICdyNkIsIyc59yc5l6YzVWbuoCLwpmLzVXajNXZt9iKs2WauMXdpN6cl5mLqwSbvNmLzVXajNXZt9iKsAnau26YuMXdpN6cl5mLqwSbvNmL6VGZ9RXajVGchJ7ZuoCLuNmLt36YukHdpNWZwFmcn9iKs46bj9Se4l6YlBXYydmLqwicr9ybj9Se4l6YlBXYydmLqwCcq9ybj9Se4l6YlBXYydmLqIiOiMXbEJCLiMVVJN4UF5kI0ISYONkIsUWdyRnOiwmdFJCLiEDO7MTO9IjM8gTM4gDNzIiOiQWSisnOiQkIsISP3EkVxBVUHFDMplzLlVUdGd7cI9UeIt4SshESzV7NvY7ZxlDOuNTb5tzLr',
SJS_LICENSE_KEY:
'E518585142165236#B0wm4nx4QzdlTHRTSOFzcvVnaJdjSnNEeXdTMUtSUzk6bU94QuVXNwZVZjd4SzYjcadXRIVEMzEXTThkVyR7R85UayoHZZBTYQ5mZyh4Shd6VxFXazF4cBNGRG5WTvUGTsV4T6knQYRzKxxUdk9EarplU7d6VLF6KIR7bPJ5N6ZUMWZWaURGRKRDbLJDN5YjSN5mUoxmaxonSD56LEh7Y7RXenpmTvomevZlV9dkaysCO7hTRQFHcGRWQyc5LI9kQmB7QwR4Z7ZHOR3CSXp6SiFWYzFXeXZUSp94K8VDTkFjdwl4KptSYlRWcDxmNE5kS6kzdrkVcNJXROVGbLJkcTNGRzIER8tmd4YGNhh7dxAnMvIHRv46VtBXS4U5KvJ6dZJ6M5p4TxIjd9I5QSpXTTV6SDZXb7lzaL56ZiojITJCLikTQxUTQFV4NiojIIJCLyETO7UzM7kTO0IicfJye&Qf35VfikkR9IkI0IyQiwiIyEjL6ByUKBCZhVmcwNlI0IiTis7W0ICZyBlIsISNwkTN6ADI8EDMxMjMwIjI0ICdyNkIsIyc59yc5l6YzVWbuoCLwpmLzVXajNXZt9iKs2WauMXdpN6cl5mLqwSbvNmLzVXajNXZt9iKsAnau26YuMXdpN6cl5mLqwSbvNmL6VGZ9RXajVGchJ7ZuoCLuNmLt36YukHdpNWZwFmcn9iKs46bj9Se4l6YlBXYydmLqwicr9ybj9Se4l6YlBXYydmLqwCcq9ybj9Se4l6YlBXYydmLqIiOiMXbEJCLiMVVJN4UF5kI0ISYONkIsUWdyRnOiwmdFJCLiYzMyUjNxIDNxUDO5gTM5IiOiQWSiwSfdtlOicGbmJCLlNHbhZmOiI7ckJye0ICbuFkI1pjIEJCLi4TPRtGOhtWWEFWd4IDOLRVRvx4SyMGcDhTW6n4ep',
},
};
</script>
<script src="/dataviewsjs/demos/node_modules/jquery/dist/jquery.min.js" type="text/javascript"></script>
<script src="/dataviewsjs/demos/static/dataviews/gc.dataviews.common.min.js" type="text/javascript"></script>
<script src="/dataviewsjs/demos/static/dataviews/gc.dataviews.core.min.js" type="text/javascript"></script>
<script src="/dataviewsjs/demos/static/dataviews/gc.dataviews.grid.min.js" type="text/javascript"></script>
<script src="/dataviewsjs/demos/static/js/license.js" type="text/javascript"></script>
</head>
<body class="theme-default">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div class="main-container">
<div class="sample-options">
<label>Footer location:</label>
<select id="footer-location">
<option value="top" selected>top</option>
<option value="bottom">bottom</option>
</select>
</div>
<div id="grid" class="grid"></div>
</div>
<script src="data.js" type="text/javascript"></script>
<script src="app.js" type="text/javascript"></script>
</body>
</html>
var cols = [
{
id: 'location',
caption: 'Location',
dataField: 'location',
allowCellMerging: true,
width: 120,
},
{
id: 'dept',
caption: 'Department',
dataField: 'dept',
allowCellMerging: true,
width: 120,
},
{
id: 'name',
caption: 'Employee',
dataField: 'name',
width: 90,
},
{
id: 'basic',
caption: 'Basic',
columns: [
{
id: 'BeLate',
caption: 'BeLate',
dataField: 'BeLate',
groupFooter: '{{=it.eval("=sum([BeLate])")}}',
width: 70,
},
{
id: 'LeaveEarly',
caption: 'LeaveEarly',
dataField: 'LeaveEarly',
groupFooter: '{{=it.eval("=sum([LeaveEarly])")}}',
width: 95,
},
{
id: 'Absent',
caption: 'Absent',
dataField: 'Absent',
groupFooter: '{{=it.eval("=sum([Absent])")}}',
width: 70,
},
{
id: 'Total',
caption: 'Total',
dataType: 'number',
dataField: '=[BeLate]+[LeaveEarly]+[Absent]',
groupFooter: '{{=it.eval("=sum([Total])")}}',
width: 55,
},
],
},
{
id: 'askForLeave',
caption: 'Ask For Leave',
columns: [
{
id: 'Leave',
caption: 'Leave',
dataField: 'Leave',
groupFooter: '{{=it.eval("=sum([Leave])")}}',
width: 65,
},
{
id: 'SickLeave',
caption: 'SickLeave',
dataField: 'SickLeave',
groupFooter: '{{=it.eval("=sum([SickLeave])")}}',
width: 90,
},
{
id: 'TotalLeave',
caption: 'TotalLeave',
dataType: 'number',
dataField: '=[Leave]+[SickLeave]',
groupFooter: '{{=it.eval("=sum([TotalLeave])")}}',
width: 95,
},
],
},
];
var topFooterLocation = [
{
field: 'location',
header: {
visible: false,
},
footer: {
location: 'top',
},
collapsed: true,
},
{
field: 'dept',
header: {
visible: false,
},
footer: {
location: 'top',
},
collapsed: true,
},
];
var bottomFooterLocation = [
{
field: 'location',
header: {
visible: false,
},
footer: {
location: 'bottom',
},
collapsed: true,
},
{
field: 'dept',
header: {
visible: false,
},
footer: {
location: 'bottom',
},
collapsed: true,
},
];
var layout = new GC.DataViews.GridLayout({
allowColumnReorder: false,
allowCellMerging: true,
cellMergingSettings: {
groupedColumn: {
onlyShowFirstRowValueInEachGroup: true,
showIcon: true,
},
},
grouping: topFooterLocation,
});
var dataView = new GC.DataViews.DataView(document.getElementById('grid'), data, cols, layout);
$('#footer-location').on('change', function () {
var sel = document.getElementById('footer-location');
var value = sel.options[sel.selectedIndex].value;
if (value === 'top') {
dataView.data.groupDescriptors = topFooterLocation;
} else {
dataView.data.groupDescriptors = bottomFooterLocation;
}
}); // focus data.view by default
document.getElementById('grid').focus();
var data = [
{
location: 'US District',
dept: 'Development',
name: 'Jack',
BeLate: 3,
LeaveEarly: 1,
Absent: 1,
Leave: 2,
SickLeave: 1,
},
{
location: 'US District',
dept: 'Development',
name: 'Tom',
BeLate: 0,
LeaveEarly: 1,
Absent: 1,
Leave: 1,
SickLeave: 1,
},
{
location: 'US District',
dept: 'Development',
name: 'Tim',
BeLate: 4,
LeaveEarly: 1,
Absent: 2,
Leave: 1,
SickLeave: 0,
},
{
location: 'US District',
dept: 'Development',
name: 'Paul',
BeLate: 1,
LeaveEarly: 1,
Absent: 1,
Leave: 1,
SickLeave: 0,
},
{
location: 'US District',
dept: 'Development',
name: 'Lucy',
BeLate: 5,
LeaveEarly: 1,
Absent: 1,
Leave: 1,
SickLeave: 0,
},
{
location: 'US District',
dept: 'Personnel',
name: 'Lily',
BeLate: 4,
LeaveEarly: 4,
Absent: 1,
Leave: 1,
SickLeave: 1,
},
{
location: 'US District',
dept: 'Personnel',
name: 'Jackson',
BeLate: 2,
LeaveEarly: 2,
Absent: 2,
Leave: 1,
SickLeave: 0,
},
{
location: 'US District',
dept: 'Personnel',
name: 'Robert',
BeLate: 1,
LeaveEarly: 1,
Absent: 1,
Leave: 1,
SickLeave: 0,
},
{
location: 'US District',
dept: 'Personnel',
name: 'John',
BeLate: 0,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 1,
},
{
location: 'US District',
dept: 'Sales',
name: 'Young',
BeLate: 3,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 1,
},
{
location: 'US District',
dept: 'Sales',
name: 'Rose',
BeLate: 1,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 1,
},
{
location: 'US District',
dept: 'Sales',
name: 'Ben',
BeLate: 0,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 0,
},
{
location: 'US District',
dept: 'Logistics',
name: 'Ailsa',
BeLate: 1,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 0,
},
{
location: 'US District',
dept: 'Logistics',
name: 'Selina',
BeLate: 0,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 0,
},
{
location: 'US District',
dept: 'Logistics',
name: 'Philip',
BeLate: 0,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 0,
},
{
location: 'China District',
dept: 'Development',
name: 'Jack',
BeLate: 3,
LeaveEarly: 1,
Absent: 1,
Leave: 2,
SickLeave: 1,
},
{
location: 'China District',
dept: 'Development',
name: 'Tom',
BeLate: 0,
LeaveEarly: 1,
Absent: 1,
Leave: 1,
SickLeave: 1,
},
{
location: 'China District',
dept: 'Development',
name: 'Tim',
BeLate: 4,
LeaveEarly: 1,
Absent: 2,
Leave: 1,
SickLeave: 0,
},
{
location: 'China District',
dept: 'Development',
name: 'Paul',
BeLate: 1,
LeaveEarly: 1,
Absent: 1,
Leave: 1,
SickLeave: 0,
},
{
location: 'China District',
dept: 'Development',
name: 'Lucy',
BeLate: 5,
LeaveEarly: 1,
Absent: 1,
Leave: 1,
SickLeave: 0,
},
{
location: 'China District',
dept: 'Personnel',
name: 'Lily',
BeLate: 4,
LeaveEarly: 4,
Absent: 1,
Leave: 1,
SickLeave: 1,
},
{
location: 'China District',
dept: 'Personnel',
name: 'Jackson',
BeLate: 2,
LeaveEarly: 2,
Absent: 2,
Leave: 1,
SickLeave: 0,
},
{
location: 'China District',
dept: 'Personnel',
name: 'Robert',
BeLate: 1,
LeaveEarly: 1,
Absent: 1,
Leave: 1,
SickLeave: 0,
},
{
location: 'China District',
dept: 'Personnel',
name: 'John',
BeLate: 0,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 1,
},
{
location: 'China District',
dept: 'Sales',
name: 'Young',
BeLate: 3,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 1,
},
{
location: 'China District',
dept: 'Sales',
name: 'Rose',
BeLate: 1,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 1,
},
{
location: 'China District',
dept: 'Sales',
name: 'Ben',
BeLate: 0,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 0,
},
{
location: 'China District',
dept: 'Logistics',
name: 'Ailsa',
BeLate: 1,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 0,
},
{
location: 'China District',
dept: 'Logistics',
name: 'Selina',
BeLate: 0,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 0,
},
{
location: 'China District',
dept: 'Logistics',
name: 'Philip',
BeLate: 0,
LeaveEarly: 0,
Absent: 0,
Leave: 1,
SickLeave: 0,
},
];
.main-container {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.sample-options {
background: #fbfbfb;
box-sizing: border-box;
overflow: auto;
padding: 10px;
flex-grow: 0;
flex-shrink: 0;
}
.sample-options label {
margin-right: 5px;
}
.grid {
height: calc(100% - 52px);
width: 100%;
flex-grow: 1;
flex-shrink: 1;
}
.gc-group-footer-cell {
background-color: transparent;
}
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkZlYXR1cmVzL0dyb3VwaW5nL0Zvb3RlckxvY2F0aW9uL3B1cmVqcy9zdHlsZXMuc2NzcyIsIkZlYXR1cmVzL0dyb3VwaW5nL0Zvb3RlckxvY2F0aW9uL3B1cmVqcy9zdHlsZXMuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0VBQ0UsYUFBQTtFQUNBLHNCQUFBO0VBQ0EsV0FBQTtFQUNBLFlBQUE7QUNDRjs7QURFQTtFQUNFLG1CQUFBO0VBQ0Esc0JBQUE7RUFDQSxjQUFBO0VBQ0EsYUFBQTtFQUNBLFlBQUE7RUFDQSxjQUFBO0FDQ0Y7QURDRTtFQUNFLGlCQUFBO0FDQ0o7O0FER0E7RUFDRSx5QkFBQTtFQUNBLFdBQUE7RUFDQSxZQUFBO0VBQ0EsY0FBQTtBQ0FGOztBREdBO0VBQ0UsNkJBQUE7QUNBRiIsImZpbGUiOiJGZWF0dXJlcy9Hcm91cGluZy9Gb290ZXJMb2NhdGlvbi9wdXJlanMvc3R5bGVzLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi5tYWluLWNvbnRhaW5lciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG59XG5cbi5zYW1wbGUtb3B0aW9ucyB7XG4gIGJhY2tncm91bmQ6ICNmYmZiZmI7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gIG92ZXJmbG93OiBhdXRvO1xuICBwYWRkaW5nOiAxMHB4O1xuICBmbGV4LWdyb3c6IDA7XG4gIGZsZXgtc2hyaW5rOiAwO1xuXG4gIGxhYmVsIHtcbiAgICBtYXJnaW4tcmlnaHQ6IDVweDtcbiAgfVxufVxuXG4uZ3JpZCB7XG4gIGhlaWdodDogY2FsYygxMDAlIC0gNTJweCk7XG4gIHdpZHRoOiAxMDAlO1xuICBmbGV4LWdyb3c6IDE7XG4gIGZsZXgtc2hyaW5rOiAxO1xufVxuXG4uZ2MtZ3JvdXAtZm9vdGVyLWNlbGwge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB0cmFuc3BhcmVudDtcbn1cbiIsIi5tYWluLWNvbnRhaW5lciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gIHdpZHRoOiAxMDAlO1xuICBoZWlnaHQ6IDEwMCU7XG59XG5cbi5zYW1wbGUtb3B0aW9ucyB7XG4gIGJhY2tncm91bmQ6ICNmYmZiZmI7XG4gIGJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gIG92ZXJmbG93OiBhdXRvO1xuICBwYWRkaW5nOiAxMHB4O1xuICBmbGV4LWdyb3c6IDA7XG4gIGZsZXgtc2hyaW5rOiAwO1xufVxuLnNhbXBsZS1vcHRpb25zIGxhYmVsIHtcbiAgbWFyZ2luLXJpZ2h0OiA1cHg7XG59XG5cbi5ncmlkIHtcbiAgaGVpZ2h0OiBjYWxjKDEwMCUgLSA1MnB4KTtcbiAgd2lkdGg6IDEwMCU7XG4gIGZsZXgtZ3JvdzogMTtcbiAgZmxleC1zaHJpbms6IDE7XG59XG5cbi5nYy1ncm91cC1mb290ZXItY2VsbCB7XG4gIGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50O1xufSJdfQ== */