When dealing with checkboxes in Angular forms, remember that the form control value is tied to the "checked" state and not the "value" attribute. It should be either true
or false
.
Furthermore, it's important to choose between using reactive forms or template-driven forms instead of mixing them.
Template-Driven Form
If you opt for template-driven forms, adjust your template as follows:
...
<form name="optOutForm" (ngSubmit)="onSubmit()" #f="ngForm">
<div>
<input type="checkbox" name="privacyOptIn" id="privacyOptIn"
[(ngModel)]="optIn.privacy" required>
<label for="privacyOptIn">Privacy</label>
</div>
<div>
<input type="checkbox" name="securityOptIn" id="securityOptIn"
[(ngModel)]="optIn.security" required>
<label for="securityOptIn">Security</label>
</div>
<div>
<input type="checkbox" name="consentOptIn" id="consentOptIn"
[(ngModel)]="optIn.consent" required>
<label for="consentOptIn">Consent</label>
</div>
<button>Submit Preference</button>
</form>
...
In your component, ensure the model optIn
has properties all set to true
to have the checkboxes pre-selected.
export class MyComponent {
optIn: {
privacy: boolean;
security: boolean;
consent: boolean;
} = {
privacy: true,
security: true,
consent: true
};
onSubmit() {
...
}
}
View Stackblitz example here.
Reactive Form
Alternatively, if you prefer reactive forms, update your template like this:
<form [formGroup]="form" (ngSubmit)="onSubmit()">
<div>
<input type="checkbox" formControlName="privacyOptIn" id="privacyOptIn">
<label for="privacy">Privacy</label>
</div>
<div>
<input type="checkbox" formControlName="securityOptIn" id="securityOptIn">
<label for="security">Security</label>
</div>
<div>
<input type="checkbox" formControlName="consentOptIn" id="consentOptIn">
<label for="consent">Consent</label>
</div>
<button>Submit Preference</button>
</form>
In your component, set up the form like this:
export class MyComponent implements OnInit {
form: FormGroup;
submitted = false;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.form = this.formBuilder.group({
privacyOptIn: [true, Validators.required],
securityOptIn: [true, Validators.required],
consentOptIn: [true, Validators.required]
});
}
// Shortcut for accessing form fields easily
get f() { return this.form.controls; }
onSubmit() {
...
}
}
See Stackblitz example here.
UPDATE
If you want your component to emit strings 'optin'
or 'optout'
, introduce a new variable during form submission:
export class MyComponent {
@Output() options = new EventEmitter<{
privacy: string;
security: string;
consent: string;
}>();
...
onSubmit() {
const emittedOptions = {
privacy: this.optIn.privacy ? 'optin' : 'optout',
security: this.optIn.security ? 'optin' : 'optout',
consent: this.optIn.consent ? 'optin' : 'optout',
}
this.options.emit(emittedOptions);
}
Check it out in action!