Reputation: 3272
I have a form that sends the correct data to my api/forms array on "save". There is an array of checkboxes that the user can select. Once selected I want to give a summary of the values selected. I can present this after form save as the values will be on the reactive forms array, however I want to pick up the value for presentation purposes before save/form submission. StackBlitz - https://stackblitz.com/edit/angular-fgupp3
I've nearly accomplished this however the first checkbox brings back a true/false value whereas the rest of the checkboxes return the desired value
component.html
<form [formGroup]="form" (ngSubmit)="onSubmit('formSubmit')" novalidate>
<div class="row">
<div class="col-md-8">{{form.value.selection}}</div> <!--present selected values here -->
<div class="col-md-8">
<input type="text" formControlName="title" class="form-control" placeholder="Title">
</div>
<div class="col-md-6">
<label formArrayName="selection" *ngFor="let order of form.controls.selection.controls; let i = index">
<input (change)="onChange(i, $event)" type="checkbox" [formControlName]="i">
{{ordersData[i].name}}
</label>
</div>
</div>
<div class="form-group text-center">
<button class="btn btn-success btn-info" (click)="goToNext(Work)"> Next </button>
</div>
</form>
component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Personal } from '../data/formData.model';
import { FormDataService } from '../data/formData.service';
import { of } from 'rxjs';
import { FormGroup, FormBuilder, ValidatorFn, FormArray, FormControl } from '@angular/forms';
@Component({
selector: 'mt-wizard-personal',
templateUrl: './personal.component.html',
})
export class PersonalComponent implements OnInit {
personal: Personal;
form: FormGroup;
ordersData = [];
selectedItems: any[] = [];
constructor(private formBuilder: FormBuilder, private router: Router, private formDataService: FormDataService) {
}
ngOnInit() {
this.personal = this.formDataService.getPersonal();
this.form = this.createEntry(this.formBuilder);
// synchronous orders
// this.ordersData = this.getOrders();
// this.addCheckboxes();
of(this.getOrders()).subscribe(selection => {
this.ordersData = selection;
this.addCheckboxes();
});
}
createEntry(formBuilder: FormBuilder) {
return this.formBuilder.group({
title: this.personal.title,
creationDate: this.personal.creationDate,
//selection: new FormArray([], minSelectedCheckboxes(1))
selection: new FormArray([])
});
}
private addCheckboxes() {
this.ordersData.forEach((o, i) => {
const control = new FormControl; // if first item set to true, else false
(this.form.controls.selection as FormArray).push(control);
});
}
getOrders() {
return [
{ id: 100, name: 'order 1' },
{ id: 200, name: 'order 2' },
{ id: 300, name: 'order 3' },
{ id: 400, name: 'order 4' }
];
}
onChange(i: boolean) {
console.log(i);
if (i) {
const selectedOrderIds = this.form.value.selection
.map((v, i) => v ? this.ordersData[i].id : null)
.filter(v => v !== null);
return this.form.value.selection = selectedOrderIds;
}
}
save(form: any): boolean {
const selectedOrderIds = this.form.value.selection
.map((v, i) => v ? this.ordersData[i].id : null)
.filter(v => v !== null);
console.log(selectedOrderIds);
this.form.value.selection = selectedOrderIds;
const data: Personal = Object.assign({}, this.form.value);
this.formDataService.setPersonal(data);
return true;
}
goToNext(form: any) {
if (this.save(form)) {
// Navigate to the work page
this.router.navigate(['/work']);
}
}
}
Upvotes: 0
Views: 240
Reputation: 115
The issue about the first value marked as true
instead of 100
can be solved change the if in onChange
function line 76 if (i || i===0)
:
onChange(i: boolean) {
if (i || i===0) {
const selectedOrderIds = this.form.value.selection
.map((v, i) => v ? this.ordersData[i].id : null)
.filter(v => v !== null);
return this.form.value.selection = selectedOrderIds;
}
}
Unfortunately in javascript number = 0; if(number)
it is a falsy expression.
Also OnInit
method is a little messy, instead having a method getOrders()
i will use a variable in component someting like this:
orders = [
{ id: 100, name: 'order 1' },
{ id: 200, name: 'order 2' },
{ id: 300, name: 'order 3' },
{ id: 400, name: 'order 4' }
]
that can be use both in component .ts and .html and i will simplified 'OnInit` like this:
ngOnInit() {
this.personal = this.formDataService.getPersonal();
const ordersArray = new FormArray([]);
this.orders.forEach(order => {
ordersArray.push(new FormControl);
});
this.form = this.formBuilder.group({
title: this.personal.title,
creationDate: this.personal.creationDate,
selection: ordersArray
});
}
Upvotes: 1