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