Issue
I have written a custom FormGroup as AddLayerFormGroup
and custom control CustomFormControl
:
Custom Control
export class CustomFormControl extends FormControl {
public label: string;
public name: string;
public type: string;
constructor(
name,
options = [],
customOptions = <CustomFormControlOptions>{}
) {
super(name, options);
this.setLabel(customOptions.name);
this.setName(customOptions.field);
this.setType(customOptions.type);
}
setLabel(label: string) {
this.label = label;
}
setName(name: string) {
this.name = name;
}
setType(type: string) {
this.type = type;
}
}
Custom form group:
export class AddLayerFormGroup extends FormGroup {
private formArray = new FormArray([]);
constructor(options = {}) {
super(options);
}
createControls(fields: any) {
this.addControl("items", this.formArray);
fields
.filter((field) => !!field.htmlInputAttr)
.forEach((field) => {
this.formArray.push(this.getControl(field));
});
}
getControl(_fields: any): CustomFormControl {
const { htmlInputAttr, value, field, name } = _fields;
const { type } = htmlInputAttr;
const control = new CustomFormControl(name, [], { name, field, type });
if (value) {
control.setValue(value);
}
if (htmlInputAttr?.required) {
control.setValidators([Validators.required, ValidateEmpty]);
}
if (htmlInputAttr?.disabled) {
control.disable();
}
return control;
}
getControls() {
return this.controls.items["controls"];
}
}
I try to use it like:
HTML template where controls iterates
<form [formGroup]="addLayerForm">
<ol-edit-field *ngFor="let control of addLayerForm.getControls()"
[formGroup]="addLayerForm"
[formControl]="control">
</ol-edit-field>
</form>
The component where I pass control:
<input autocomplete="off"
[formGroupName]="formControl"
type="text"
pInputText
/>
I got the error:
ERROR Error: No value accessor for form control with unspecified name attribute. ERROR Error: Cannot find control with name: '1'
I have tried this:
<form [formGroup]="addLayerForm">
<div formArrayName="items">
<ol-edit-field
*ngFor="
let control of addLayerForm.getControls();
let i = index
"
[formControl]="control"
[formGroupName]="i"
[formGroup]="addLayerForm"
></ol-edit-field>
</div>
</form>
Template of component is:
<div[formGroupName]="formGroupName">
<input [formControlName]="formControl.name">
</div>
Dump of formGroup is:
Solution
I think you have some the input variable names mixed up in your template and component. I didn't go through your actual code in the question, but used the stackblitz from your comment, to make it a workable demo.
Hope you can take the hint from it to get your actual code working :)
html:
<form [formGroup]="form">
<input type="checkbox" formControlName="published"> Published
<div *ngIf="form.controls.published.value">
<h2>Credentials</h2>
<button (click)="addCreds()">Add</button>
<div *ngIf="f.length > 0">
<div *ngFor="let creds of f.controls; let i = index">
<div [formGroup]="creds">
<ng-container>
<input placeholder="Username" formControlName="name">
<input placeholder="Password" formControlName="password">
</ng-container>
</div>
</div>
</div>
</div>
</form>
<!-- Below code added for demo purposes -->
<br>
<div *ngIf="f.length > 0">
<div *ngFor="let creds of f.controls; let i = index">
<p>Form {{ i + 1}} Data:</p>
<p>username: {{ creds.controls.name.value }}</p>
<p>password: {{ creds.controls.password.value }}</p>
</div>
</div>
component.ts:
export class AppComponent {
form: FormGroup;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
published: true,
credentials: new FormArray([])
});
}
addCreds() {
this.f.push(this.fb.group({
name: [null],
password: [null]
}));
console.log(this.form);
}
get f() {
return this.form.controls.credentials as FormArray;
}
}
Result:
Answered By - Nehal
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.