I would like in a Main form to be able to add/remove dynamically a subForm. the subform is based on a model object, and embeds several things :
- use data transmitted from parent form component (for select input choices)
- has event trigger onChange function
- May be used in edit mode, such may permit form pre-fill
I then create a dedicated component for this subform:
Model:
impoort { Obj } from ./Obj.model.ts
export class Foo
{
constructor(
public name: string,
public obj: Obj,
public bar: string
) {}
}
subform.component.ts:
@Component({
selector: 'ngx-subformcomp',
templateUrl: './subform.component.html',
styleUrls: ['./subform.component.scss']
})
export class SubformComponent implements OnInit, OnDestroy {
@Input() objs: Obj[];
@Input() foodata?: Foo;
subForm: FormGroup;
showBar: boolean = true;
constructor(
private formBuilder: FormBuilder,
private loadingService: LoadingService,
) { }
ngOnInit(): void {
initForm();
if (foodata) {
//In case Edit mode
this.subForm.patchValue({
name: foodata.name,
obj: foodata.obj,
bar: foodata.bar,
});
if (foodata.obj.id == 1) {
this.subForm.get('bar').setValidators([Validators.required]);
this.subForm.get('bar').updateValueAndValidity();
this.showbar = true;
}
else {
this.subForm.patchValue({ bar: '' });
this.subForm.get('bar').setValidators([]);
this.subForm.get('bar').updateValueAndValidity();
}
}
}
initForm() {
this.subForm = this.formBuilder.group({
name: ['', [Validators.required],
obj: new FormControl('', [Validators.required, SelectedValue]),
bar: ['', [Validators.required],
},
{
validator: [... , ...]
});
}
onObjChange(event) {
if (event == 1) {
this.subForm.get('bar').setValidators([Validators.required]);
this.subForm.get('bar').updateValueAndValidity();
this.showbar = true;
}
else {
this.subForm.patchValue({ bar: '' });
this.subForm.get('bar').setValidators([]);
this.subForm.get('bar').updateValueAndValidity();
}
}
}
and html:
<form [formGroup]="subForm">
<div class="form-group">
<input id="name" class="form-control" formControlName="name" />
</div>
<div class="form-group">
<nb-select id="obj" formControlName="obj" (selectedChange)="onObjChange($event)">
<nb-option *ngFor="let option of objs" [value]="option.id">{{ option.label }}</nb-option>
</nb-select>
</div>
<div class="form-group">
<input *ngIf="showBar" id="bar" class="form-control" formControlName="bar" />
</div>
</form>
I try now to use it in my main form but I am lost...
I defined my main form component like that:
export class MainComponent implements OnInit, OnDestroy {
objs:Obj[] = [{....}],
mainForm: FormGroup;
ngOnInit(): void {
initForm();
}
initForm() {
this.mainForm = this.formBuilder.group({
foobar: ['', [Validators.required],
objs: this.formBuilder.array([]),
},
{
validator: [... ,...]
});
}
getObjs(): FormArray {
return this.sMainForm.get('objs') as FormArray;
}
onAddObj() {
}
and in my template:
<div class="form-group">
<ng-container formArrayName="objs" *ngFor="let obj of objs; let i=index">
<ngx-subformcomp id="'gsprice_'+i" [formControlName]="objs[i]"></ngx-subformcomp>
</ng-container>
<button (click)="onAddObj()" outline>Add}</button>
</div>
I do not know how to treat the onAddObj function neither the coming removeObj... Thank you for your help