I have a mat-table with whole row click:
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" (click)="clickHandler(row)"></tr>
And I have click on certain row in this table:
<ng-container matColumnDef="test">
<th mat-header-cell *matHeaderCellDef mat-sort-header> test </th>
<td mat-cell *matCellDef="let row" (click)="getRecord(row)"> {{row.test}} </td>
</ng-container>
How I can disable click on whole row((click)="clickHandler(row)") when I click on certain
cell (click)="getRecord(row);
You can send $event to getRecord method and call stopPropagation(); of the event:
getRecord(row,$event){
$event.stopPropagation();
....
}
And in your HTML:
<td mat-cell *matCellDef="let row" (click)="getRecord(row,$event)">
Here is working sample I create for you: StackBlitz
Related
I have a table where a column is a text input.
When the user edits the text both a save and cancel button became enabled.
The save button should just send the new value to the server. I can do that one no problem.
But the cancel button I can't figure out how to change the input back. Because with both model or a child element how do I know which element of the table I'm writing in?
The template part:
<table mat-table [dataSource]="gsServersDataSource" class="mat-elevation-z8">
<tr mat-header-row *matHeaderRowDef="gsServersHeaders"></tr>
<tr mat-row *matRowDef="let row; columns: gsServersHeaders;"></tr>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef > Name </th>
<td mat-cell *matCellDef="let element" > {{element.name}} </td>
</ng-container>
<ng-container matColumnDef="value">
<th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription="Sort by value"> Value </th>
<td mat-cell *matCellDef="let element">
<input id="valueInput" type="text" value="{{element.value}}" (keyup)="onChangeValue()">
</td>
</ng-container>
<ng-container matColumnDef="modify">
<th mat-header-cell *matHeaderCellDef> Modify </th>
<td mat-cell *matCellDef="let element">
<button id="saveChanges" mat-mini-fab color="primary" (click)="onClickSave()" [disabled]="disabled">
<mat-icon>✓</mat-icon>
</button>
<button id="cancelChanges" mat-mini-fab color="primary" (click)="onClickCancel(element)" [disabled]="disabled">
<mat-icon>X</mat-icon>
</button>
</td>
</ng-container>
</table>
The component part:
gsServersDataSource = [{name: 'name1', value: 'value1'}];
gsServersHeaders: string[] = ['name', 'value', 'modify'];
disabled=true;
onChangeValue(){
this.disabled=false;
}
onClickSave(element: InstanceDataPoint){
//service call with new value
this.disabled=true;
}
onClickCancel(element: InstanceDataPoint){
//Put original back : How to??
this.disabled=true;
}
}
I created another value for each line that contains the temporary value the user inputted.
When the user wants to save it, it will be posted and on success saved as the original value.
When the user wants to cancel the changes. The temporary value will be reset to the original value.
On the template I'm now using the newValue as the value of the text input.
And I'm passing to the keyup hook the inputted value
<ng-container matColumnDef="value">
<th mat-header-cell *matHeaderCellDef mat-sort-header sortActionDescription="Sort by value"> Value </th>
<td mat-cell *matCellDef="let element">
<input id="valueInput" type="text" value="{{element.newValue}}" (keyup)="onChangeValue(element,$event.target.value)">
</td>
</ng-container>
On the component, I'm now saving the inputted value to the newValue on changes to the text input.
On clicking save I'm assigning the newValue to the originalValue if the post is successful.
And on clicking cancel I'm putting the newValue back to the originalValue.
onChangeValue(element: InstanceDataPoint, newValue: string){
element.disabled = false;
element.newValue = newValue;
}
onClickSave(element: InstanceDataPoint){
this.gsInstancesService.postModifiedValue(this.selectedEnvironment,
{ "param-name": element.name, "param-val": element.newValue, "server-id": element.server, "language": element.language}).
subscribe({complete: ()=>element.value=element.newValue});
element.disabled=true;
}
onClickCancel(element: InstanceDataPoint){
element.newValue = element.value;
element.disabled = true;
}
im trying to show a list of products, and it does, but the problem is it freeze for 6 or 8 seconds, tha size of the register is 2338, im using entity framework to obtain the register, some idea to solve or optimize
this is the method to get the list from the other class and there i obtain from the entity framework
getProveedor(){
this.apiproveedor.getProveedor().subscribe(response=>{
console.log(response.data);
if(response.exito==1){
this.lst=response.data;
this.resultsLength=this.lst.length;
this.dataSource=response.data;
}
});
getProveedor():Observable<Response>{
return this._http.get<Response>(this.url);
}
this is the html, im using a mat table
<!--
-->
<div>
<mat-toolbar >
<span >Pharmacy Lion</span>
<img src="./assets/img/2.png" class="tama">
</mat-toolbar>
<div>
<a mat-raised-button color="primary" (click)="openAdd()">Nuevo Producto</a>
</div>
<mat-form-field appearance="standard">
<mat-label>Filter</mat-label>
<input matInput placeholder="Buscar Nombre" #input (keyup)="applyFilter($event)">
</mat-form-field>
<table mat-table [dataSource]="lst" class="table"
matSort matSortActive="created" matSortDisableClear matSortDirection="desc">
<ng-container matColumnDef ="IdProducto" class="header-align-right"
mat-sort-header disableClear>
<th mat-header-cell *matHeaderCellDef mat-sort-header >#</th>
<td mat-cell *matCellDef="let element">{{element.idProducto}}</td>
</ng-container>
<ng-container matColumnDef ="Nombre" >
<th mat-header-cell *matHeaderCellDef mat-sort-header class="header-align-right" >Nombre Producto</th>
<td mat-cell *matCellDef="let element" class="header-align-right">{{element.nombre}}</td>
</ng-container>
<ng-container matColumnDef ="Cantidad">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="header-align-right"> Cantidad </th>
<td mat-cell *matCellDef="let element" class="header-align-right">{{element.cantidad}}</td>
</ng-container>
<ng-container matColumnDef ="Descripcion">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="header-align-right">Descripcion</th>
<td mat-cell *matCellDef="let element" class="header-align-right">{{element.descripcion}}</td>
</ng-container>
<ng-container matColumnDef ="Precio">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="header-align-right">Precio</th>
<td mat-cell *matCellDef="let element" class="header-align-right">{{element.precio}}</td>
</ng-container>
<ng-container matColumnDef ="Acciones">
<th mat-header-cell *matHeaderCellDef class="header-align-right margencab" >Acciones</th>
<td mat-cell *matCellDef="let element" class="header-align-right ">
<button (click)="Edit(element)" mat-raised-button color="primary" class="margencab">Editar</button>
<button (click)="delete(element)" mat-raised-button color="Basic" class="margencab">Eliminar</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="Columnas"></tr>
<tr mat-row *matRowDef="let row; columns Columnas"></tr>
</table>
</div>
You could try implementing lazy loading of data, which is mentioned in material docs.
You can implementing server side pagination. You need to send page size and page number along with your existing query parameters. In this way it will be more scalable no matter how many data you have cause you are dealing with small chunk of data each request.
you can find a lot of examples out there. With a quick search I found this article one that seems easier to understand
You could also try to implement virtual-scroller provided by material angular CDK (Common Development Kit).
You can find the details here.
I'm trying to create a custom Angular Material Table, more exactly, to split one column in 5 columns like here:
The first row with No, Name, Weight and Symbol (with the 5 columns) represent the header of the table. How can I split the Symbol column in 5 columns?
My code is that one from Angular Material:
<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource">
<!-- Position Column -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef>No.</th>
<td mat-cell *matCellDef="let element">{{ element.position }}</td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>Name</th>
<td mat-cell *matCellDef="let element">{{ element.name }}</td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="weight">
<th mat-header-cell *matHeaderCellDef>Weight</th>
<td mat-cell *matCellDef="let element">{{ element.weight }}</td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef>Symbol</th>
<td mat-cell *matCellDef="let element">{{ element.symbol }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
<mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons aria-label="Select page of periodic elements"> </mat-paginator>
</div>
I had to do a similar thing this week and I put together a Stackblitz to play around and have something working that might help?
https://stackblitz.com/edit/generic-mat-table-kji9ey?file=src%2Fapp%2Fapp.component.html
The key seems to be to configure the two header rows with colspan and rowspan attributes for the resultant columns
This answer was useful too:
https://stackoverflow.com/a/59626423/2928193
I am attempting to add row-deletion into my <mat-table>. Most of the table is working fine, except the checkbox column is not showing up. Previously, the code did not contain the <!-- Checkbox/Selection Column --> section. I added it in using one of the examples on angular.material.io.
Im a bit confused, because it looks to me like the pattern should be a <th> & <td> wrapped inside an <ng-container>. I seem to be missing something here, because the checkbox/selection column isn't showing up, there aren't any errors in the browser console, and there aren't any errors being thrown at ng serve in powershell.
<table mat-table [dataSource]="dataSource" matSort>
<!-- Checkbox/Selection Column -->
<ng-container matColumnDef="select">
<th mat-header-cell *matHeaderCellDef>
<mat-checkbox [checked]="false" [aria-label]="checkboxLabel()">
</mat-checkbox>
</th>
<td mat-cell *matCellDef="let row">
<mat-checkbox [checked]="true"></mat-checkbox>
</td>
</ng-container>
<!-- Working Columns -->
<ng-container *ngFor="let field of Fields" matColumnDef="{{field.name}}">
<th class="w-134" mat-header-cell *matHeaderCellDef mat-sort-header>{{field.name}}</th>
<td class="w-130" mat-cell *matCellDef="let row">
<input *ngIf="field.editType == 'free'" matInput [(ngModel)]="row[field.name]" placeholder="{{row[field.name]}}" required>
<mat-select *ngIf="field.editType == 'spinner'" [(ngModel)]="row[field.name]">
<mat-option *ngFor="let option of field.options" [value]="option">{{option}}</mat-option>
</mat-select>
<div class="checkbox-cell" (click)="toggleBoolean(row, field.name)">
<mat-checkbox *ngIf="field.editType == 'checkbox'" [(ngModel)]="row[field.name]" (click)="toggleBoolean(row, field.name)"></mat-checkbox>
</div>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="ColumnHeaders"></tr>
<tr mat-row *matRowDef="let row; columns: ColumnHeaders;"></tr>
</table>
Seems like you did not added the column in your ColumnHeaders array inside TS file.
ColumnHeaders = ['select'] //ColumnHeaders should have an entry of select(your checkbox column defintion)
yes you have to add select inside displayedColumns
displayedColumns: string[] = ['select','position', 'name','gender', 'weight', 'symbol'];
I have the following code :
<ng-container matColumnDef="compare" >
<th mat-header-cell *matHeaderCellDef mat-sort-header> Compare </th>
<!--<td mat-cell *matCellDef="let protocol"><i class="material-icons">favorite_border</i></td>-->
<td mat-cell *matCellDef="let experiment" (click)="$event.stopPropagation()" >
<button mdcIconButton [on]="true">
<mdc-icon mdcIconOn #content onClick="onSelect(1, experiment)">radio_button_unchecked</mdc-icon>
<mdc-icon onClick="onSelect(2, experiment)">radio_button_checked</mdc-icon>
</button>
</td>
</ng-container>
which is working but sometimes it has delay and do not get it when I select a radio button, and this is a problem. Usually when I choose slowly, it gets it.
I wanted to know if there was another simple way to do a toggle switch like this one, without using mdc-icon because apparently it's a problem. I don't understand how to use ng-switch for exemple...
I tried this :
<ng-container matColumnDef="compare" >
<th mat-header-cell *matHeaderCellDef mat-sort-header> Compare </th>
<!--<td mat-cell *matCellDef="let protocol"><i class="material-icons">favorite_border</i></td>-->
<td mat-cell *matCellDef="let experiment" (click)="$event.stopPropagation()" >
<button (click)='onSelect(1, experiment)'>Select</button>
<button (click)='onSelect(2, experiment)'>Unselect</button>
</td>
</ng-container>
and it confirms the problem is coming from the mdc-icon, because it works quickly and gets my selections.
But obviously it's ugly and not switching.