#Haro's data table

49 messages · Page 1 of 1 (latest)

upper prairie
#

@dire fiber, let's continue here to keep the conversation in one place without interruptions from other questions.

Can you copy/paste the entire html for the data table? You can use codeblocks for syntax highlighting

#

g!codeblock

sonic mossBOT
#

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
```

dire fiber
#

hello

upper prairie
#

Hey, here we won't get interrupted with other questions 🙂

dire fiber
#

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>

dire fiber
#

--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;
}

}

upper prairie
#

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

dire fiber
#

do i need to send enterprise.html and ts?

upper prairie
#

No need I think, the reason why the column with buttons isn't displayed is in the data-table

upper prairie
#

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']"

upper prairie
#

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'.

dire fiber
upper prairie
#

Now in the html, change this line <tr mat-header-row matHeaderRowDef="displayedColumns"></tr> to <tr mat-header-row matHeaderRowDef="columnHeaders"></tr>

dire fiber
#

but what did this 3 points mean?

upper prairie
#

[...this.displayedColumns] means that we take the contents of the displayedColumns array and place them in the new array

#

So we're basically unpacking the contents of the array and place it in a new array with the added 'actions' string

dire fiber
#

eurror:Cannot read properties of undefined (reading 'template')

upper prairie
#

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>

upper prairie
#

Are you still getting an error after changing the last html?

dire fiber
upper prairie
#

Ok, can you post the code you have now so i can see what has changed?

dire fiber
#

<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>

upper prairie
#

Give me a sec, i'm trying to recreate the table

upper prairie
#

Almost ready, running into some issues with typescript strict mode that I need to fix haha

dire fiber
#

thkk uu for ur timmeee

upper prairie
#

hmm, i'm also getting ERROR Error: Cannot read properties of undefined (reading 'template')

#

Not sure where it's coming from yet

dire fiber
#

maby from enterprise , ?

upper prairie
#

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

dire fiber
#

it shows up , thankk u

#

👏 i dont know how can thank u , but thankkkk u very much