#Haro's data table
49 messages · Page 1 of 1 (latest)
Hi @upper prairie, you can use the following snippet to have your code formatted and syntax highlighted by Discord. Replace ts with the language you need (i.e. html, js, css, etc).
```ts
// your code goes here
```
hello
Hey, here we won't get interrupted with other questions 🙂
html data table:
<div class="container">
<mat-form-field appearance="fill">
<mat-label>Filter</mat-label>
<input matInput (keyup)="applyFilter($event)" placeholder="Search">
</mat-form-field>
<table mat-table [dataSource]="dataSource" matSort>
<ng-container *ngFor="let column of displayedColumns" [matColumnDef]="column">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ column | titlecase }} </th>
<td mat-cell *matCellDef="let element"> {{ element[column] }} </td>
</ng-container>
<ng-container matColumnDef="actions">
<td mat-cell *matCellDef="let element">
<button mat-icon-button color="primary" (click)="showFunction(element)">
<mat-icon>show</mat-icon>
</button>
<button mat-icon-button color="accent" (click)="updateFunction(element)">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button color="warn" (click)="deleteFunction(element)">
<mat-icon>delete</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator [pageSizeOptions]="pageSizeOptions" [pageSize]="pageSize"
[pageIndex]="currentPage" length="filteredData.length"
(page)="onPageChange($event)">
</mat-paginator>
</div>
yeepp its more nice
--ts data-table --:
import { Component, Input, OnInit, ViewChild,OnChanges, SimpleChanges } from '@topaz gulch/core';
import { MatPaginator, PageEvent } from '@topaz gulch/material/paginator';
import { MatTableDataSource } from '@topaz gulch/material/table';
import { MatSort } from '@topaz gulch/material/sort';
@Component({
selector: 'app-data-table',
templateUrl: './data-table.component.html',
styleUrls: ['./data-table.component.css']
})
export class DataTableComponent implements OnChanges {
@Input() displayedColumns: string[] = [];
@Input() data: any[];
@Input() updateFunction: Function;
@Input() deleteFunction: Function;
@Input() showFunction: Function;
dataSource: MatTableDataSource<any>;
filteredData: any[];
pageSizeOptions: number[] = [5, 10, 25];
pageSize: number = 5;
currentPage: number = 0;
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
initDataSource(data: any[]) {
this.filteredData = data;
console.log('Data:', data);
this.dataSource = new MatTableDataSource<any>(this.filteredData);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
}
ngOnChanges(changes: SimpleChanges) {
if(changes['data'].currentValue !== 'undefined') {
this.initDataSource(changes['data'].currentValue)
}
}
applyFilter(event: any) {
const filterValue = event.target.value.trim().toLowerCase();
console.log('Filter Value:', filterValue);
this.dataSource.filter = filterValue;
}
onPageChange(event: PageEvent) {
console.log('Page Event:', event);
this.currentPage = event.pageIndex;
this.pageSize = event.pageSize;
}
}
Ok, I see now why it gave the duplicate error. I was not aware you used ngFor to display the other columns
Give me a bit, I haven't worked with material tables in a while so need to check the documentation
tyt
do i need to send enterprise.html and ts?
No need I think, the reason why the column with buttons isn't displayed is in the data-table
ohh ok
This line: <tr mat-header-row matHeaderRowDef="displayedColumns"></tr> in your original code does not have the actions. So to change that, we need to make a new property just for displaying the correct header row
If you haven't done already, please change back the suggestion I made to add actions to the displayedColumns input property
so like this again: [displayedColumns]="['siren', 'name', 'city', 'postalCode', 'address', 'mail', 'phone']"
ok , i did that
ok, we're going to make a new property on the DataTableComponent class.
columnHeaders: string[];
columnHeaders: string[];
initDataSource(data: any[]) {
this.filteredData = data;
console.log('Data:', data);
this.dataSource = new MatTableDataSource<any>(this.filteredData);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
this.columnHeaders = [...this.displayedColumns, 'actions'];
}
see the last line in the method, we're assigning a new array with the contents of displayedColumns + 'actions'.
ohhhhhhhhh okkkkkk , nicee idea
Now in the html, change this line <tr mat-header-row matHeaderRowDef="displayedColumns"></tr> to <tr mat-header-row matHeaderRowDef="columnHeaders"></tr>
but what did this 3 points mean?
[...this.displayedColumns] means that we take the contents of the displayedColumns array and place them in the new array
See here for explanation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
The spread (...) syntax allows an iterable, such as an array or string, to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected. In an object literal, the spread syntax enumerates the properties of an object and adds the key-value pairs to the object being created.
So we're basically unpacking the contents of the array and place it in a new array with the added 'actions' string
eurror:Cannot read properties of undefined (reading 'template')
ohhh okkk nice
Ok, I think this also needs to change: <tr mat-rowmatRowDef="let row; columns: displayedColumns;"></tr> to <tr mat-rowmatRowDef="let row; columns: columnHeaders;"></tr>
okk i will check it
Are you still getting an error after changing the last html?
when u tell me to change the first , i change all the other with , maby thats why they give me the euror
Ok, can you post the code you have now so i can see what has changed?
<div class="container">
<mat-form-field appearance="fill">
<mat-label>Filter</mat-label>
<input matInput (keyup)="applyFilter($event)" placeholder="Search">
</mat-form-field>
<table mat-table [dataSource]="dataSource" matSort>
<ng-container *ngFor="let column of displayedColumns" [matColumnDef]="column">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ column | titlecase }} </th>
<td mat-cell *matCellDef="let element"> {{ element[column] }} </td>
</ng-container>
<ng-container matColumnDef="actions">
<td mat-cell *matCellDef="let element">
<button mat-icon-button color="primary" (click)="showFunction(element)">
<mat-icon>show</mat-icon>
</button>
<button mat-icon-button color="accent" (click)="updateFunction(element)">
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button color="warn" (click)="deleteFunction(element)">
<mat-icon>delete</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnHeaders"></tr>
<tr mat-row *matRowDef="let row; columns: columnHeaders;"></tr>
</table>
<mat-paginator [pageSizeOptions]="pageSizeOptions" [pageSize]="pageSize"
[pageIndex]="currentPage" length="filteredData.length"
(page)="onPageChange($event)">
</mat-paginator>
</div>
Give me a sec, i'm trying to recreate the table
tyt
Almost ready, running into some issues with typescript strict mode that I need to fix haha
thkk uu for ur timmeee
hmm, i'm also getting ERROR Error: Cannot read properties of undefined (reading 'template')
Not sure where it's coming from yet
maby from enterprise , ?
No, I have it working: https://stackblitz.com/edit/angular-ivy-ts-strict-enabled-zkf4bm?file=src%2Fapp%2Fdata-table%2Fdata-table.component.html,src%2Fapp%2Fdata-table%2Fdata-table.component.ts
Had to comment out the form because it gave me some errors, but the important part is in the table code
<table mat-table [dataSource]="dataSource" matSort>
<ng-container
*ngFor="let column of displayedColumns"
[matColumnDef]="column"
>
<th mat-header-cell *matHeaderCellDef mat-sort-header>
{{ column | titlecase }}
</th>
<td mat-cell *matCellDef="let element">{{ element[column] }}</td>
</ng-container>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Actions</th> // This was missing from your HTML
<td mat-cell *matCellDef="let element">
<button mat-icon-button color="primary" (click)="showFunction(element)">
<mat-icon>show</mat-icon>
</button>
<button
mat-icon-button
color="accent"
(click)="updateFunction(element)"
>
<mat-icon>edit</mat-icon>
</button>
<button mat-icon-button color="warn" (click)="deleteFunction(element)">
<mat-icon>delete</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="columnHeaders"></tr>
<tr mat-row *matRowDef="let row; columns: columnHeaders"></tr>
</table>
``` There were also some `*` missing in front of some of the directives like `matCellDef`. These are important, because it makes the directive a structural directive (meaning it can alter the html structure))
So to recap: we had to make sure all the headers were properly set (by adding 'actions' to it) and with <th mat-header-cell *matHeaderCellDef mat-sort-header>Actions</th> to make sure there was a header present for the actions column