webentwicklung-frage-antwort-db.com.de

Wie kann überprüft werden, dass mindestens ein Kontrollkästchen ausgewählt werden muss?

Ich möchte die Checkboxen hier ohne Formular-Tag validieren. Mindestens eine Checkbox sollte ausgewählt werden.

<div *ngFor="let item of officeLIST">
  <div *ngIf=" item.officeID == 1">
    <input #off type="checkbox" id="off" name="off" value="1" [(ngModel)]="item.checked">
    <label>{{item.officename}}</label>
  </div>

  <div *ngIf="item.officeID== 2">
    <input #off type="checkbox" id="off" name="off" value="2" [(ngModel)]="item.checked">
    <label>{{item.officename}}</label>
  </div>

  <div *ngIf="item.officeID== 3">
    <input #off type="checkbox" id="off" name="off" value="3" [(ngModel)]="item.checked">
    <label>{{item.officename}}</label>
  </div>
</div>

für ein anderes Feld werde ich "required" eingeben und den Fehler | touched | valid usw. ausführen. Da das Kontrollkästchen jedoch nicht eine einzelne Eingabe ist, kann ich nicht in jedes Kontrollkästchen "Pflichtfeld" setzen, da alle Kontrollkästchen aktiviert werden müssen. Wie kann ich also die Validierung durchführen, um den Benutzer zu warnen?

12
user3431310

erstellen Sie eine FormGroup, die Ihre Kontrollkästchengruppe enthält, und binden Sie den überprüften Wert der Gruppe mit einem erforderlichen Prüfer an ein verstecktes Formularsteuerelement.

Angenommen, Sie haben drei Kontrollkästchen

items = [
  {key: 'item1', text: 'value1'},      // checkbox1 (label: value1)
  {key: 'item2', text: 'value2'},      // checkbox2 (label: value2)
  {key: 'item3', text: 'value3'},      // checkbox3 (label: value3)
];

Schritt1: Definiere FormArray für deine Kontrollkästchen

let checkboxGroup = new FormArray(this.items.map(item => new FormGroup({
  id: new FormControl(item.key),      // id of checkbox(only use its value and won't show in html)
  text: new FormControl(item.text),   // text of checkbox(show its value as checkbox's label)
  checkbox: new FormControl(false)    // checkbox itself
})));

* einfach über ngFor anzeigen

Schritt2: Erstellen Sie ein verstecktes erforderliches formControl, um den Status der Kontrollkästchengruppe zu erhalten.

let hiddenControl = new FormControl(this.mapItems(checkboxGroup.value), Validators.required);
// update checkbox group's value to hidden formcontrol
checkboxGroup.valueChanges.subscribe((v) => {
  hiddenControl.setValue(this.mapItems(v));
});

wir kümmern uns nur um den erforderlichen Validierungsstatus der versteckten Kontrolle und zeigen diese versteckte Kontrolle nicht in HTML an.

Step3: Endgültige Formulargruppe erstellen enthält untere Kontrollkästchengruppe und ausgeblendete FormController

this.form = new FormGroup({
  items: checkboxGroup,
  selectedItems: hiddenControl
});

HTML-Vorlage:

<form [formGroup]="form">
  <div [formArrayName]="'items'" [class.invalid]="!form.controls.selectedItems.valid">
    <div *ngFor="let control of form.controls.items.controls; let i = index;" [formGroup]="control">
      <input type="checkbox" formControlName="checkbox" id="{{ control.controls.id.value }}">
      <label attr.for="{{ control.controls.id.value }}">{{ control.controls.text.value }}</label>
    </div>
  </div>
  <div [class.invalid]="!form.controls.selectedItems.valid" *ngIf="!form.controls.selectedItems.valid">
    checkbox group is required!
  </div>
  <hr>
  <pre>{{form.controls.selectedItems.value | json}}</pre>
</form>

verweisen Sie auf diese Demo .

20
Pengyy

Die akzeptierte Antwort missbraucht Dinge so, wie sie nicht sein sollen. Mit reaktive Formulare ist der beste, einfachste und wahrscheinlich richtige Weg, ein FormGroup zu verwenden, das Ihre gruppierten Kontrollkästchen enthält und einen Validator erstellt, um zu überprüfen, ob mindestens ein (oder mehrere) Kontrollkästchen vorhanden sind ist in dieser Gruppe aktiviert.

Erstellen Sie dazu einfach ein anderes FormGroup in Ihrem vorhandenen FormGroup und hängen Sie einen Validator daran an:

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

Und hier ist der Validator. Ich habe es so gemacht, dass Sie es sogar verwenden können, um zu überprüfen, ob mindestens X Kontrollkästchen aktiviert sind, z. 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;
  };
}

