This Angular Grid component can allow users to visualize and edit data themselves. See for yourself!
When working with data in our applications, users often want to visualize it and occasionally need to edit it. As developers, we need to craft an intuitive and appealing way to both visualize and edit the data.
For instance, we might need to create a grid, combined with a form that contains custom controls to align with the data types present in each row or cell. Defining how these controls should appear and function can become a challenging and daunting task, especially when such configurations must be repeated across various sections.
One solution that can save time for your company and simplify tasks for your developers is to leverage the capabilities of the Grid from Progress Kendo UI for Angular. This tool empowers you to edit entire rows or specific cells with precision, allowing you to customize and control data editing seamlessly.
Rather than detailing each feature of Kendo UI for Angular Grid, I will demonstrate just how straightforward it is to enable users to edit data within Angular apps using a practical example. In this article, we’ll cover:
We have provided a list of NBA players and want to perform the following tasks:
Let’s go! 🏀
Create a new app by running the command in the terminal:
ng new nba
Answer the CLI question with default options:
Go to the nba
folder, edit the app.component.html and remove the default HTML to be ready for our next step.
Now, continue to use the Angular schematic to install the Kendo UI for Angular Data Grid into our app by running the following command in the terminal.
ng add @progress/kendo-angular-grid
It automatically adds the Kendo UI for Angular Data Grid Module to the app.module, making the Kendo UI for Angular Grid component available for use.
Note: If you are using Angular v17 or higher, the default will be standalone in new applications. Standalone apps do not have modules, so this set up will be a little different. Essentially, after the install, you will need to import each Kendo UI component you require into the individual component files.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { GridModule } from '@progress/kendo-angular-grid';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
GridModule,
BrowserAnimationsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Perfect! Let’s start to write code!
We’re going to use fake data to populate the grid. For this purpose, we’ll define a type NbaPlayer and create a list of sample NBA player data.
Start by creating a new file named mock.ts
and add the following content:
// Define the NBA player type
export type NbaPlayer = {
id: string;
name: string;
points: number;
rebounds: number;
assist: number;
height: number;
captain: boolean;
startDate: string;
};
// Sample NBA player data
export const players: Array<NbaPlayer> = [
{
id: '1',
name: 'LeBron James',
points: 28,
rebounds: 8,
assist: 9,
height: 6.8,
captain: true,
startDate: '10/10/2003',
},
{
id: '2',
name: 'Stephen Curry',
points: 32,
rebounds: 6,
assist: 6,
height: 6.2,
captain: true,
startDate: '11/11/2009',
},
{
id: '3',
name: 'Kevin Durant',
points: 29,
rebounds: 7,
assist: 5,
height: 6.9,
captain: false,
startDate: '12/12/2007',
},
...
]
This sets the foundation for our grid by creating the required data structure and providing sample data. Next, we’ll integrate this with our Kendo UI Grid component.
Before using the Kendo UI Data Grid to show and edit the players list, we want to create a component players-grid to utilize the Kendo UI for Angular Data Grid component to render and edit player information.
Next, using the Angular CLI, we will create the players-grid
component using the -t
flag for an inline template, which prevents the creation of an HTML file. Run the following command:
–ng g c components/players-grid –t
CREATE src/app/components/players-grid/players-grid.component.spec.ts (635 bytes)
CREATE src/app/components/players-grid/players-grid.component.ts (239 bytes)
CREATE src/app/components/players-grid/players-grid.component.css (0 bytes)
UPDATE src/app/app.module.ts (588 bytes)
Open players-grid.component.ts and add a new property called players to link with the player array. Replace <p>players-grid works!</p>
with the kendo-grid
component and bind the data property to nbaPlayers
.
import { Component} from '@angular/core';
@Component({
selector: 'app-player-edit-row',
template: `<kendo-grid [data]="nbaPlayers"
> </kendo-grid>`,
styleUrls: ['./player-edit-row.component.css'],
})
export class PlayerEditRowComponent {
nbaPlayers = players;
}
Note: If you are using standalone, you will need to import the PlayersGridComponent:
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { PlayersGridComponent } from './components/players-grid/players-grid.component';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, PlayersGridComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
title = 'nba';
}
Alright, we’ve successfully configured the players-grid component. Now, let’s incorporate it into app.component.html.
Open app.component.html and insert the <app-players-grid/>
component. Your HTML should resemble:
<app-players-grid/>
After saving the changes, run ng serve -o
. The app should now display the list of players.
Magic! The Grid is up and running! The real magic comes from the Kendo UI for Angular Data Grid. It simplifies our work by automatically binding properties in the Grid when possible. It’s a feature we’ll be tweaking, but it’s undeniably handy.
Before making our grid editable, it’s crucial to control which columns will be displayed.
The Kendo UI Grid offers the <kendo-grid-column>
component, which comes with two properties: title
and field
. These allow us to define the columns that will be rendered.
The nbaPlayers
is an array of the NbaPlayer
type, each with a set of properties.
export type NbaPlayer = {
id: string;
name: string;
points: number;
rebounds: number;
assist: number;
height: number;
captain: boolean;
startDate: string;
};
We can bind to all properties or exclude some. When we want to specify which columns to bind to, we should use the kendo-grid-column
component.
Inside the kendo-grid
, add the kendo-grid-column
component. Set the title
property for the column title and the field
property for the column field.
<kendo-grid
[data]="nbaPlayers"
>
<kendo-grid-column title="ID" field="id"> </kendo-grid-column>
<kendo-grid-column title="Name" field="name"> </kendo-grid-column>
<kendo-grid-column title="Points" field="points"> </kendo-grid-column>
<kendo-grid-column title="Assists" field="assist"> </kendo-grid-column>
<kendo-grid-column title="Rebounds"field="rebounds"> </kendo-grid-column>
<kendo-grid-column title="Captain"field="captain"> </kendo-grid-column>
<kendo-grid-column title="Start Date" field="startDate"> </kendo-grid-column>
</kendo-grid>
Save the changes. Now, the grid will display all columns except for the height column.
Before diving into creating an interface that allows users to edit, there are several factors to consider. Our goal is to provide an excellent user experience and maintain control over the editing process.
Important considerations include:
This isn’t an exhaustive list since we’re aiming for brevity in this article. Rather than building all these features from scratch, we’ll leverage the capabilities of the Kendo UI for Angular Data Grid.
The Kendo UI Grid offers all these features (and more), enabling us to implement an editable grid quickly and painlessly. This efficiency might just give you some extra time for a Netflix binge or an early evening at home.
Let’s get coding!
Angular offers two methods for working with forms: reactive and template-driven forms. Similarly, the Kendo UI for Angular Data Grid provides two mechanisms for enabling editability using either the kendoGridReactiveEditing
or kendoGridTemplateEditing
directives.
The directives make CRUD operations straightforward, whether by cell or row. In our scenario, we’ll opt for the reactive approach. We prefer reactive forms because they leverage Angular’s FormBuilder, simplifying the construction of reactive forms and allowing us to define our form group, controls and validations.
Read more about reactive forms.
Before getting started, it’s essential to add both FormsModule and ReactiveFormsModule to the imports section of app.module.ts
. Afterward, open the players-grid.component
and inject the FormBuilder using the constructor.
export class PlayersGridComponent {
nbaPlayers = players;
formBuilder = inject(FormBuilder);
Alternatively, if using standalone, you will simply import the FormBuilder into your component’s imports array:
import { Component, inject } from '@angular/core';
import { GridModule } from '@progress/kendo-angular-grid';
import { players } from '../../../../src/app/mock';
import { FormBuilder } from '@angular/forms';
@Component({
selector: 'app-players-grid',
standalone: true,
imports: [GridModule],
template: `...`,
styleUrl: './players-grid.component.css'
})
export class PlayersGridComponent {
nbaPlayers = players;
formBuilder = inject(FormBuilder);
}
Remember we need a form? We must connect the form with the Kendo UI for Angular Data Grid using events, allowing the grid to switch to edit mode and linking the grid field with the form.
First, create a new method called createFormGroup
, taking a NbaPlayer
object as a parameter (it represents a row in our grid). Use the form builder to create a form for each field and bind the values to the form.
The final code will look like:
private createFormGroup(player: NbaPlayer): any {
return this.formBuilder.group({
id: player.id,
name: player.name,
points: player.points,
assist: player.assist,
rebounds: player.rebounds,
height: player.height,
captain: player.captain,
startDate: player.startDate,
});
}
The form is complete. Next, we need to configure the grid to connect the form with the built-in editor.
Read more about the kendo-column component.
This is one of my favorite features of Kendo UI for Angular Data Grid. It provides an easy way to connect the data with a component related to that data using the editor property. It supports multiple types of editors, such as numeric, text, Boolean and date. The editor displays an input related to a specific type, for example:
Let’s activate this for all columns except for ID.
<kendo-grid-column title="ID" field="id"> </kendo-grid-column>
<kendo-grid-column title="Name" field="name" editor="text">
</kendo-grid-column>
<kendo-grid-column field="points" editor="numeric"> </kendo-grid-column>
<kendo-grid-column field="assist" editor="numeric"> </kendo-grid-column>
<kendo-grid-column field="rebounds" editor="numeric"> </kendo-grid-column>
<kendo-grid-column field="height" editor="numeric"> </kendo-grid-column>
<kendo-grid-column field="captain" editor="boolean"> </kendo-grid-column>
<kendo-grid-column field="startDate" editor="date"> </kendo-grid-column>
We have the editor, but how do we connect the form with it?
Kendo UI for Angular Data Grid provides built-in cellClick
and cellClose
events. We will link each event to specific methods to handle our editing logic. Let’s begin with cellClick
. We’ll associate it with a new method named cellEditClick
, passing the event as a parameter.
<kendo-grid
[data]="nbaPlayers"
(cellClick)="cellEditClick($event)"
....>
The method receives the event and retrieves cell information it provides, such as the row, column and item. The item is then passed to the createFormGroup
method to connect the reactive forms with the values.
The finalized code looks like:
cellEditClick(cellEvent: CellClickEvent) {
cellEvent.sender.editCell(
cellEvent.rowIndex,
cellEvent.columnIndex,
this.createFormGroup(cellEvent.dataItem)
);
}
Save the changes and see what happens.
Yes! When you double-click on a cell, it dynamically creates an input text, checkbox or even a calendar, all with just a few lines of code.
Hmm… something is not as expected. The values were not saved, and there’s no validation. How can we save the values and trigger validations?
The entity responsible for the form is the FormGroup. We can use Angular validators to make our forms a bit stricter. Import the Validators from import { FormBuilder, Validators }
from '@angular/forms';
in the form declaration. Instead of using the property directly, use an array, passing the property and the validator.
Example: for the name, use Validators.required
and for points, use Validators.min(1)
.
The final code looks like:
private createFormGroup(player: NbaPlayer): any {
return this.formBuilder.group({
id: player.id,
name: [player.name, Validators.required],
points: [player.points, Validators.min(1)],
assist: player.assist,
rebounds: player.rebounds,
height: player.height,
captain: player.captain,
startDate: player.startDate,
});
}
}
Next, we have to perform some steps:
To update, we create a method to find the player and update by ID, using the findIndex
method from the nbaPlayers
array.
private updatePlayer(player: NbaPlayer) {
const playerIndex = this.nbaPlayers.findIndex((p) => p.id === player.id);
this.nbaPlayers[playerIndex] = player;
}
Next, connect the closeCell
event to a new method, cellCloseClick
, passing the event and a template variable reference linked to the Grid.
<kendo-grid
[data]="nbaPlayers"
#playerGrid
(cellClose)="cellCloseClick($event, playerGrid)"
....>
Add the new method cellCloseClick
with two parameters: the event
and the GridComponent
. Our method will perform the following tasks:
updatePlayer
with the value and call the method closeCell
.The final code looks like:
cellCloseClick(cellEvent: CellCloseEvent, playerGrid: GridComponent) {
const { value, valid } = cellEvent.formGroup;
if (valid) {
this.updatePlayer(value);
playerGrid.closeCell();
}
}
Save the changes and reload the application. Now, try to edit the values and play with the grid.
We have successfully configured your Kendo UI for Angular Data Grid to enable click-to-edit functionality for rows. Making our grid editable not only adds fun but also simplifies the addition of complex logic, validation and more. Introducing in-cell editing to the grid streamlines the editing process for your users.
I recommend exploring the Kendo UI documentation further to harness even more of the Grid’s powerful features!
If you haven’t yet taken Kendo UI for Angular for a spin, remember it comes with a free 30-day trial.
Dany Paredes is a Google Developer Expert on Angular and Progress Champion. He loves sharing content and writing articles about Angular, TypeScript and testing on his blog and on Twitter (@danywalls).