角度反应表单自定义验证器最小和最大复选框已选中 [英] Angular Reactive Forms custom validator minimum and maximum checked checkboxes

查看:0
本文介绍了角度反应表单自定义验证器最小和最大复选框已选中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个角度反应形式,让人们选择他们最喜欢的最少1到最多3个水果。

模板:

<div>
    <h3>Which maximum 3 fruits do you like best?</h3>
    <form *ngIf="myForm" [formGroup]="myForm" (ngSubmit)="onSubmit(myForm.value)" novalidate>
        <div *ngFor="let answer of answers.controls; let i=index">
            <input type="checkbox" [formControl]="answer">{{fruits[i]}}<br>
        </div>
        <button type="submit" [disabled]="!myForm.valid">Submit</button>
    </form>
</div>

组件:

export class AppComponent {

  myForm: FormGroup;
  fruits: Array<string> = ["apple", "pear", "kiwi", "banana", "grape", "strawberry", "grapefruit", "melon", "mango", "plum"];

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.myForm = this.formBuilder.group({}, {
      validator: this.anotherValidator.bind(this)
    });
    let answersFormArray = this.fruits.map(fruit => { return this.formBuilder.control(false, [this.validateMaxCheckboxes.bind(this)]) });
    this.myForm.setControl('answers', this.formBuilder.array(answersFormArray));
  }

  validateMaxCheckboxes(control: FormControl) {
    return null;
  };

  anotherValidator(group: FormGroup) {
    return null;
  };

  get answers(): FormArray {
    return this.myForm.get('answers') as FormArray;
  };

  onSubmit(submit) {
    console.log(submit.answers);
  }

}

你最喜欢哪3种水果?则显示用户可以选择的水果列表(复选框)。

我想要此行为:

如果用户未选择任何内容,则提交按钮处于禁用状态,需要至少选择1个水果。如果用户选择了1个或2个水果,则启用提交按钮。如果用户选择第三个水果(3个复选框被选中),我想禁用所有未选中的水果,提交按钮保持启用。如果选中的3个水果中有一个未选中,则所有复选框均处于启用状态。这样,用户可以从列表中选择最少1个和最多3个水果。

我试了很多东西,谷歌了很多次,但我就是不能用。

推荐答案

@arunkumaresh的答案也行,但距离我的原始代码太远了。但他给我指明了正确的方向,所以我想出了这个解决方案:

模板:

<div>
    <h3>Which maximum 3 fruits do you like best</h3>
    <form *ngIf="myForm" [formGroup]="myForm" (ngSubmit)="onSubmit(myForm)" novalidate>
        <div *ngFor="let answer of answers.controls; let i=index">
            <input type="checkbox" [formControl]="answer" (change)="onChangeAnswer($event.target.checked)">{{fruits[i]}}<br>
        </div>
        <button type="submit" [disabled]="!myForm.valid">Submit</button>
    </form>
</div>

组件:

export class AppComponent {

  fruits: Array<string> = ["apple", "pear", "kiwi", "banana", "grape", "strawberry", "grapefruit", "melon", "mango", "plum"];
  myForm: FormGroup;
  numChecked: number = 0;

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {
    this.myForm = this.formBuilder.group({}, {
      validator: this.minOneAnswer.bind(this)
    });
    let answersFormArray = this.fruits.map(fruit => { return this.formBuilder.control(false) });
    this.myForm.setControl('answers', this.formBuilder.array(answersFormArray));
  }

  minOneAnswer(control) {
    return this.numChecked === 0 ? { minOneAnswerChecked: true } : null;
  }

  onChangeAnswer(checked: boolean) {
    checked ? this.numChecked++ : this.numChecked--;
    const answerFormArray = this.myForm.get('answers') as FormArray;
    if (this.numChecked >= 3) {
      answerFormArray.controls.forEach((item) => {
        if (!item.value) item.disable()
      })
    } else {
      answerFormArray.controls.forEach((item) => {
        if (!item.value) item.enable()
      })
    }
  }

  get answers(): FormArray {
    return this.myForm.get('answers') as FormArray;
  };

  onSubmit(form: FormGroup) {
    const answerFormArray = form.get('answers') as FormArray;
    answerFormArray.controls.forEach((item) => {
      if (!item.value) item.enable()
    })
    console.log(form.value);
  }
}

这篇关于角度反应表单自定义验证器最小和最大复选框已选中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