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

4
  • The validator is working ? Invalid flag is emitten by this formgroup ? Commented Sep 11, 2019 at 20:19
  • not, the validator is not working, supposed to be, button submit disabled until I selected one of the checkbox, but it didnt Commented Sep 11, 2019 at 22:54
  • If you want an e.g. of custom validation over an array, stackoverflow.com/questions/57794118/… Commented Sep 11, 2019 at 23:22
  • it is my approach is wrong ? @Eliseo Commented Sep 12, 2019 at 0:21

2 Answers 2

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);
    });
}
Sign up to request clarification or add additional context in comments.

Comments

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.