简体   繁体   中英

disable button on certain select checkbox

I had condition in my reactive form where one checkbox selected, submit button will be enabled, and if there are none checkbox selected, it will remain disabled, the problem is I had selectAll function, which if I clicked, it will selected all the checkbox and enabled submit button , then if I unselect individual checkbox after select all function , the submit button should be enabled until all the checkbox is unselect, this is what I had tried:

ts file

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

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

html file

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

supposed to be after select all function, submit button will enabled until all checkbox is unselected individually then it will disabled, this is my stackblitz demo , I could use any suggestion to solve this problem,

In html, define a reference in input " #checkboxes "

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

In ts,

We can get all checkbox values using @ViewChildren

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

ViewChildren , QueryList , ElementRef to be imported from ' 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;
  }

Working code at Stackblitz

the "clasic solution" is make a custom error validator

Imagine that you has some like

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

You only need

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

The completed form is like

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

NOTE: I choose use a formArray of FormControls, not a FormArray of formGroups, if you want to use a formArray of FormGroups, the code becomes like

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

And the.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>

You can see the two forms in stackblitz

Updated I add two funtions to check/uncheck all

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

The check to check/uncheck all like (see as I use a refernce variable to pass if is checkd or not the checkBox

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

Try the below code:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM