Подтвердить что ты не робот

Как проверить, что нужно выбрать хотя бы один флажок?

Я хочу сделать проверку для флажков здесь без тега формы. Должен быть установлен хотя бы один флажок.

<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>

для другого поля я поставлю обязательный и сделаю ошибку | коснулся | действительный и т.д., но поскольку флажок не является единичным вводом, я не могу поставить обязательный для каждого флажка, потому что все флажки будут обязательны для проверки. так как мне сделать проверку, чтобы предупредить пользователя, по крайней мере, один должен быть проверен?

4b9b3361

Ответ 1

рассмотрите возможность создания FormGroup которая содержит вашу группу флажков и привяжите проверенное значение группы к скрытому контролю формы с требуемым валидатором.

Предположим, что у вас есть три флажка

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

Шаг 1: определите FormArray для ваших флажков

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 label)
  checkbox: new FormControl(false)    // checkbox itself
})));

* легко показать через ngFor

Шаг 2: создайте скрытый обязательный formControl, чтобы сохранить статус группы флажков

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

мы заботимся только о скрытом элементе управления, необходимом для проверки статуса, и не будем показывать этот скрытый элемент управления в формате HTML.

Шаг 3: создать окончательную группу форм, содержащую ниже флажок группы и скрытый контроль формы

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

Шаблон HTML:

<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>

см. это демо

Ответ 2

Принятый ответ злоупотребляет вещами, которые они не используют. С реактивными формами лучший, самый простой и, вероятно, правильный способ - это использовать FormGroup, которая содержит ваши сгруппированные флажки и создать валидатор, чтобы проверить, установлен ли хотя бы один (или более) флажок в этой группе.

Для этого просто создайте другую FormGroup внутри существующей FormGroup и присоедините к ней валидатор:

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

А вот и валидатор. Я сделал это так, чтобы вы могли даже использовать его, чтобы проверить, установлены ли хотя бы X флажки, например 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;
  };
}

В вашем шаблоне не забудьте добавить директиву formGroupName, чтобы обернуть ваши флажки. Но не волнуйтесь, компилятор напомнит вам с сообщением об ошибке, если вы забудете. Затем вы можете проверить, является ли флажок-группа действительной так же, как и в 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>

* Этот шаблон очень статичен. Конечно, вы можете создать его динамически, используя дополнительный массив, который содержит данные формы (ключ FormControl, label, required и т.д.) И автоматически создать шаблон с помощью ngFor.

Пожалуйста, не злоупотребляйте скрытым FormControl, как в принятом ответе. FormControl не предназначен для хранения таких данных, как имя, идентификатор, метка, текст справки и т.д. Все это и многое другое должно храниться отдельно, например, с помощью обычного массива объектов. FormControl содержит только входное значение и предоставляет все это классное состояние и функции.

Я создал рабочий пример, с которым вы можете поиграть: https://stackblitz.com/edit/angular-at-least-one-checkbox-checked

Ответ 3

При проверке (т.е. Например, событие click) итерации по вашему массиву и проверьте, является ли хотя бы один элемент истинным.

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

Ответ 4

У меня была та же проблема, и это решение я использовал в Angular 6 FormGroup, потому что у меня было несколько флажков.

Примечание HTML: я использую Angular Material для стилей, меняйте их по мере необходимости.

<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>

Машинопись

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

По сути, подпишитесь на любые изменения в форме, а затем измените ошибки по мере необходимости в соответствии с новыми значениями формы.

Ответ 5

Добавьте (ngModelChange) = "onChange (officeLIST)" к своему флажку и введите код в файле.ts.

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

Используйте переменную isChecked в любых местах.

Ответ 6

Вы должны проверять затронутые и грязные условия элемента формы

<form #myForm="ngForm"  *ngIf="active"  (ngSubmit)="onSubmit()">

    <div class="form-group">
        <label for="name">Name</label>
        <input type="text" id="name" class="form-control"
               required name="name" [(ngModel)]="myform.name"
               #name="ngModel" >
        <div *ngIf="name.errors && (name.dirty || name.touched)"
             class="alert alert-danger">
            <div [hidden]="!name.errors.required">
              Name is required
            </div>
        </div>
    </div>

</form>

Вы можете комбинировать предыдущий и мой ответ для обоих сценариев

Ответ 7

Вы можете проверить свой массив "officeList" с помощью функции карты, которую вы можете перебирать по каждому "объекту" в этом массиве и проверять каждый объект "object.checked", и если по крайней мере вы обнаружите, что объект "object.checked" является истинным, значит, это означает по крайней мере, один флажок установлен еще, покажите сообщение об ошибке. Примените эту функцию "onClick()" к кнопке отправки. Надеюсь, поможет. Что-то вроде этого:

Отправить

в component.ts:

onClick(){
    let flag=false;
    this.officeList.map(function(obj){
        if(obj.checked===true){
            flag=true; //set the flag again
        }
    })
    if(flag===false){
        alert('atleast one checkbox should be checked');
        flag=true; //reset the flag again
    }
}