Vergessen Sie nicht, in Ihrer Vorlage die Direktive ' formGroupName ' einzufügen, um die Kontrollkästchen einzuschließen. Aber keine Sorge, der Compiler erinnert Sie mit einer Fehlermeldung, wenn Sie dies vergessen. Sie können dann überprüfen, ob die Checkbox-Gruppe genauso gültig ist wie in FormControl:

<ng-container [formGroup]="form">
   <!-- ...more form controls... -->

   <div class="form-group" formGroupName="myCheckboxGroup">
      <div class="custom-control custom-checkbox">
        <input type="checkbox" class="custom-control-input" formControlName="myCheckbox1" id="myCheckbox1">
        <label class="custom-control-label" for="myCheckbox1">Check</label>
      </div>

      <div class="custom-control custom-checkbox">
        <input type="checkbox" class="custom-control-input" formControlName="myCheckbox2" id="myCheckbox2">
        <label class="custom-control-label" for="myCheckbox2">At least</label>
      </div>

      <div class="custom-control custom-checkbox">
        <input type="checkbox" class="custom-control-input" formControlName="myCheckbox3" id="myCheckbox3">
        <label class="custom-control-label" for="myCheckbox3">One</label>
      </div>

      <div class="invalid-feedback" *ngIf="form.controls['myCheckboxGroup'].errors && form.controls['myCheckboxGroup'].errors.requireCheckboxesToBeChecked">At least one checkbox is required to check</div>
    </div>

    <!-- ...more form controls... -->
  </ng-container>

* Diese Vorlage ist sehr statisch. Natürlich können Sie es dynamisch erstellen, indem Sie ein zusätzliches Array verwenden, das die Formulardaten (Schlüssel von FormControl, Bezeichnung, Erforderlich usw.) enthält, und die Vorlage automatisch mit ngFor erstellen.

Bitte missbrauchen Sie versteckte FormControls nicht wie in der akzeptierten Antwort. Ein FormControl ist nicht dazu gedacht, Daten wie ID, Label, Hilfetext usw. zu speichern und hat nicht einmal einen Namen/Schlüssel. All dies und vieles mehr sollte getrennt aufbewahrt werden, z. durch eine regelmäßige Anordnung von Objekten. Ein FormControl enthält nur einen Eingabewert und bietet alle diese coolen Zustände und Funktionen.

Ich habe ein Arbeitsbeispiel erstellt, mit dem Sie spielen können: https://stackblitz.com/edit/angular-at-least-one- Kontrollkästchen aktiviert

24
Mick

Bei der Validierung (d. H. Bei einem Klickereignis) durchlaufen Sie Ihr Array und überprüfen, ob mindestens ein Element wahr ist.

let isSelected: any = this.officeLIST.filter((item) => item.checked === true);
if(isSelected != null && isSelected.length > 0) {
 //At least one is selected
}else {
 alert("select at least one");
}
2
Nugu

Ich hatte das gleiche Problem und dies ist die Lösung, die ich mit Angular 6 FormGroup verwendet habe, da ich nur wenige Kontrollkästchen hatte. 

HTMLHinweis: Ich benutze Winkelmaterial für das Styling. Ändern Sie es nach Bedarf.

<form [formGroup]="form">
  <mat-checkbox formControlName="checkbox1">First Checkbox</mat-checkbox>
  <mat-checkbox formControlName="checkbox2">Second Checkbox</mat-checkbox>
  <mat-checkbox formControlName="checkbox3">Third Checkbox</mat-checkbox>
</form>

TypeScript

form: FormGroup;

constructor(private formBuilder: FormBuilder){}

ngOnInit(){

  this.form = this.formBuilder.group({
    checkbox1: [''],
    checkbox2: [''],
    checkbox3: [''],
  });

  this.form.setErrors({required: true});
  this.form.valueChanges.subscribe((newValue) => {
    if (newValue.checkbox1 === true || newValue.checkbox2 === true || newValue.checkbox3 === true) {
      this.form.setErrors(null);
    } else {
      this.form.setErrors({required: true});
    }
  });
}

Abonnieren Sie grundsätzlich alle Änderungen im Formular und ändern Sie die Fehler entsprechend den neuen Formularwerten.

1
eper

Fügen Sie (ngModelChange) = "onChange (officeLIST)" zu Ihrem Kontrollkästchen hinzu und fügen Sie den Code in Ihrer .ts-Datei ein.

onChange(items) {
    var found = items.find(function (x) { return x.checked === true; });
    if (found)
      this.isChecked = true;
    else
      this.isChecked = false;
  }

Verwenden Sie die Variable isChecked an beliebigen Orten.

0
shailesh kumar