Adding Advanced Sorting to the Angular Data Table
Welcome Back to Our Angular Journey
Introduction to Sorting
In the previous article, we successfully integrated pagination into our generic-data-table
. Now, we elevate its functionality by implementing sorting. Sorting is not just a feature; it's a necessity for users who need to navigate through data intuitively. In this segment, we'll explore how we brought this crucial feature to life in our Angular data table.
1. Setting Up Sorting Inputs
We begin by enhancing our generic-data-table
component with crucial @Input()
properties:
@Input() isServerSideSorting: boolean = true;
Note: Before proceeding, import below modules
import { MatPaginatorModule } from '@angular/material/paginator';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
2 Implementing Sorting in HTML
Firstly, we modified our table headers to include sorting capabilities. This is done by adding Angular Material’s mat-sort-header
the directive in each header and adding matSort
directive in the table
tag itself.
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" matSort>
<ng-container *ngFor="let column of columns; let i = index" [matColumnDef]="column.field">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
{{ column.label }}
</th>
<td mat-cell *matCellDef="let element" [style.width.%]="column.width">{{ element[column.field] }}</td>
</ng-container>
</table>
3 The TypeScript Logic: Handling Sorting Events
For sorting functionality, we introduced sortTable();
in generic-data-table. This gets triggered when a user alters the sorting criteria, handling both client-side and server-side sorting scenarios
We start by declaring a MatSort
view child and an @Output()
event emitter for sorting changes:
@ViewChild(MatSort) sort: MatSort;
@Output() sortChanged = new EventEmitter<{ property: string, direction: string } | null>();
MatSort
is a directive that manages the sorting state and decision-making process for the table.sortChanged
is an event emitter that communicates the sorting criteria back to a parent component, especially useful for server-side sorting scenarios
sortTable() {
this.sort.sortChange.subscribe((event) => {
if (this.isServerSideSorting) {
// Emit parameters for server-side sorting
let sortParam = null;
if (event.direction === 'asc' || event.direction === 'desc') {
sortParam = { property: event.active, direction: event.direction.toUpperCase() };
}
this.sortChanged.emit(sortParam);
} else {
// Handle client-side sorting
this.clientSideSorting(event.active, event.direction);
}
});
}
This method determines whether to handle sorting on the client side or to emit the sorting parameters for server-side processing.
How It Functions
- Server-Side Sorting: When the table is set for server-side sorting,
sortTable
listens for changes and emits thesortChanged
event with the appropriate parameters. This notifies the parent component about the user's chosen sorting criteria, prompting it to fetch or rearrange data accordingly. - Client-Side Sorting: In scenarios where the data resides on the client side,
sortTable
takes a direct approach. It calls theclientSideSorting
function, which rearranges the displayed data based on the selected column and sort direction.
Client-Side Sorting Logic
For client-side scenarios, the clientSideSorting
function arranges the data based on the chosen column and direction:
const sortedData = this.dataSource.slice().sort((a, b) => {
let valueA = a[columnName];
let valueB = b[columnName];
// Assuming string sorting, include your own for numbers, dates, etc.
let comparison = 0;
if (valueA > valueB) {
comparison = 1;
} else if (valueA < valueB) {
comparison = -1;
}
return direction === 'asc' ? comparison : -comparison;
});
this.dataSource = sortedData;
Integrating Sorting in the Parent Component
Just like with pagination, the parent component plays a crucial role in handling sorting, especially in server-side scenarios. The sortChanged
event is captured by the parent, which then fetches or rearranges the data based on the new sorting parameters.
<app-generic-data-table
[dataSource]="dataSource"
[columns]="columns"
[totalItems]="totalItemCount"
[isServerSidePagination]="false"
[isServerSideSorting]="false"
(pageChanged)="pageChanged($event.pageIndex, $event.pageSize)"
(sortChanged)="onSortChanged($event)">
</app-generic-data-table>
Conclusion: A Table That Listens and Reacts
With sorting integrated, our generic-data-table
isn't just displaying data; it's providing a dynamic interface for users to interact with and organize information effectively. This makes our table not just a tool but a smart component that enhances the overall user experience.
Stay tuned as we continue to refine our data table with more features, ensuring it remains a versatile and essential component in any Angular application.