How to validate that at least one checkbox should be selected?

后端 未结 6 1849
遇见更好的自我
遇见更好的自我 2020-12-04 22:20

I want to do validation for checkboxes here without form tag. At least one checkbox should be selected.



        
6条回答
  •  感动是毒
    2020-12-04 22:57

    The accepted answer abuses stuff to use in a way they are not meant to be. With reactive forms the best, easiest and probably right way is to use a FormGroup that holds your grouped checkboxes and create a validator to check if at least one(or more) checkbox is checked within that group.

    To do so just create another FormGroup inside your existing FormGroup and attach a validator to it:

    form = new FormGroup({
        // ...more form controls...
        myCheckboxGroup: new FormGroup({
          myCheckbox1: new FormControl(false),
          myCheckbox2: new FormControl(false),
          myCheckbox3: new FormControl(false),
        }, requireCheckboxesToBeCheckedValidator()),
        // ...more form controls...
      });
    

    And here is the validator. I made it so you can even use it to check if at least X checkboxes are checked, e.g. requireCheckboxesToBeCheckedValidator(2):

    import { FormGroup, ValidatorFn } from '@angular/forms';
    
    export function requireCheckboxesToBeCheckedValidator(minRequired = 1): ValidatorFn {
      return function validate (formGroup: FormGroup) {
        let checked = 0;
    
        Object.keys(formGroup.controls).forEach(key => {
          const control = formGroup.controls[key];
    
          if (control.value === true) {
            checked ++;
          }
        });
    
        if (checked < minRequired) {
          return {
            requireCheckboxesToBeChecked: true,
          };
        }
    
        return null;
      };
    }
    

    In your template don't forget to add the directive 'formGroupName' to wrap your checkboxes. But don't worry, the compiler will remind you with an error-message if you forget. You can then check if the checkbox-group is valid the same way you do on FormControl's:

    
       
    
       
    At least one checkbox is required to check

    *This template is very static. Of course you could create it dynamically by using an additional array that holds the the form-data(key of FormControl, label, required, etc.) and create the template automatically by use of ngFor.

    Please don't abuse hidden FormControl's like in the accepted answer. A FormControl is not meant to store data like id, label, help-text etc. and doesnt even have a name/key. All this, and much more, should be stored separate, e.g. by a regular array of objects. A FormControl only holds an input-value and provides all this cool state's and functions.

    I created a working example you can play with: https://stackblitz.com/edit/angular-at-least-one-checkbox-checked

提交回复
热议问题