【问题标题】:disable button on certain select checkbox禁用某些选择复选框上的按钮
【发布时间】:2020-01-28 08:45:39
【问题描述】:

我的反应式form 中有一个条件,其中一个checkbox 被选中,提交button 将被启用,如果没有checkbox 被选中,它将保持禁用状态,问题是我有selectAll功能,如果我点击它,它将选中所有复选框并启用提交button,然后如果我取消选择单个checkbox选择所有功能后,提交按钮应该启用,直到所有复选框未选择,这是我尝试过的:

ts 文件

  selectAll() {
    this.formReceivedSummons.controls.map(value => value.get('isChecked').setValue(true));
    return this.disabledButton = false;
  }

  changeCheck(event){
    this.disabledButton = !event.target.checked;
  }

html 文件

<div *ngIf="isShowResponse">
    <p>Inquiry Response</p>
    <form [formGroup]="form" (ngSubmit)="submitSelectedCheckboxes()">
        <ng-container formArrayName="receivedSummons" *ngFor="let 
            summon of formReceivedSummons.controls; let i = index">
            <ng-container [formGroupName]="i">
                <input type="checkbox" formControlName="isChecked"
        (change)="changeCheck($event)">
  {{ summon.get('isChecked').value ? 'selected' : 'select' }}
      </ng-container>
    </ng-container>
    <button [disabled]="disabledButton">Submit</button>
</form>
<button (click)="selectAll()">Select All</button>
</div>

应该在select all函数之后,提交按钮将启用,直到所有checkbox被单独取消选择然后它将被禁用,这是我的stackblitz demo,我可以使用任何建议来解决这个问题,

【问题讨论】:

  • 您必须维护一个数组来存储所有复选框的值。所以使用全选,数组中所有项目的值为真。当任何单个复选框未选中时,您将在数组中为该复选框设置值 false。要禁用提交按钮,如果数组中的所有项目都为假,它将被禁用,否则为真。

标签: javascript angular typescript checkbox


【解决方案1】:

“经典解决方案”是制作自定义错误验证器

想象一下你有一些喜欢

  options=["option 1","option 2","option 2"]
  form=new FormGroup({
      prop1:new FormControl(),
      receivedSummons:new FormArray(this.options.map(x=>new FormControl()),this.selectAtLeastOne())
  })

  selectAtLeastOne()
  {
    return (formArray:FormArray)=>{
      return formArray.value.some(x=>x)?null:{error:"At least one"}
    }
  }

你只需要

  <button [disabled]="form.invalid">submit</button>

填好的表格是这样的

  <div [formGroup]="form">
  <input formControlName="prop1">
  <div formArrayName="receivedSummons">
    <div *ngFor="let control of form.get('receivedSummons').controls;let i=index" >
      <input type="checkbox" [formControlName]="i">{{options[i]}}
    </div>
  </div>
  <button [disabled]="form.invalid">submit</button>
  </div>

注意:我选择使用FormControls的formArray,而不是formGroups的FormArray,如果你想使用FormGroups的formArray,代码变成这样

  form2=new FormGroup({
      prop1:new FormControl(),
      receivedSummons:new FormArray(
         this.options.map(x=>new FormGroup({
           isChecked:new FormControl()
           })),this.selectAtLeastOne2())
  })

  selectAtLeastOne2()
  {
    return (formArray:FormArray)=>{
      return formArray.value.some(x=>x.isChecked)?null:{error:"At least one"}
    }
  }

还有.html

  <div [formGroup]="form2">
  <input formControlName="prop1">
  <div formArrayName="receivedSummons">
    <div *ngFor="let control of form.get('receivedSummons').controls;let i=index" [formGroupName]="i" >
      <input type="checkbox" formControlName="isChecked">{{options[i]}}
    </div>
  </div>
  <button [disabled]="form2.invalid">submit</button>
  </div>

你可以在stackblitz看到这两个表格

更新我添加了两个功能来选中/取消选中所有

  selectAll(select: boolean) {
    this.form.get("receivedSummons").setValue(this.options.map(x => select));
  }

  selectAll2(select: boolean) {
    this.form2.get("receivedSummons").setValue(
      this.options.map(x => {
        return { isChecked: select };
      })
    );
  }

检查/取消检查都喜欢(请参阅我使用引用变量来传递是否已检查或未检查复选框

  <input #check1 type="checkbox" (change)="selectAll(check1.checked)">Check All

【讨论】:

  • 这太好了,感觉我只给了他一个立竿见影的解决方案。但是你的想法是完全受欢迎的。
【解决方案2】:

试试下面的代码:

  changeCheck(event){
    let flag = true
    for (let summon of this.formReceivedSummons.controls){
      if(summon.get('isChecked').value) {
        flag = false
      }
    }
    this.disabledButton = flag
  }

【讨论】:

    【解决方案3】:

    在 html 中,在输入“#checkboxes”中定义一个引用

    <input type="checkbox" formControlName="isChecked" #checkboxes (click)="changeCheck()">
    

    在ts中,

    我们可以使用@ViewChildren获取所有复选框值

    @ViewChildren("checkboxes") checkboxes: QueryList<ElementRef>; 
    

    ViewChildrenQueryListElementRef 要从“angular/core”导入

    changeCheck(){
        let flag= true;
         this.checkboxes.forEach((element) => { // loop all checkboxes to find checked boxes
          if(element.nativeElement.checked){
            flag=false // if atleast one checkbox checked, put the flag flase
          }
        });
    
        this.disabledButton = flag;
      }
    

    工作代码Stackblitz

    【讨论】:

    • Varman,您的解决方案有效,但我认为这不是“角度解决方案”。经典解决方案是制作自定义验证器
    • @jajanato 如果这个答案有用,请点赞并点击打勾以帮助其他寻求此类问题的人
    猜你喜欢
    • 2016-02-25
    • 2012-06-29
    • 2020-11-23
    • 1970-01-01
    • 2015-08-02
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    相关资源
    最近更新 更多