【问题标题】:Angular Reactive Forms custom validator minimum and maximum checked checkboxesAngular Reactive Forms 自定义验证器最小和最大复选框
【发布时间】:2018-04-24 02:26:27
【问题描述】:

我有一个 Angular Reactive Form,人们可以在其中选择他们最喜欢的最少 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);
  }

}

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

我想要这种行为:

如果用户什么都不选择,提交按钮被禁用,至少需要选择 1 个水果。如果用户选择了 1 或 2 个水果,则启用提交按钮。如果用户选择了第 3 个水果(选中了 3 个复选框),我想禁用所有未选中的水果,提交按钮保持启用状态。如果选中的 3 个水果之一未选中,则启用所有复选框。这样,用户可以从列表中选择最少 1 种和最多 3 种水果。

我尝试了很多东西,谷歌了很多,但我无法让它工作。

【问题讨论】:

    标签: angular angular-reactive-forms


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 2018-08-09
      • 1970-01-01
      • 2022-06-10
      • 1970-01-01
      • 2020-02-20
      • 2019-01-08
      • 1970-01-01
      • 2011-07-25
      • 1970-01-01
      相关资源
      最近更新 更多