Home > Enterprise >  Toggle Angular checkbox with string values instead of boolean true/false
Toggle Angular checkbox with string values instead of boolean true/false

Time:02-17

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 >

   <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]
});  

CodePudding user response:

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

CodePudding user response:

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 >

   <div >
           <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 >
           <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 >
           <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]
   });
}
  • Related