Reputation: 41
I would like make my table sortable. For that I use https://material.angular.io/components/sort/overview. The "Sort Header" works in the other tables of the web-app, I read the doc, watched tutorials .. I don't understand why in this specific component it doesn't work...
The matSort and mat-sort-header seems to be well positioned because I see the arrows in my table, they are clickable but nothing is happening
import { MatSortModule } from '@angular/material/sort'
is well imported in admin.module.ts
Component, OnInit, ViewChild, MatSort are well imported in user.component.ts
@ViewChild(MatSort, { static: true }) sort: MatSort;
in the export class UserComponent implements OnInit
this.dataSource.sort = this.sort;
in ngOnInit
Somebody to help me ?
import { Component, OnInit, ViewChild } from '@angular/core';
//[...]other imports
import { MatSort } from '@angular/material/sort';
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.less'],
})
export class UserComponent implements OnInit {
public translatePage: ComponentsTrslt = ComponentsTrslt.PROFILE;
users: UserItem[] = []; // contains users get from back
public dataSource: MatTableDataSource<UserItem>; // users that will be displayed in a material way
public displayedColumns: string[] = [
'email',
'firstName',
'lastName',
'userRating',
'coreHour',
'action',
]; // columns to display
public pageSize = 10; // default displayed elements number
public currentPage = 0; // default displayed page
public totalSize = 0; // default number of element in dataSource (not set yet)
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator; // paginator at the bottom of the page
// sorted data
@ViewChild(MatSort, { static: true }) sort: MatSort;
// [...] other code... : Popups / Dialog boxes + Edition data passed to forms / fields ...
constructor(
public translateService: TranslationService,
private userService: UserService,
private expertService: ExpertService,
private clientService: ClientService,
private router: Router,
private snackBar: MatSnackBar,
private formBuilder: FormBuilder,
public dialog: MatDialog,
public languageService: LanguageService
) {
}
ngOnInit(): void {
this.fetchAndMapUsers(); // include this.dataSource.sort = this.sort;
this.editExpertProfileForm = this.formBuilder.group({
lastName: '',
firstName: '',
email: '',
phone: '',
company: '',
title: '',
wage: '',
citizenship: '',
country: '',
city: '',
address: '',
zipCode: '',
rating: [{ value: null }],
});
this.editProfileForm = this.formBuilder.group({
lastName: '',
firstName: '',
email: '',
phone: '',
company: '',
service: '',
citizenship: '',
country: '',
city: '',
address: '',
zipCode: '',
languages: [],
});
this.editRatingForm = this.formBuilder.group({
id: '',
userId: '',
title: '',
rating: '',
wage: '',
available: '',
});
this.editCoreHourForm = this.formBuilder.group({
coreHour: 0,
});
}
// Get expert data from User Id
this.expertService.getByUserId(expertId).subscribe((data) => {
// Send data to form
this.editRatingForm.setValue({
id: data.id,
userId: data.userId,
title: '',
rating: data.rating,
wage: '',
available: '',
});
this.expertInfoEdition = data;
this.expertRatingEdition = data.rating;
this.editModeRating = !this.editModeRating;
});
}
// Get all users from back
private fetchAndMapUsers(): void {
this.userService.getAll().subscribe((data) => {
console.log(data);
this.mapUsers(data); // include this.dataSource.sort = this.sort;
});
}
// populateTable() {
// this.userService.getAll()
// .subscribe(data => {
// this.results = data;
// this.dataSource = new MatTableDataSource(this.results);
// this.dataSource.sort = this.sort;
// })}
public handlePage(e: any) {
this.currentPage = e.pageIndex;
this.pageSize = e.pageSize;
this.iterator();
}
private iterator() {
const end = (this.currentPage + 1) * this.pageSize;
const start = this.currentPage * this.pageSize;
const part = this.users.slice(start, end);
this.dataSource = new MatTableDataSource<UserItem>(part);
}
// Create the list of users from the users got by the call to back
private mapUsers(data): void {
// Fill the list of users from the users got by the call to back
this.users = data.map((element) => {
const ui: UserItem = {
userId: element.id,
email: element.email,
firstName: element.firstName,
lastName: element.lastName,
isValidated: element.isValidated,
isAdmin: element.isAdmin,
isPremiumCommunity: element.isPremiumCommunity,
hasCommunityAccess: element.hasCommunityAccess,
userRating: null,
coreHour: null,
};
this.userService.get(element.id).subscribe((userData) => {
ui.coreHour = userData.creditsTimeRatio;
if (userData.expertId) {
this.expertService.get(userData.expertId).subscribe((expertData) => {
ui.userRating = expertData.rating;
});
}
});
if (!element.isDisabled) {
return ui;
}
});
// Sort by email address before displaying the list
this.users.sort((user1, user2) => {
if (user1.email < user2.email) {
return -1;
}
if (user1.email > user2.email) {
return 1;
}
return 0;
});
// setting datasource of table from users
this.dataSource = new MatTableDataSource<UserItem>(this.users);
this.dataSource.sort = this.sort;
console.log(' this.dataSource', this.dataSource); // return is ok and complete cf screenshot
this.dataSource.sortingDataAccessor = (
element: any,
sortHeaderId: string
): string => {
if (typeof element[sortHeaderId] === 'string') {
return element[sortHeaderId].toLocaleLowerCase();
}
return element[sortHeaderId];
};
this.dataSource.paginator = this.paginator;
this.totalSize = this.users.length;
this.iterator();
}
// [...] + several functions : especially to update data
<mat-table [dataSource]="this.dataSource" class="mat-elevation-z8" matSort>
<!-- E-Mail Column -->
<ng-container matColumnDef="email">
<mat-header-cell *matHeaderCellDef mat-sort-header>
E-Mail
</mat-header-cell>
<mat-cell *matCellDef="let element"> {{ element.email }} </mat-cell>
</ng-container>
<!-- First Name Column -->
<ng-container matColumnDef="firstName">
<mat-header-cell *matHeaderCellDef mat-sort-header>
First Name
</mat-header-cell>
<mat-cell *matCellDef="let element"> {{ element.firstName }} </mat-cell>
</ng-container>
<!-- Last Name Column -->
<ng-container matColumnDef="lastName">
<mat-header-cell *matHeaderCellDef mat-sort-header>
Last Name
</mat-header-cell>
<mat-cell *matCellDef="let element"> {{ element.lastName }} </mat-cell>
</ng-container>
<!-- Rating Column -->
<ng-container matColumnDef="userRating">
<mat-header-cell *matHeaderCellDef mat-sort-header>
Rating
</mat-header-cell>
<mat-cell *matCellDef="let element" class="ratingCell">
{{ element.userRating }}
<button
class="editRatingButton"
mat-button
color="stroked"
*ngIf="element.userRating"
matTooltip="Edit user rating"
(click)="OpClExRatingEdit(element.userId)"
>
Edit
</button>
</mat-cell>
</ng-container>
<!-- [...] etc... more or less the same template for all the others columns -->
</mat-table>
<mat-paginator
#paginator
[pageSize]="pageSize"
[pageSizeOptions]="[5, 10, 100]"
[showFirstLastButtons]="true"
[length]="totalSize"
[pageIndex]="currentPage"
(page)="handlePage($event)"
></mat-paginator>
<!--some edit pop up-->
<div class="editPopup" *ngIf="editModeExpert">
<mat-card>
<form>
<!-- [...] -->
</form>
</mat-card>
</div>
<div class="editPopup" *ngIf="editModeClient">
<mat-card>
<form>
<!-- [...] -->
</form>
</mat-card>
</div>
<div class="editRatingPopup" *ngIf="editModeRating">
<mat-card>
<form>
<!-- [...] -->
</form>
</mat-card>
</div>
export interface UserItem {
email: string;
firstName: string;
lastName: string;
userId: string;
isValidated: boolean;
isAdmin: boolean;
hasCommunityAccess: boolean;
isPremiumCommunity: boolean;
userRating: number;
coreHour: number;
}
console log screenshot: enter image description here thank you !
Upvotes: 1
Views: 709
Reputation: 41
[resolved]
1/Sorting didn't work because (I didn't see...) 'this.dataSource' was also set in an other function: see below
private iterator() {
const end = (this.currentPage + 1) * this.pageSize;
const start = this.currentPage * this.pageSize;
const part = this.users.slice(start, end);
// this.dataSource = new MatTableDataSource<UserItem>(part); // init dataSource here create a bugg for the table's sorting
}
2/ Other pb I met. In another table. When I clicked on the sort arrow, that created new tables in my cell... very weird, the cells in my table were completely disorganized. Well, the solution:
In x.component.ts, change the 'trigger':
Insteed of:
trigger('detailExpand', [
state('collapsed', style({ height: '0px', minHeight: '0', display: 'none' })),
state('expanded', style({ height: '*' })),
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
])
try:
trigger('detailExpand', [
state('collapsed, void', style({ height: '0px', minHeight: '0', display: 'none' })),
state('expanded', style({ height: '*' })),
transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
transition('expanded <=> void', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)'))
])
(solution found on github.com)
Hope it will help somebody... !
Upvotes: 2