disable FormGroup by using Validators
Asked Answered
R

2

0

I had formArray checkbox on my checkboxForm, I need to disabled button submit if no checkbox are checked, I had implement custom validator on my checkboxForm, this is what I had tried;

Ts file

  get formReceivedSummons() {
    return this.checkboxForm.get('receivedSummons') as FormArray;
  }

  ngOnInit() {
    this.checkboxForm = this.formBuilder.group({
      receivedSummons: this.formBuilder.array([])
    });
    this.getReceivedSummons();
  }

  getReceivedSummons() {
    this.receivedSummonsSubscription = this.inquiryStore.summons$
      .subscribe(receivedSummons => {
        this.receivedSummons = receivedSummons;
      });
  }

  addCheckboxes() {
    this.formReceivedSummons.setValue([]);
    this.formReceivedSummons.setValidators([minSelectedCheckboxes(1)]);
    this.receivedSummons.data.items.map(x => {
      this.formReceivedSummons.push(
        this.formBuilder.group({
          itemNo: [x.itemNo],
          isChecked: false,
        }));
    });
  }


function minSelectedCheckboxes(min = 1) {
  const validator: ValidatorFn = (formArray: FormArray) => {
    const totalSelected = formArray.controls
      .map(control => control.value)
      .reduce((prev, next) => (next ? prev + next : prev), 0);

    return totalSelected >= min ? null : { required: true };
  };
  return validator;
}

I had place validators at formArray which is this.formReceivedSummons.setValidators([minSelectedCheckboxes(1)]);

this is what I had implement in html file

    <form [formGroup]="checkboxForm" (ngSubmit)="submitSelectedCheckbox()">
        <ng-container formArrayName="receivedSummons" *ngFor="let summon of formReceivedSummons.controls; let i = index">
            <ng-container [formGroupName]="i">
                <input type="checkbox" formControlName="isChecked"> {{summon.value.itemNo}}
      </ng-container>
    </ng-container>
    <button [disabled]="!checkboxForm .valid">submit</button>
</form>

my checkboxForm button have been disabled, but if I checked one checkbox it should be enabled, but it didnt. I'm not sure how to solve thw problems, could use some guide and guidance to solve this.

Update

based on my finding in google and So, this is the close I can get,

  addCheckboxes() {
    this.formReceivedSummons.setValue([]);
    this.receivedSummons.data.items.map(item => {
      this.formReceivedSummons.push(
        this.formBuilder.group({
          itemNo: [x.itemNo]
          isChecked: [false, Validators.requiredTrue],
        }));
    });
  }

by using Validators.requiredTrue, it need two checkboxes to be selected, then it will enable the button,but my requirement I need at least one checkbox to be select than it will enable the button submit form

Rockyrococo answered 11/9, 2019 at 19:48 Comment(4)
The validator is working ? Invalid flag is emitten by this formgroup ?Benedict
not, the validator is not working, supposed to be, button submit disabled until I selected one of the checkbox, but it didntRockyrococo
If you want an e.g. of custom validation over an array, #57794618Aboriginal
it is my approach is wrong ? @AboriginalRockyrococo
M
0

Make something like this:

export a function. something like this:

export function customValdiator(form: FormGroup) {
  const formValue = form.value;
  // with the formValue apply your own validation logic .
  if (/* HAVE ERROR */) {
    return { checkboxesRequired: true };
  } else {
    return null;
  }
}

build your form:

 this.checkboxForm = this.formBuilder.group({
      receivedSummons: this.formBuilder.array([])
    },  { validator: customValdiator });

and remove add validators from your addCheckboxes method.

dont matter if u add or remove rows to receivedSummons FormArray when u change any data on the form angular will execute customValdiator function and pass the form as argument and you have access to current receivedSummons values for valid which is checked.

Materiel answered 12/9, 2019 at 0:20 Comment(0)
S
0

When you are initializing the form in the constructor add the validator to the formarray first.Then after you receive the data call the addCheckboxes method.

form: FormGroup;
receivedSummons = [];

constructor(private formBuilder: FormBuilder) {
   this.checkboxForm = this.formBuilder.group({
     receivedSummons: new FormArray([], minSelectedCheckboxes(1))
   });

   of(this.someMethodWhichReturnReceivedSummons()).subscribe(receivedSummons => {
      this.receivedSummons = receivedSummons;
      this.addCheckboxes();
   });
}

In the addCheckboxes

private addCheckboxes() {
    this.receivedSummons.map((o, i) => {
      const control = new FormControl(i === 0); // if first item set to true, else false
      (this.form.controls.receivedSummons as FormArray).push(control);
    });
}
Splinter answered 12/9, 2019 at 2:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.