<dx-data-grid
id="gridContainer"
[dataSource]="orders"
keyExpr="ID"
[showBorders]="true"
>
<dxo-data-grid-grouping [autoExpandAll]="expandAll"></dxo-data-grid-grouping>
<dxo-data-grid-column-chooser [enabled]="true"></dxo-data-grid-column-chooser>
<dxo-data-grid-load-panel [enabled]="true"></dxo-data-grid-load-panel>
<dxi-data-grid-column
dataField="OrderNumber"
caption="Invoice Number"
></dxi-data-grid-column>
<dxi-data-grid-column dataField="OrderDate"></dxi-data-grid-column>
<dxi-data-grid-column dataField="Employee"></dxi-data-grid-column>
<dxi-data-grid-column
dataField="CustomerStoreCity"
caption="City"
></dxi-data-grid-column>
<dxi-data-grid-column
dataField="CustomerStoreState"
caption="State"
[groupIndex]="0"
></dxi-data-grid-column>
<dxi-data-grid-column
dataField="SaleAmount"
alignment="right"
format="currency"
></dxi-data-grid-column>
<dxo-data-grid-toolbar>
<dxi-data-grid-item location="before">
<div *dxTemplate class="informer">
<div class="count">{{ totalCount }}</div>
<span>Total Count</span>
</div>
</dxi-data-grid-item>
<dxi-data-grid-item location="before" locateInMenu="auto">
<div *dxTemplate>
<dx-select-box
width="225"
[items]="groupingValues"
[inputAttr]="{ 'aria-label': 'Value' }"
displayExpr="text"
valueExpr="value"
value="CustomerStoreState"
(onValueChanged)="toggleGroupColumn($event)"
>
</dx-select-box>
</div>
</dxi-data-grid-item>
<dxi-data-grid-item
location="before"
locateInMenu="auto"
widget="dxButton"
[options]="toggleButtonOptions"
>
</dxi-data-grid-item>
<dxi-data-grid-item
location="after"
locateInMenu="auto"
showText="inMenu"
widget="dxButton"
[options]="refreshButtonOptions"
>
</dxi-data-grid-item>
<dxi-data-grid-item name="columnChooserButton"></dxi-data-grid-item>
</dxo-data-grid-toolbar>
</dx-data-grid>
import { bootstrapApplication } from '@angular/platform-browser';
import {
ChangeDetectorRef, Component, ViewChild, enableProdMode, provideZoneChangeDetection,
} from '@angular/core';
import {
DxDataGridModule,
DxDataGridComponent,
} from 'devextreme-angular';
import { DxButtonTypes } from 'devextreme-angular/ui/button';
import { query } from 'devextreme-angular/common/data';
import { DxSelectBoxModule, DxSelectBoxTypes } from 'devextreme-angular/ui/select-box';
import { Service, Order } from './app.service';
if (!/localhost/.test(document.location.host)) {
enableProdMode();
}
@Component({
selector: 'demo-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [Service],
imports: [
DxDataGridModule,
DxSelectBoxModule,
],
})
export class AppComponent {
@ViewChild(DxDataGridComponent, { static: false }) dataGrid: DxDataGridComponent;
orders: Order[];
totalCount: number;
expandAll = true;
groupingValues = [{
value: 'CustomerStoreState',
text: 'Grouping by State',
}, {
value: 'Employee',
text: 'Grouping by Employee',
}];
refreshButtonOptions: DxButtonTypes.Properties = {
icon: 'refresh',
text: 'Refresh',
onClick: () => {
this.dataGrid.instance.refresh();
},
};
toggleButtonOptions: DxButtonTypes.Properties = {
text: this.expandAll ? 'Collapse All' : 'Expand All',
width: 136,
onClick: () => {
this.toggleExpandAll();
this.toggleButtonOptions = {
...this.toggleButtonOptions,
text: this.expandAll ? 'Collapse All' : 'Expand All',
};
this.changeDetectorRef.detectChanges();
},
};
constructor(service: Service, private changeDetectorRef: ChangeDetectorRef) {
this.orders = service.getOrders();
this.totalCount = this.getGroupCount('CustomerStoreState');
}
getGroupCount(groupField: string) {
return query(this.orders)
.groupBy(groupField)
.toArray().length;
}
toggleGroupColumn(e: DxSelectBoxTypes.ValueChangedEvent) {
this.dataGrid.instance.clearGrouping();
this.dataGrid.instance.columnOption(e.value, 'groupIndex', 0);
this.totalCount = this.getGroupCount(e.value);
}
toggleExpandAll() {
this.expandAll = !this.expandAll;
}
}
bootstrapApplication(AppComponent, {
providers: [
provideZoneChangeDetection({ eventCoalescing: true, runCoalescing: true }),
],
});
::ng-deep #gridContainer .informer {
display: grid;
width: 120px;
grid-template-columns: 100%;
padding-right: 20px;
text-align: center;
}
::ng-deep #gridContainer .count {
font-size: 18px;
font-weight: 500;
}
::ng-deep #gridContainer .dx-toolbar-items-container {
min-height: 44px;
}
import { Injectable } from '@angular/core';
export class Order {
ID: number;
OrderNumber: number;
OrderDate: Date;
SaleAmount: number;
Terms: string;
TotalAmount: number;
CustomerStoreState: string;
CustomerStoreCity: string;
Employee: string;
}
const orders: Order[] = [{
ID: 1,
OrderNumber: 35703,
OrderDate: new Date(2024, 3, 10),
SaleAmount: 11800,
Terms: '15 Days',
TotalAmount: 12175,
CustomerStoreState: 'California',
CustomerStoreCity: 'Los Angeles',
Employee: 'Harv Mudd',
}, {
ID: 4,
OrderNumber: 35711,
OrderDate: new Date(2024, 0, 12),
SaleAmount: 16050,
Terms: '15 Days',
TotalAmount: 16550,
CustomerStoreState: 'California',
CustomerStoreCity: 'San Jose',
Employee: 'Jim Packard',
}, {
ID: 5,
OrderNumber: 35714,
OrderDate: new Date(2024, 0, 22),
SaleAmount: 14750,
Terms: '15 Days',
TotalAmount: 15250,
CustomerStoreState: 'Nevada',
CustomerStoreCity: 'Las Vegas',
Employee: 'Harv Mudd',
}, {
ID: 7,
OrderNumber: 35983,
OrderDate: new Date(2024, 1, 7),
SaleAmount: 3725,
Terms: '15 Days',
TotalAmount: 3850,
CustomerStoreState: 'Colorado',
CustomerStoreCity: 'Denver',
Employee: 'Todd Hoffman',
}, {
ID: 9,
OrderNumber: 36987,
OrderDate: new Date(2024, 2, 11),
SaleAmount: 14200,
Terms: '15 Days',
TotalAmount: 14800,
CustomerStoreState: 'Utah',
CustomerStoreCity: 'Salt Lake City',
Employee: 'Clark Morgan',
}, {
ID: 11,
OrderNumber: 38466,
OrderDate: new Date(2024, 2, 1),
SaleAmount: 7800,
Terms: '15 Days',
TotalAmount: 8200,
CustomerStoreState: 'California',
CustomerStoreCity: 'Los Angeles',
Employee: 'Harv Mudd',
}, {
ID: 14,
OrderNumber: 39420,
OrderDate: new Date(2024, 1, 15),
SaleAmount: 20500,
Terms: '15 Days',
TotalAmount: 9100,
CustomerStoreState: 'California',
CustomerStoreCity: 'San Jose',
Employee: 'Jim Packard',
}, {
ID: 15,
OrderNumber: 39874,
OrderDate: new Date(2024, 1, 4),
SaleAmount: 9050,
Terms: '30 Days',
TotalAmount: 19100,
CustomerStoreState: 'Nevada',
CustomerStoreCity: 'Las Vegas',
Employee: 'Harv Mudd',
}, {
ID: 18,
OrderNumber: 42847,
OrderDate: new Date(2024, 1, 15),
SaleAmount: 20400,
Terms: '30 Days',
TotalAmount: 20800,
CustomerStoreState: 'Wyoming',
CustomerStoreCity: 'Casper',
Employee: 'Todd Hoffman',
}, {
ID: 19,
OrderNumber: 43982,
OrderDate: new Date(2024, 4, 29),
SaleAmount: 6050,
Terms: '30 Days',
TotalAmount: 6250,
CustomerStoreState: 'Utah',
CustomerStoreCity: 'Salt Lake City',
Employee: 'Clark Morgan',
}, {
ID: 29,
OrderNumber: 56272,
OrderDate: new Date(2024, 1, 6),
SaleAmount: 15850,
Terms: '30 Days',
TotalAmount: 16350,
CustomerStoreState: 'Utah',
CustomerStoreCity: 'Salt Lake City',
Employee: 'Clark Morgan',
}, {
ID: 30,
OrderNumber: 57429,
OrderDate: new Date(2023, 11, 31),
SaleAmount: 11050,
Terms: '30 Days',
TotalAmount: 11400,
CustomerStoreState: 'Arizona',
CustomerStoreCity: 'Phoenix',
Employee: 'Clark Morgan',
}];
@Injectable()
export class Service {
getOrders(): Order[] {
return orders;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>DevExtreme Demo</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/26.1.5/css/dx.light.css" />
</head>
<body class="dx-viewport">
<div class="demo-container">
<demo-app>Loading...</demo-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/zone.js@0.16.2/bundles/zone.umd.js"></script>
<script src="./bundle.js" type="module"></script>
</body>
</html>