4

I have to create three checkboxes in my form and their values need to toggle as "optin" and "optout" (string) as I check/uncheck the checkbox. Also I need to check all the checkboxes by default for "optin" value. I cannot figure out any solution, any help would be really appreciated :( as I am fairly new to angular

Here is the code I am working on

component.html

<form [formGroup]="optOutForm" (ngSubmit)="submitOptFormValue()">
    <div class="form-group">

   <input type="checkbox" formControlName="optOutFlag1" id="privacy" aria-labelledby="check1">
   <label for="privacy" id="check1"> Checkbox 1</label><br><br>

   <input type="checkbox" formControlName="optOutFlag2" id="security" aria-labelledby="check2">
   <label for="security" id="check2"> Checkbox 2</label><br><br>

   <input type="checkbox" formControlName="optOutFlag3" id="consent" aria-labelledby="check3">
   <label for="consent" id="check3"> Checkbox 3</label><br><br>

   <button> Submit Preference </button>

</div>
</form>

component.ts file

optOutForm:FormGroup
this.optOutForm=this.fb.group({
    optOutFlag1:["optin",Validators.required],
    optOutFlag2:["optin",Validators.required],
    optOutFlag3:["optin",Validators.required]
});  
2
  • 1
    stackoverflow.com/questions/59910767/…. That's you use [ngModel]="if the value of the formControl is 'optin'" and (ngModelChange)="set the value of the formControl if $event==true 'optin' and if is false 'optout' Commented Feb 16, 2022 at 7:45
  • Thank you so much @Eliseo and frank for making it work. I have pasted my solution that is working :] Commented Feb 16, 2022 at 13:39

2 Answers 2

4

With checkboxes, the Angular form control value is bound to the "checked" state (not the "value" attribute), so it should be either true or false.

Also, you are mixing reactive forms and template-driven forms. You probably should do one or the other.

Template-Driven Form

If you want to use template-driven forms, you can change your template like this:

...
<form name="optOutForm" (ngSubmit)="onSubmit()" #f="ngForm">
   <div>
      <input type="checkbox" name="privacyOptIn" id="privacyOptIn" 
         [(ngModel)]="optIn.privacy" required>&nbsp;
      <label for="privacyOptIn">Privacy</label>
   </div>
   <div>
      <input type="checkbox" name="securityOptIn" id="securityOptIn"
         [(ngModel)]="optIn.security" required>&nbsp;
      <label for="securityOptIn">Security</label>
   </div>
   <div>
      <input type="checkbox" name="consentOptIn" id="consentOptIn"
         [(ngModel)]="optIn.consent" required>&nbsp;
      <label for="consentOptIn">Consent</label>
   </div>
   <button>Submit Preference</button>
</form>
...

And have your component like this. Notice the model optIn has properties all set to true so the checkboxes are ticked by default.

export class MyComponent {
    optIn: {
        privacy: boolean;
        security: boolean;
        consent: boolean;
    } = {
        privacy: true,
        security: true,
        consent: true
    };

    onSubmit() {
        ...
    }
}

See Stackblitz example here.

Reactive Form

If however, you want to go reactive forms, you can change your template like this:

<form [formGroup]="form" (ngSubmit)="onSubmit()">
   <div>
       <input type="checkbox" formControlName="privacyOptIn" id="privacyOptIn">&nbsp;
       <label for="privacy">Privacy</label>
   </div>
   <div>
       <input type="checkbox" formControlName="securityOptIn" id="securityOptIn">&nbsp;
       <label for="security">Security</label>
   </div>
   <div>
       <input type="checkbox" formControlName="consentOptIn" id="consentOptIn">&nbsp;
       <label for="consent">Consent</label>
   </div>
   <button>Submit Preference</button>
</form>

Then you can set the form in your component 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]
        });
    }

    // Convenience getter for easy access to form fields
    get f() { return this.form.controls; }

    onSubmit() {
        ...
    }
}

See Stackblitz example here.

UPDATE

If you want your component to return/emit 'optin' or 'optout' strings, you can simply introduce a new variable in the component 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);
    }

See it work here

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the detailed explanation :] really appreciate it.Also how can we set checkbox values as strings instead of boolean, after submitting the form instead of getting true/false what i really need is "optin" for checked state and "optout" for unchecked state
@blume0F, see my update to my answer
instead of changing value in component can we do it in html. Using console.log(this.optOutForm.value) should display the string values of checkbox
Is there a way to bind the checkbox to the value property instead of its checked property? Like its null if not, check and when its checked it the value property
there should be a none template way of doing this
|
0

This solution is based on the solution link by Eliseo.

The checkbox toggles values as "optin" or "optout" when checked/unchecked and is initialized as "optin" by default in .ts file

component.html file

<form [formGroup]="optOutForm" (ngSubmit)="submitOptFormValue()">

   <div class="form-group">

   <div class="optClass">
           <input  type="checkbox" 
           [ngModel]="optOutForm.get('optOutFlag1')?.value==='optin'"
           (ngModelChange)="optOutForm.get('optOutFlag1').setValue($event?'optin':'optout')"  
           [ngModelOptions]="{standalone:true}" id="privacy">

           <label "for="privacy" id="check1">Checkbox 1</label>
  </div>

 <div class="optClass">
           <input  type="checkbox" 
           [ngModel]="optOutForm.get('optOutFlag2')?.value==='optin'"
           (ngModelChange)="optOutForm.get('optOutFlag2').setValue($event?'optin':'optout')"  
           [ngModelOptions]="{standalone:true}" id="security">

           <label "for="security" id="check1">Checkbox 2</label>
  </div>

 <div class="optClass">
           <input  type="checkbox" 
           [ngModel]="optOutForm.get('optOutFlag3')?.value==='optin'"
           (ngModelChange)="optOutForm.get('optOutFlag3').setValue($event?'optin':'optout')"  
           [ngModelOptions]="{standalone:true}" id="consent">

           <label "for="consent" id="check1">Checkbox 3</label>
  </div>
</div>
</form>

component.ts file

optOutForm:FormGroup

constructor(private fb:FormBuilder){}

ngOnInit(){
 this.optOutForm=this.fb.group({
    optOutFlag1:['optin',Validators.required],
    optOutFlag2:['optin',Validators.required],
    optOutFlag3:['optin',Validators.required]
   });
}

1 Comment

I find this approach makes your template hard to read. But if it works, and that's what you want to do, no problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.