I have a stackblitz as a guide.
I am wanting to display a list of material cards that I click an 'edit' button, to which I can edit text fields, and when I click on the 'save' icon, it of course saves by triggering an function etc.
I am struggling however to get to grips with how this all works within Angular and the Material nature of my app.
html
<form id="myForm" [formGroup]="thisIsMyForm">
<mat-card [formGroup]="x" *ngFor="let x of data; let i = index">
<mat-form-field>
<label for="{{x.name}}">Name</label>
<input formControlName="name" id="{{x.name}}" matInput value="{{x.name}}">
</mat-form-field>
<mat-form-field>
<label for="{{x.type}}">Type</label>
<input formControlName="type" id="{{x.type}}" matInput value="{{x.type}}"/>
</mat-form-field>
</mat-card>
</form>
ts
import { Component, ViewChild } from '@angular/core';
import {MatSnackBar} from '@angular/material';
import {FormArray, FormBuilder, FormGroup, Validators} from '@angular/forms';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
thisIsMyForm: FormGroup
data = [
{name:"one", type:"one"},
{name:"two", type:"two"},
{name:"three", type:"three"},
];
constructor(private formBuilder: FormBuilder) {}
onSubmit() {
// Here I would like to be able to access the values of the 'forms'
}
}
Doing it with
QueryList
:your html (this is an example):
some css just for the style
the component:
Working stackblitz: https://stackblitz.com/edit/angular-j2n398?file=src%2Fapp%2Fapp.component.ts
You are diving into the deep end for sure, trying to build a dynamic reactive form within the scope of an
*ngFor
is a challenge. I will walk you through it the best I can.You will need to create an array for controls, in your constructor create your form setting
formArrayName
as an empty array usingthis.formBuild.array([])
... call this whatever you want, I just usedformArrayName
for demonstration purposes.After the form is instantiated with an empty array call
this.buildForm()
In your
buildForm()
iterate over yourdata[]
and push controls for each index while assigning the default value and a default state of disabled.Please Note: console.log(controlArray.controls) results in the following output... each index is a FormGroup with two controls
name
andtype
In your html you will need to establish a container hierarchy that mimics the
thisIsMyForm
you just created.thisIsMyForm
formArrayName
i as formGroupName
grandchild is important because it matches the console log of
controlArray.controls
in previous stepCreate edit and save buttons based on control disabled state
Create methods in component to receive the index as an argument and handle logic to hide buttons and toggle input fields enable and disable state.
Submit button that console.log's the form value when clicked... also disable button while any of the input formControls are in enabled state.
Stackblitz
https://stackblitz.com/edit/dynamic-form-ngfor-otbuzn?embed=1&file=src/app/app.component.ts