All I'm trying to do is display a certain value if the item has a certain property, but all I end up with is [object Object]. This is my approach.
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef> Given Name </th>
<td mat-cell *matCellDef="let item">
<div *ngIf="item.hasOwnProperty('value'); else default">
// Display something else
</div>
<ng-template #default>
{{item.name}}
</ng-template>
</td>
</ng-container>
You could simply write *ngIf="item.value" if the property is mandatory for the item that should have it.
Else, if the value property is present even when it is not filled (Which should not happen btw), then you could edit your items with a boolean in your .ts file, something like :
ngOnInit() {
// To do before to set the data in your table
this.data = this.data.map(item => ({
...item,
hasValueProp: item.hasOwnProperty('value'),
}));
}
then in your html template you'll condition it like:
*ngIf="item.hasValueProp"
Related
in my code I get an image of the API (row. fotoPessoa), if I don't have an image I put another one in place ([src] = "imgPessoa"). How to do this?
<ng-container matColumnDef="fotoIndividuo">
<th mat-header-cell *matHeaderCellDef > Foto </th>
<td mat-cell *matCellDef="let row" data-label="Foto: " >
<img [src]="imgPessoa" >
{{row.fotoPessoa}}
</td>
</ng-container>
I have a mat-toggle as a column in Mat-table.I am changing values on toggle on/off. However the issue is if I change the value then the value changes for all the rows. I want to do it only for the particular row. How can I do it.
HTML Code:
<ng-container matColumnDef="active">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Reschedule</th>
<td mat-cell *matCellDef="let element">
<mat-slide-toggle (change)="setMessage($event)">{{
message
}}</mat-slide-toggle>
</td>
</ng-container>
Typescript Code:
// Toggle Button Code
message = 'Disabled!';
setMessage(e) {
if (e.checked) {
this.message = 'Running';
} else {
this.message = 'Disabled!';
}
}
You need a property for every row to bind your toggle state to.
E.g.:
Component data:
....
const ELEMENT_DATA: PeriodicElement[] = [
{ position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H', activate: true, role: '1' },
...
Template:
...
<!-- toggle olumn -->
<ng-container matColumnDef="toggle">
<th mat-header-cell *matHeaderCellDef> toggle </th>
<td mat-cell *matCellDef="let element" >
<mat-slide-toggle [checked]="element.activate" (change)="updateActiveStatus(element)"></mat-slide-toggle>
</td>
</ng-container>
...
Check this Stackblitz for a working version.
How to push new values at the click of a button in formArray without adding new fields. Fields already exist, which means I don't need new ones, I just need new values from those fields entered.
Look at my code:
<form [formGroup]="form" (submit)="submit()">
<div *ngFor="let data of contactFormGroup.controls; let i = index;" formArrayName="data">
<div [formGroupName]="i">
<mat-form-field>
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Pretraži prozivod...">
</mat-form-field>
<table mat-table [dataSource]="productSource" matSort class="mat-elevation-z8">
<!-- Position Column -->
<ng-container matColumnDef="id">
<th mat-header-cell mat-sort-header *matHeaderCellDef> Broj Proizvoda </th>
<td mat-cell *matCellDef="let element" > {{ element.id }} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="name">
<th mat-header-cell mat-sort-header *matHeaderCellDef> Naziv proizvoda </th>
<td mat-cell *matCellDef="let element"> {{ element.name }} </td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="description">
<th mat-header-cell mat-sort-header *matHeaderCellDef> Opis proizvoda </th>
<td mat-cell *matCellDef="let element"> {{element.description}} </td>
</ng-container>
<!-- quantity Column -->
<ng-container matColumnDef="images" class="test" >
<th mat-header-cell mat-sort-header *matHeaderCellDef> quantity</th>
// i need this values but on click add new object in formArray
<td mat-cell *matCellDef="let element" class="test"> <input formControlName="quantity" type="text"> </td>
</ng-container>
<ng-container matColumnDef="images2">
<th mat-header-cell mat-sort-header *matHeaderCellDef> Add new </th>
<td mat-cell *matCellDef="let element"> <button mat-raised-button color="primary">Add new</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr (click)="test(row.id)" mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator [pageSizeOptions]="[5,10,20]" showFirstLastButtons></mat-paginator>
<div class="button-submit">
<button (click)="openDialog2()" mat-raised-button color="warn">
Posalji narudzbu
</button>
</div>
</div>
</div>
</form>
Ts file:
ngOnInit() {
this.productSource.sort = this.sort;
this.productSource.paginator = this.paginator;
this.getProducts();
this.form = this.fb.group({
deliveryDate: [''],
data: this.fb.array([this.createContact()]),
note: [null]
});
this.contactList = this.form.get('data') as FormArray;
}
createContact(): FormGroup {
return this.fb.group({
id: ['', Validators.required],
quantity: ['', Validators.required]
});
}
addContact() {
this.contactList.push(this.createContact());
}
This code works well when I set fields and add function addContact(). When click show new fields and work good but in this situation, I don't want new fields. I have existing fields only to enter a quantity and push id and quantity in new FormArray.
This is an example what I need: https://ibb.co/1Tj2HNc
ON click button add new. If you have any question just ask
The current code works on principle when I add the first product:
console.log(my form.values)
data: Array(1)
0: {id: "", quantity: "99"}
And this is good only need id but ok... But when I add new quantity for new fields example 15 for another field and console.log my form values:
data: Array(1)
0: {id: "", quantity: "15 "}
override the old value and enter the new value.
It should add a new object in array with that value.
Example:
data: Array(2)
0: {id: "", quantity: "99"}
1: {id: "", quantity: "15"}
Also i need id :)
EDIT:
I forgot a piece of code:
get contactFormGroup() {
return this.form.get('data') as FormArray;
}
just create new function that accepts the index you want to insert the data into and the object you want to insert and it should do what you want.
assignContactForm(index: number, data: any): void {
// data is object of type {id: number, quantity: number }
this.contactFormGroup.controls[i].patchValue(data);
}
I have such issue I need to extract data from:
<ng-container matColumnDef="title">
<th mat-header-cell *matHeaderCellDef> Title </th>
<td mat-cell *matCellDef="let row"><div id="{{'make_editable' + row.title}}">{{row.title}}</div></td>
</ng-container>
...
<ng-container matColumnDef="buttonEdit">
<th mat-header-cell *matHeaderCellDef> buttonEdit </th>
<td mat-cell *matCellDef="let row"><button (click)="makeEditable(row.title)" class="mat-raised-button" form="myform">Edit</button></td>
/ng-container>
makeEditable(title){
console.log(this.checkOutForm.value.title);
let id:string="make_editable"+title;
if(this.toggleEdit()){
document.getElementById(id).innerHTML = `<form id="myform" (ng-submit)="extractFormValues()" [formGroup]="checkOutForm"><input type="text" value="${title}"></form>`;
}
else {
document.getElementById(id).innerHTML = title;
console.log(this.checkOutForm.controls.title.value);
}
The button is outside the function. If edit button is clicked then input wraps data and make it active. I need to do it without refreshing all page.The button Edit is outside of the form
You could create on the type, that the rows have, a boolean property - isEdited.
makeEditable(title) would find the correct row and toggle its isEdited value. It would also set:
checkOutForm.setValue({title: title});
(if isEdited was set to true).
In the template you would wrap the whole block in
<form id="myform" (ng-submit)="extractFormValues()" [formGroup]="checkOutForm"</form>
and change the td for a title:
<td mat-cell *matCellDef="let row">
<div *ngIf="!row.isEdited">{{row.title}}</div>
<input *ngIf="row.isEdited" type="text" formControlName="title">
</td>
This only works if just one row is edited at once.
my previous question was not clear. Allow me to ask again clearly as I'm struggling complete my task.
I've mat-table along with checkbox for every row. (No master checkbox). whenever I select the row I should send the values of the selected row to button which is outside of the table.
[if I have a button inside the table, I could do that by accessing the default ELEMENT from *matCellDef="let element" variable if the button present inside the table.
But I don't know how to pass the selected row value to the button. I've to do routing based on the value from the selected row.
so far I've.
HTML
<div><button mat-button [disabled]="!checkedbtn" (click)='linktomynxtpage()'>link to another page</button></div>
<table #demoTable mat-table [dataSource]="sample" multiTemplateDataRows>
// some ng-container with <th><td>
<ng-container *ngIf="isAdmin" matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef> Action </th>
<td mat-cell *matCellDef="let element">
<mat-checkbox class="select-checkbox" [(ngModel)]="checkedbtn" ></mat-checkbox>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row style="text-align:left" *matRowDef="let element; columns: displayedColumns;" ></tr>
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="detail-row"></tr>
</table>
TS
linktomynxtpage(){
//some logics
//passing row value. and doing routing
this.nxtPage.navigate(['/home/particular-user'])
}
use the (change) event
<mat-checkbox class="select-checkbox" [(ngModel)]="checkedbtn" (change)="onChange(element)" ></mat-checkbox>
onChange(row){
// put the row whenever you want
}