I'm getting some data from backend and displaying it in my UI. The problem is I want to be able to modify each row's input field and checkbox and then submit the whole form and process the information.
I can render the page, no problem, but I have no clue where to start with creating the FormArray and how to place them in my HTML to be able to click on the save button and submit the entire form.
Here is my type script code
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { AttributeSetRootObject } from '../../models/attribute-set.model';
import { AttributeSetService } from '../../services/attribute-set.service';
@Component({
selector: 'app-attribute-set-standard',
templateUrl: './attribute-set-standard.component.html',
styleUrls: ['./attribute-set-standard.component.scss'],
})
export class AttributeSetStandardComponent implements OnInit {
attributeSets: AttributeSetRootObject;
attributeSetForm: FormGroup;
displayedColumns = [
'attributeName',
'englishLabel',
'frenchLabel',
'dataType',
'fieldType',
'defaultValue',
'mandatoryIndicator',
];
constructor(
private route: ActivatedRoute,
private attributeSetService: AttributeSetService,
private fb: FormBuilder
) {}
ngOnInit(): void {
const attributeSetId = parseInt(this.route.snapshot.paramMap.get('id'));
console.log(attributeSetId);
this.attributeSetForm = this.fb.group({
defaultValue: [],
mandatory: [],
});
this.attributeSetService.getStandardAttributes(attributeSetId).subscribe({
next: (data: AttributeSetRootObject) => {
console.log(data);
this.attributeSets = data;
},
});
}
onSubmit() {
console.log(this.attributeSetForm.value);
}
}
HTML Code
<app-breadcrumb [crumbs]="attributeSets?.data.parentlinks"></app-breadcrumb>
<div >
<h3>{{ "ATTRIBUTE-SET.STANDARD-ATTRIBUTES-TITLE" | translate }}</h3>
<div *ngIf="attributeSets?.data?.attributes?.length">
<form [formGroup]="attributeSetForm" (ngSubmit)="onSubmit()">
<table
mat-table
#attributeSetSort="matSort"
[dataSource]="attributeSets.data.attributes"
matSort
matSortDisableClear
>
<ng-container matColumnDef="attributeName">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
Attribute Name
</th>
<td mat-cell *matCellDef="let element">
{{ element.attributeName }}
</td>
</ng-container>
<ng-container matColumnDef="englishLabel">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
English Label
</th>
<td mat-cell *matCellDef="let element">
{{ element.englishLabel }}
</td>
</ng-container>
<ng-container matColumnDef="frenchLabel">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
French Label
</th>
<td mat-cell *matCellDef="let element">
{{ element.frenchLabel }}
</td>
</ng-container>
<ng-container matColumnDef="dataType">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Data Type</th>
<td mat-cell *matCellDef="let element">
{{ element.dataType }}
</td>
</ng-container>
<ng-container matColumnDef="fieldType">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Field Type</th>
<td mat-cell *matCellDef="let element">
{{ element.fieldType }}
</td>
</ng-container>
<ng-container matColumnDef="defaultValue">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
Default Value
</th>
<td mat-cell *matCellDef="let element">
<mat-form-field>
<mat-label
>{{ "ATTRIBUTE-SET.DEFAULT-VALUE" | translate }}
</mat-label>
<input
type="text"
matInput
formControlName="defaultValue"
[value]="element.defaultValue"
/>
</mat-form-field>
</td>
</ng-container>
<ng-container matColumnDef="mandatoryIndicator">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Mandatory</th>
<td mat-cell *matCellDef="let element">
<mat-checkbox
formControlName="mandatory"
[checked]="element.mandatoryIndicator === 'Y'"
></mat-checkbox>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
</table>
<button mat-raised-button color="primary">
{{ "BUTTONS.SAVE" | translate }}
</button>
</form>
</div>
</div>
The UI
This is how the page looks like
Right now when I click on save, it only submits one value. I would like to be able to submit all the values for the form.
CodePudding user response:
You can check the https://material.angular.io/components/table/overview link. They have sample forms with code. Try to read Angular Material Documentation too.
CodePudding user response:
When we work with a FormArray when not use in the "clasic way" we can simply use <input [formControl]="...">
To get the formControl we can use a function. e.g. you can use
formArray:FormArray;
getControl(index: number, controlName: string): FormControl {
return (this.formArray.at(index) as FormGroup)
.get(controlName) as FormControl;
}
Now you can define your "cells" like
<ng-container matColumnDef="defaultValue">
<th mat-header-cell *matHeaderCellDef mat-sort-header>
Default Value
</th>
<td mat-cell *matCellDef="let element;let i = index">
<input
type="text"
matInput
[formControl]="getControl(i,'defaultValue')"
/>
</td>
</ng-container>
<ng-container matColumnDef="mandatoryIndicator">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Mandatory</th>
<td mat-cell *matCellDef="let element;let i=index">
<mat-checkbox
[formControl]="getControl(i,'mandatory')"
></mat-checkbox>
</td>
</ng-container>
See that not use value in the check. You should create the formArray mapping the dataSource.data
formArray = new FormArray(
this.attributeSets.data.attributes.map(
(x:any) =>
new FormGroup({
defaultValue: new FormControl(x.defaultValue),
mandatory: new FormControl(x.mandatory == 'yes' ? true : false),
})
)
);