Angular Grid
The Grid solution for Angular Enterprise Applications with 14 Material Themes and 100+ Angular Grid Demos.
- Grouping
- Filtering
- Sorting
- Editing
- Paging
- Selection
- Outstanding Performance
- Masted Detail
- Export to Excel, PDF, CSV, TSV, HTML, JSON
- Import from Excel
- Cut, Copy, Paste
- Auto-Fill
- Merged Cells
- Printing
- Lazy Load
- Server side operation
- 80%+ code coverage with Tests
- Industry best Accessibility support
- Localization, I18n, RTL
- Tree Data
Angular Grid Project Tracker Example
Overview
We will walk you through the steps to add Smart.Grid to an Angular project, and configure some of the features. Smart.Grid is a feature complete data grid component with enterprise-grade features. We will show you some of the data grid capabilities (properties, data source). In addition, we will customize the Grid appearance with custom Column Templates. If you would like to move directly to our examples, please navigate to Angular Grid Demos.
Table of Contents
Add Grid to Your Angular Project
The Angular step we need to take to make Angular display the smart-grid is to import the GridModule.If you use Angular 17+ with standalone components, you can skip the below step with app.module.ts.
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { GridModule } from 'smart-webcomponents-angular/grid'; @NgModule({ declarations: [AppComponent], imports: [BrowserModule, FormsModule, GridModule], schemas: [], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
We can now use the smart-grid with Angular. Data binding and event handlers will just work right out of the box.
Here’s how we would use our Smart.Grid element as part of a simple Angular app. First, our component template:
app.component.html
<smart-grid [columns]="columns" [dataSource]="dataSource" id="grid"></smart-grid>
We have bound the "columns" and "dataSource" properties of the smart-grid to values in our Angular component.
app.component.ts
if you use Angular 17+ with standalone components, see the code below:
import { Component, ViewChild, AfterViewInit, ViewEncapsulation } from '@angular/core'; import { GridComponent, GridColumn, DataAdapter, Smart } from 'smart-webcomponents-angular/grid'; import { CommonModule } from '@angular/common'; import { RouterOutlet } from '@angular/router'; import { GridModule } from 'smart-webcomponents-angular/grid'; @Component({ selector: 'app-root', standalone: true, imports: [CommonModule, GridModule, RouterOutlet], templateUrl: './app.component.html', styleUrls: ['app.component.css'], encapsulation: ViewEncapsulation.None }) export class AppComponent implements AfterViewInit { dataSource = new Smart.DataAdapter( { dataSource: [{ "id": 0, "firstName": "Beate", "lastName": "Wilson", "productName": "Caramel Latte", "price": 3.8, "quantity": 6, "total": 22.799999999999997 }, { "id": 1, "firstName": "Ian", "lastName": "Nodier", "productName": "Caramel Latte", "price": 3.8, "quantity": 8, "total": 30.4 }, { "id": 2, "firstName": "Petra", "lastName": "Vileid", "productName": "Green Tea", "price": 1.5, "quantity": 2, "total": 3 }, { "id": 3, "firstName": "Mayumi", "lastName": "Ohno", "productName": "Caramel Latte", "price": 3.8, "quantity": 2, "total": 7.6 }, { "id": 4, "firstName": "Mayumi", "lastName": "Saylor", "productName": "Espresso con Panna", "price": 3.25, "quantity": 4, "total": 13 }, { "id": 5, "firstName": "Regina", "lastName": "Fuller", "productName": "Caffe Americano", "price": 2.5, "quantity": 4, "total": 10 }, { "id": 6, "firstName": "Regina", "lastName": "Burke", "productName": "Caramel Latte", "price": 3.8, "quantity": 8, "total": 30.4 }, { "id": 7, "firstName": "Andrew", "lastName": "Petersen", "productName": "Caffe Americano", "price": 2.5, "quantity": 6, "total": 15 }, { "id": 8, "firstName": "Martin", "lastName": "Ohno", "productName": "Espresso con Panna", "price": 3.25, "quantity": 3, "total": 9.75 }, { "id": 9, "firstName": "Beate", "lastName": "Devling", "productName": "Green Tea", "price": 1.5, "quantity": 9, "total": 13.5 }, { "id": 10, "firstName": "Sven", "lastName": "Devling", "productName": "Espresso Truffle", "price": 1.75, "quantity": 6, "total": 10.5 }, { "id": 11, "firstName": "Petra", "lastName": "Burke", "productName": "Peppermint Mocha Twist", "price": 4, "quantity": 11, "total": 44 }], dataFields: [ 'id: number', 'firstName: string', 'lastName: string', 'productName: string', 'quantity: number', 'price: number', 'total: number' ] }) columns: GridColumn[] = [ { label: 'First Name', dataField: 'firstName', columnGroup: 'name' }, { label: 'Last Name', dataField: 'lastName', columnGroup: 'name' }, { label: 'Product', dataField: 'productName', columnGroup: 'order' }, { label: 'Quantity', dataField: 'quantity', columnGroup: 'order' }, { label: 'Unit Price', dataField: 'price', cellsFormat: 'c2', columnGroup: 'order', formatFunction(settings) { const rowId = settings.row; const columnDataField = settings.column; const template = settings.template; const cell = settings.cell!; if (settings.value >= 4) { cell.background = '#00A45A'; cell.color = '#fff'; } else if (settings.value < 2) { cell.background = '#DF3800'; cell.color = '#fff'; } else { cell.background = '#FFFDE1'; cell.color = '#333'; } settings.value = '$' + new Number(settings.value).toFixed(2); } }, { label: 'Total', dataField: 'total', cellsFormat: 'c2', columnGroup: 'order', formatFunction(settings) { const rowId = settings.row; const columnDataField = settings.column; const template = settings.template; const cell = settings.cell!; if (settings.value >= 20) { cell.background = '#00A45A'; cell.color = '#fff'; } else if (settings.value <= 5) { cell.background = '#DF3800'; cell.color = '#fff'; } else { cell.background = '#FFFDE1'; cell.color = '#333'; } settings.value = '$' + new Number(settings.value).toFixed(2); } } ] ngOnInit(): void { } ngAfterViewInit(): void { } }
Otherwise, the tradional way is:
import { Component, ViewChild, AfterViewInit, ViewEncapsulation } from '@angular/core'; import { GridComponent, GridColumn, DataAdapter, Smart } from 'smart-webcomponents-angular/grid'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['app.component.css'], encapsulation: ViewEncapsulation.None }) export class AppComponent implements AfterViewInit { dataSource = new Smart.DataAdapter( { dataSource: [{ "id": 0, "firstName": "Beate", "lastName": "Wilson", "productName": "Caramel Latte", "price": 3.8, "quantity": 6, "total": 22.799999999999997 }, { "id": 1, "firstName": "Ian", "lastName": "Nodier", "productName": "Caramel Latte", "price": 3.8, "quantity": 8, "total": 30.4 }, { "id": 2, "firstName": "Petra", "lastName": "Vileid", "productName": "Green Tea", "price": 1.5, "quantity": 2, "total": 3 }, { "id": 3, "firstName": "Mayumi", "lastName": "Ohno", "productName": "Caramel Latte", "price": 3.8, "quantity": 2, "total": 7.6 }, { "id": 4, "firstName": "Mayumi", "lastName": "Saylor", "productName": "Espresso con Panna", "price": 3.25, "quantity": 4, "total": 13 }, { "id": 5, "firstName": "Regina", "lastName": "Fuller", "productName": "Caffe Americano", "price": 2.5, "quantity": 4, "total": 10 }, { "id": 6, "firstName": "Regina", "lastName": "Burke", "productName": "Caramel Latte", "price": 3.8, "quantity": 8, "total": 30.4 }, { "id": 7, "firstName": "Andrew", "lastName": "Petersen", "productName": "Caffe Americano", "price": 2.5, "quantity": 6, "total": 15 }, { "id": 8, "firstName": "Martin", "lastName": "Ohno", "productName": "Espresso con Panna", "price": 3.25, "quantity": 3, "total": 9.75 }, { "id": 9, "firstName": "Beate", "lastName": "Devling", "productName": "Green Tea", "price": 1.5, "quantity": 9, "total": 13.5 }, { "id": 10, "firstName": "Sven", "lastName": "Devling", "productName": "Espresso Truffle", "price": 1.75, "quantity": 6, "total": 10.5 }, { "id": 11, "firstName": "Petra", "lastName": "Burke", "productName": "Peppermint Mocha Twist", "price": 4, "quantity": 11, "total": 44 }], dataFields: [ 'id: number', 'firstName: string', 'lastName: string', 'productName: string', 'quantity: number', 'price: number', 'total: number' ] }) columns: GridColumn[] = [ { label: 'First Name', dataField: 'firstName', columnGroup: 'name' }, { label: 'Last Name', dataField: 'lastName', columnGroup: 'name' }, { label: 'Product', dataField: 'productName', columnGroup: 'order' }, { label: 'Quantity', dataField: 'quantity', columnGroup: 'order' }, { label: 'Unit Price', dataField: 'price', cellsFormat: 'c2', columnGroup: 'order', formatFunction(settings) { const rowId = settings.row; const columnDataField = settings.column; const template = settings.template; const cell = settings.cell!; if (settings.value >= 4) { cell.background = '#00A45A'; cell.color = '#fff'; } else if (settings.value < 2) { cell.background = '#DF3800'; cell.color = '#fff'; } else { cell.background = '#FFFDE1'; cell.color = '#333'; } settings.value = '$' + new Number(settings.value).toFixed(2); } }, { label: 'Total', dataField: 'total', cellsFormat: 'c2', columnGroup: 'order', formatFunction(settings) { const rowId = settings.row; const columnDataField = settings.column; const template = settings.template; const cell = settings.cell!; if (settings.value >= 20) { cell.background = '#00A45A'; cell.color = '#fff'; } else if (settings.value <= 5) { cell.background = '#DF3800'; cell.color = '#fff'; } else { cell.background = '#FFFDE1'; cell.color = '#333'; } settings.value = '$' + new Number(settings.value).toFixed(2); } } ] ngOnInit(): void { } ngAfterViewInit(): void { } }
angular.json
The below code is the angular.json file, where we updated the "styles" by adding the CSS file for the Smart Web Components.
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "bargauge": { "projectType": "application", "root": "", "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "outputPath": "dist/grid/overview/", "index": "", "main": "src/grid/overview//main.ts", "polyfills": "polyfills.ts", "tsConfig": "tsconfig.app.json", "styles": [ "node_modules/smart-webcomponents-angular/source/styles/smart.default.css" ], "es5BrowserSupport": false }, "configurations": { "production": { "optimization": true, "sourceMap": false, "extractCss": true, "namedChunks": false, "aot": true, "extractLicenses": false, "vendorChunk": false, "buildOptimizer": true } } } } } } }
Result:
Add Sorting and Filtering
Sorting and Filtering are essential features in each web application with Grids. To enable the sorting and filtering in our grid, we need to define two objects - sorting and filtering and set the "enabled" boolean property to true. We add the below code to app.component.ts
sorting = { enabled: true; } filtering = { enabled: true; }
and in app.component.html
<smart-grid [sorting]="sorting" [filtering]="filtering" [columns]="columns" [dataSource]="dataSource" id="grid"></smart-grid>
Online Examples: Grid Sorting and Grid Filtering
Enable Selection
The Grid supports selection by cell, row and with checkboxes. We can also choose from selection with single and double-click, selection by one or multiple rows or cells. In the code below, we will enable the Row selection. We add the below code to app.component.ts
selection = { enabled: true; }
and in app.component.html
<smart-grid [selection]="selection" [sorting]="sorting" [filtering]="filtering" [columns]="columns" [dataSource]="dataSource" id="grid"></smart-grid>
Online Selection Example: Grid Selection.
Enable Grouping
Grouping is a professional feature and requires a license. The comparison table with features and components included in the Community and Professional versions is here. Similar to Sorting and Filtering, Grouping is enabled by setting the "enabled" property to true
We add the below code to app.component.ts
grouping = { enabled: true; }
and in app.component.html
<smart-grid [grouping]="grouping" [selection]="selection" [sorting]="sorting" [filtering]="filtering" [columns]="columns" [dataSource]="dataSource" id="grid"></smart-grid>
Online Grouping Example: Grid Grouping.
Enable Paging
smart-grid supports editing by cell, editing by row(Professional) and editing with dialog or command column(Professional). In this case, we will use the cell editing. You can enable the editing functionality by setting the "enabled" boolean property to true.
app.component.ts
import { Component, ViewChild, AfterViewInit, ViewEncapsulation } from '@angular/core'; import { GridComponent, GridColumn, DataAdapter, Smart } from 'smart-webcomponents-angular/grid'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['app.component.css'], encapsulation: ViewEncapsulation.None }) export class AppComponent implements AfterViewInit { editing = { enabled: true } dataSource = new Smart.DataAdapter({ dataSource: [{ "id": 0, "firstName": "Beate", "lastName": "Wilson", "productName": "Caramel Latte", "price": 3.8, "quantity": 6, "total": 22.799999999999997 }, { "id": 1, "firstName": "Ian", "lastName": "Nodier", "productName": "Caramel Latte", "price": 3.8, "quantity": 8, "total": 30.4 }, { "id": 2, "firstName": "Petra", "lastName": "Vileid", "productName": "Green Tea", "price": 1.5, "quantity": 2, "total": 3 }, { "id": 3, "firstName": "Mayumi", "lastName": "Ohno", "productName": "Caramel Latte", "price": 3.8, "quantity": 2, "total": 7.6 }, { "id": 4, "firstName": "Mayumi", "lastName": "Saylor", "productName": "Espresso con Panna", "price": 3.25, "quantity": 4, "total": 13 }, { "id": 5, "firstName": "Regina", "lastName": "Fuller", "productName": "Caffe Americano", "price": 2.5, "quantity": 4, "total": 10 }, { "id": 6, "firstName": "Regina", "lastName": "Burke", "productName": "Caramel Latte", "price": 3.8, "quantity": 8, "total": 30.4 }, { "id": 7, "firstName": "Andrew", "lastName": "Petersen", "productName": "Caffe Americano", "price": 2.5, "quantity": 6, "total": 15 }, { "id": 8, "firstName": "Martin", "lastName": "Ohno", "productName": "Espresso con Panna", "price": 3.25, "quantity": 3, "total": 9.75 }, { "id": 9, "firstName": "Beate", "lastName": "Devling", "productName": "Green Tea", "price": 1.5, "quantity": 9, "total": 13.5 }, { "id": 10, "firstName": "Sven", "lastName": "Devling", "productName": "Espresso Truffle", "price": 1.75, "quantity": 6, "total": 10.5 }, { "id": 11, "firstName": "Petra", "lastName": "Burke", "productName": "Peppermint Mocha Twist", "price": 4, "quantity": 11, "total": 44 }], dataFields: [ 'id: number', 'firstName: string', 'lastName: string', 'productName: string', 'quantity: number', 'price: number', 'total: number' ] }) columns: GridColumn[] = [ { label: 'First Name', dataField: 'firstName', columnGroup: 'name' }, { label: 'Last Name', dataField: 'lastName', columnGroup: 'name' }, { label: 'Product', dataField: 'productName', columnGroup: 'order' }, { label: 'Quantity', dataField: 'quantity', columnGroup: 'order' }, { label: 'Unit Price', dataField: 'price', cellsFormat: 'c2' }, { label: 'Total', dataField: 'total', cellsFormat: 'c2' } ] ngOnInit(): void { } ngAfterViewInit(): void { } }
app.component.html
<smart-grid [editing]="editing" [columns]="columns" [dataSource]="dataSource" id="grid"></smart-grid>
Enable Paging
To enable pagination, set the grid paging and pager properties. The paging.enabled turns on/off pagination, pager.visible shows/hides the top or bottom pagers. The grid's pagination feature can be used to load data on demand. It can be used with all other grid features. There are built-in options to customize the "pageSize", navigate through pages using API, customize the pager's template, configure whether top and bottom pagers are visible all the time or only the top or bottom pager is visible. It is also optional to display a "select" tag to dynamically update the page size or an "input" tag which allows you to type the page index and navigate to the page.
app.component.ts
import { Component, ViewChild, AfterViewInit, ViewEncapsulation } from '@angular/core'; import { GridComponent, GridColumn, DataAdapter, Smart } from 'smart-webcomponents-angular/grid'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['app.component.css'], encapsulation: ViewEncapsulation.None }) export class AppComponent implements AfterViewInit { @ViewChild("grid", { read: GridComponent, static: false }) grid!: GridComponent; editing = { enabled: true } paging = { enabled: true, pageSize: 5 } pager = { visible: true } dataSource = new Smart.DataAdapter({{ dataSource: [{ "id": 0, "firstName": "Beate", "lastName": "Wilson", "productName": "Caramel Latte", "price": 3.8, "quantity": 6, "total": 22.799999999999997 }, { "id": 1, "firstName": "Ian", "lastName": "Nodier", "productName": "Caramel Latte", "price": 3.8, "quantity": 8, "total": 30.4 }, { "id": 2, "firstName": "Petra", "lastName": "Vileid", "productName": "Green Tea", "price": 1.5, "quantity": 2, "total": 3 }, { "id": 3, "firstName": "Mayumi", "lastName": "Ohno", "productName": "Caramel Latte", "price": 3.8, "quantity": 2, "total": 7.6 }, { "id": 4, "firstName": "Mayumi", "lastName": "Saylor", "productName": "Espresso con Panna", "price": 3.25, "quantity": 4, "total": 13 }, { "id": 5, "firstName": "Regina", "lastName": "Fuller", "productName": "Caffe Americano", "price": 2.5, "quantity": 4, "total": 10 }, { "id": 6, "firstName": "Regina", "lastName": "Burke", "productName": "Caramel Latte", "price": 3.8, "quantity": 8, "total": 30.4 }, { "id": 7, "firstName": "Andrew", "lastName": "Petersen", "productName": "Caffe Americano", "price": 2.5, "quantity": 6, "total": 15 }, { "id": 8, "firstName": "Martin", "lastName": "Ohno", "productName": "Espresso con Panna", "price": 3.25, "quantity": 3, "total": 9.75 }, { "id": 9, "firstName": "Beate", "lastName": "Devling", "productName": "Green Tea", "price": 1.5, "quantity": 9, "total": 13.5 }, { "id": 10, "firstName": "Sven", "lastName": "Devling", "productName": "Espresso Truffle", "price": 1.75, "quantity": 6, "total": 10.5 }, { "id": 11, "firstName": "Petra", "lastName": "Burke", "productName": "Peppermint Mocha Twist", "price": 4, "quantity": 11, "total": 44 }], dataFields: [ 'id: number', 'firstName: string', 'lastName: string', 'productName: string', 'quantity: number', 'price: number', 'total: number' ] }) columns: GridColumn[] = [ { label: 'First Name', dataField: 'firstName', columnGroup: 'name' }, { label: 'Last Name', dataField: 'lastName', columnGroup: 'name' }, { label: 'Product', dataField: 'productName', columnGroup: 'order' }, { label: 'Quantity', dataField: 'quantity', columnGroup: 'order' }, { label: 'Unit Price', dataField: 'price', cellsFormat: 'c2' }, { label: 'Total', dataField: 'total', cellsFormat: 'c2' } ] ngOnInit(): void { } ngAfterViewInit(): void { } }
app.component.html
<smart-grid [paging]="paging" [pager]="pager" [editing]="editing" [columns]="columns" [dataSource]="dataSource" id="grid"></smart-grid>
Set Theme
The Smart Web Components product includes 14 Material Themes - 7 Light and 7 Dark. To set a theme, just include the "smart.[theme].css" file after smart.default.css and set your component's theme attribute to the theme name.
<smart-grid [theme]="'dark'" [grouping]="grouping" [selection]="selection" [sorting]="sorting" [filtering]="filtering" [columns]="columns" [dataSource]="dataSource" id="grid"></smart-grid>
If you would like to customize or build a custom theme, you can use our Online Theme Builder web application.
Angular Grid Demos
You can look at our collection of demos about the Grid Component here; Angular Grid Demos. There you will find a demo about Filtering, Sorting, Editing, Selection, Print, Export to Excel, PDF, Import from Excel and more.