Reputation: 183
I am dynamically creating checkboxes and associated dropdowns from the data i get from api ....
my html code below::
<label [for]="i" class="form-check-label fw7 h5 mb0" formArrayName="planDivList" *ngFor="let plan of planForm.controls.planDivList.controls; let i = index">
<br>
<input [name]="i" [id]="i" class="form-check-input" type="checkbox" [formControlName]="i">
{{planDivList[i].planCode}}
<label *ngIf="planDivList[i].divisions.length > 0" for="inputDiv">
Divisions
<select id="inputDiv" formcontrolName='divCtrl'>
<option *ngFor="let division of planDivList[i].divisions" Value="division.divisionCode">
{{division.divisionName}}
</option>
</select>
</label>
</label>
my dataset is
planDivList = [
{ planCode: "B3692", divisions: [] },
{ planCode: "B3693", divisions: [] },
{ planCode: "B67", divisions: [{ divisionCode: "2", divisionName: "Assisted Living " }, { divisionCode: "1", divisionName: "LILC" }] },
{ planCode: "B69", divisions: [{ divisionCode: "3", divisionName: "Four Seasons" }, { divisionCode: "2", divisionName: "Lakeside" }, { divisionCode: "1", divisionName: "Sunrise" }] }
];
ts file:
const selectedPlans = this.planForm.value.planDivList
.map((checked, index) => (checked ? this.planDivList[index].planCode : null))
.filter(value => value !== null);
console.log(selectedPlans);
Here is my stackblitz
https://stackblitz.com/edit/angular-fsgswa?file=src%2Fapp%2Fapp.component.ts
i am able to get the selected checkbox value.But How do i get the value of the respective division that is selected for that checkbox in submit button? Any help is appreciated
Upvotes: 1
Views: 2728
Reputation: 13515
To solve your problem, I have take several steps, which I will break down below.
You have an array of data for which each item should have multiple controls (checkbox and select). This requires a form array of form groups.
Your form is an array and nothing more, so we can simply bind the form to an array.
We will need to refer to the nested form control values later, so store them in a property for easy reference.
form: FormArray;
private formControls: {
checkbox: FormControl;
division: FormControl;
}[];
// initialise component in ngOnInit instead of constructor
ngOnInit() {
this.formControls = this.plans.map((plan, i) => {
const divisionCode = plan.divisions.length > 0
? plan.divisions[0].divisionCode
: '';
return {
checkbox: this.fb.control(i === 0),
division: this.fb.control(divisionCode)
};
});
const formGroups = this.formControls.map(x => this.fb.group(x));
this.form = this.fb.array(formGroups, this.minSelectedCheckboxes(1));
}
You should prefer handling form submit by using (submit)
to a button (click)
. (submit)
will handle all of the ways in which a form can be submitted.
The HTML bindings match the structure of the form we built. Notice how the checkbox and division controls are binding to the i
th form group in the array.
I would also recommend using your model as much as possible to generate loops, and restrict form binding to the form control directives.
<form [formGroup]="form" (submit)="onSubmit()">
<div *ngFor="let plan of plans; index as i" [formGroupName]="i">
<label>
<input type="checkbox" formControlName="checkbox">
{{plan.planCode}}
</label>
<label *ngIf="plan.divisions.length > 0" >
Divisions
<select formControlName="division">
<option *ngFor="let division of plan.divisions"
[value]="division.divisionCode">
{{division.divisionName}}
</option>
</select>
</label>
</div>
<div *ngIf="formInvalid && form.hasError('required')">
At least one plan must be selected
</div>
<button>Enroll</button>
</form>
It is now simply a case of querying the form control array to find out which ones are checked, and what the selected division code is where relevant.
onSubmit(){
this.formInvalid = this.form.invalid;
if (this.formInvalid) {
return;
}
this.selectedPlans = this.plans
.map((plan, i) => ({
planCode: plan.planCode,
selected: this.formControls[i].checkbox.value,
divisionCode: this.formControls[i].division.value
}))
.filter(x => x.selected);
}
The actual output that you need will probably differ slightly from my example, and I renamed a few of your properties for the purposes of a simpler demo. Hopefully I have demonstrated the techniques that you can apply to your own form.
DEMO: https://stackblitz.com/edit/angular-qxm8wk
Upvotes: 1