Within my project, I am utilizing "@angular/cli": "1.2.6"
, "@angular/core": "^4.0.0"
Objective
My goal is to create a dynamic form for a product that includes feature inputs. When the user clicks the "add feature" button, a new feature column with a select box for "type" should appear. If the user then clicks the "remove" button within a feature column, that specific feature column should be deleted from the form.
Issue Faced
The problem arises when attempting to remove a feature column between the first and last columns. While the formControl updates correctly with the desired value, the UI displays an issue where the removed feature's select box values pass onto the next upcoming feature column.
Expected Outcome
Upon removing a target feature column, the UI of the subsequent feature column should move up accordingly with the correct value.
Example
1. I attempt to remove the second feature column.
https://i.stack.imgur.com/fN3i1.png
2. The formControl successfully removes the second feature. Although the second feature column in UI is effectively deleted, the third feature column moves up and fills the space with the previously removed feature's select box value.
https://i.stack.imgur.com/MYMKM.png
Below is a snippet of my code:
product-form.component.ts
formDOM;
features = [];
featureTypes = [
{ id: "pros", name: "pros" },
{ id: "cons", name: "cons" }];
ngOnInit() {
this.formDOM = this.formBuilder.group({
// Other fields...
feature: this.formBuilder.array([])
});
}
patchSingleFeature(feature: object): FormGroup {
let returnObject = this.formBuilder.group({
type: (feature && feature['type'])
// Additional fields....
});
this.features.push("feature");
return returnObject;
}
addFeature(): void {
let featureControl = <FormArray>this.formDOM.controls['feature'];
featureControl.push(this.patchSingleFeature(new Feature()));
}
removeFeature(x: number): void {
let numberOfFeature = this.features.length;
let featureControl = <FormArray>this.formDOM.controls['feature'];
featureControl.controls.splice(x, 1);
this.features.splice(x, 1);
}
product-form.component.html
<div class="form" [formGroup]="formDOM">
<div class="col-xs-12">Features</div>
<div *ngFor="let feature of features; let x = index; ">
<feature-input [x]="x" [featureTypes]="featureTypes" [form]="formDOM" (clickEvent)="removeFeature($event)"></feature-input>
</div>
<button (click)="addFeature()">Add Feature</button>
</div>
feature-input.component.html
<div class="feature-input" [formGroup]="form">
<div formArrayName="feature">
<div [formGroupName]="x">
<select formControlName="type">
<option value="" disabled>-- Select Feature Type --</option>
<option *ngFor="let type of featureTypes" [value]="type.id">{{ type.name }}</option>
</select>
</div>
</div>
</div>
feature-input.component.ts
@Input() form: FormGroup;
@Input() featureTypes: Array<object>;
@Input() x: number;
@Output() clickEvent new EventEmitter<number>();
removeFeature(x) { this.clickEvent.emit(x); }