I have a mat-table and one of the column heading is having an edit icon/button, on click of which all the values of the third column are converted into input fields. I just want to set the same value in the input fields as well.
I have tried this.
<ng-container matColumnDef="amount">
<th mat-header-cell *matHeaderCellDef>Amount
<button mat-icon-button (click)="onEditClick(datasource)">
<mat-icon style="cursor: pointer;" >edit</mat-icon>
</button>
</th>
<td mat-cell *matCellDef="let row; let i=index;">
<ng-container *ngIf="isActual">{{row.amount || "-- --"}}</ng-container>
<mat-form-field *ngIf="isEditMonth" appearance="outline">
<input matInput type="text" [formControl]="amountField" (change)="onAmountChanged($event,row)" [ngModel]=row.amount>
</mat-form-field>
</td>
</ng-container>
//ts code
amountField = new FormControl('', Validators.compose([Validators.min(0)]));
onEditClick() {
if (this.isEditMonth) {
this.loadCharges();
this.isEditMonth = false;
this.isActual = true;
}
else {
this.isEditMonth = true;
this.isActual = false;
}
}
Please check my stackbiltz code. enter link description here
CodePudding user response:
If you press edit, you have formControl and ngModel in your input-element. Thats why you have a data binding conflict.
So if you remove your formControl, you will get your correct data-binding and it will show correct values.
CodePudding user response:
For this you have to dynamically build a group of FormControls for the available length of your array.
HTML
<form [formGroup]="elementForm" id="ngForm" #form="ngForm">
<div [formGroupName]="'amountFields'">
<table mat-table [dataSource]="dataSource" >
<ng-container matColumnDef="unit">
<th mat-header-cell *matHeaderCellDef>Unit.</th>
<td mat-cell *matCellDef="let element">{{ element.unit }}</td>
</ng-container>
<ng-container matColumnDef="accountNo">
<th mat-header-cell *matHeaderCellDef>Account No.</th>
<td mat-cell *matCellDef="let element">{{ element.accountNo }}</td>
</ng-container>
<ng-container matColumnDef="amount">
<th mat-header-cell *matHeaderCellDef>
Amount
<button mat-icon-button (click)="onEditClick()">
<mat-icon style="cursor: pointer;" >edit</mat-icon>
</button>
</th>
<td mat-cell *matCellDef="let element">
<ng-container *ngIf="isActual">{{ element.amount }}</ng-container>
<mat-form-field
appearance="outline"
*ngIf="isEditMonth">
<input
matInput
appearence="fill"
type="text"
[formControlName]="element.accountNo"
(change)="onAmountChanged($event, element)"
/>
</mat-form-field>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
</div>
</form>
TS
import { OnInit, Component, VERSION } from '@angular/core';
import {
FormGroup,
FormControl,
Validators,
FormBuilder,
} from '@angular/forms';
export interface PeriodicElement {
accountNo: string;
unit: number;
amount: number;
}
const ELEMENT_DATA: PeriodicElement[] = [
{ unit: 1, accountNo: 'Hydrogen', amount: 20 },
{ unit: 2, accountNo: 'Helium', amount: 10 },
{ unit: 3, accountNo: 'Lithium', amount: 50 },
];
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
constructor(private formBuilder: FormBuilder) {}
name = 'Angular ' VERSION.major;
isActual: boolean = true;
isEditMonth: boolean = false;
amountFieldsFormGroup: FormGroup = this.formBuilder.group([]);
public elementForm: FormGroup = new FormGroup({
amountFields: this.amountFieldsFormGroup,
});
amountField = new FormControl('', Validators.compose([Validators.min(0)]));
displayedColumns: string[] = ['unit', 'accountNo', 'amount'];
dataSource = ELEMENT_DATA;
ngOnInit() {
this.createFormValues();
console.log(this.elementForm);
}
private createFormValues(): void {
this.dataSource.forEach((element: PeriodicElement) => {
this.amountFieldsFormGroup.addControl(
element.accountNo,
this.createElementFormControl(element.amount)
);
});
}
private createElementFormControl(amount: number): FormControl {
return new FormControl(
{ value: amount, disabled: false },
{ validators: Validators.nullValidator }
);
}
onEditClick() {
if (this.isEditMonth) {
this.isEditMonth = false;
this.isActual = true;
} else {
this.isEditMonth = true;
this.isActual = false;
}
}
onAmountChanged(e, elem) {}
}
Change it for your needs...
Thanks.