Home > Blockchain >  Custom Validator update help Angular 14
Custom Validator update help Angular 14

Time:10-13

I have my form and my custom validator right here, with logic that I think should work. I have 15 fields, 3 in which the custom validator refers to ('icmp','tcpPorts','udpPorts'). Along with the other required fields I need at least ONE of those three fields filled to submit.

here is the code in my component.ts

 newFWXForm = this.fb.group(
{
  sspSelect: ["", Validators.required],
  requester: [this.loggedInUser],
  requesterContactInfo: [this.loggedInUserEmail],
  fwxDescription: ["", Validators.required],
  durationTypeSelect: ["Permanent", Validators.required],
  durationDate: [""],
  infraSelect: [""],
  sourceIPs: ["", Validators.required],
  DestAnyCheck: [false],
  SrcAnyCheck: [false],
  icmp: [false],
  destinationIPs: ["", Validators.required],
  tcpPorts: [],
  udpPorts: [],
  addDirectory: new FormControl(false),
},
{
  Validators: this.atleastOnePortValue("icmp", "tcpPorts", "udpPorts"),
}
);

 private atleastOnePortValue( controlNameA: string,controlNameB: string,controlNameC: string): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
  const formGroup = control as FormGroup;
  const valueOfControlA = formGroup.get(controlNameA)?.value;
  const valueOfControlB = formGroup.get(controlNameB)?.value;
  const valueOfControlC = formGroup.get(controlNameC)?.value;

  if (
    valueOfControlA === false &&
    valueOfControlB === null &&
    valueOfControlC === null
  ) {
    return { atLeastOne: true};
  } else {
    return null;
  }
};
}

Any knowledge or help on why this still isn't working? Very much appreciated and thank you in advanced!

CodePudding user response:

NOTE: It's an answer to show how make a validator over "one control", not over the whole form

It's like this SO but extending with another field

export function conditionalValidator(field: string[]): ValidatorFn {
  return (formControl) => {
    if (!formControl.parent) {
      return null;
    }
    const otherControls = field.map((x) => formControl.parent.get(x));
    if (otherControls.filter((x) => x).length == field.length) {
      const error =
        formControl.value || otherControls.find((x) => x.value)
          ? null
          : { error: 'this field or '   field   ' is required' };

      const controlCheck = error
        ? otherControls.filter((x) => x.valid)
        : otherControls.filter((x) => x.invalid);
      if (controlCheck.length) {
        setTimeout(() => {
          controlCheck.forEach((x) =>
            x.updateValueAndValidity({ emitEvent: false })
          );
        });
      }
      return error;
    }
  };
}

You has, e.g.

form = new FormGroup({
    control1: new FormControl(
      null,
      conditionalValidator(['control2', 'control3'])
    ),
    control2: new FormControl(
      null,
      conditionalValidator(['control1', 'control3'])
    ),
    control3: new FormControl(
      null,
      conditionalValidator(['control1', 'control2'])
    ),
  });

See a stackblitz

CodePudding user response:

Simple problem :-)

The parameter for adding validators to a form via the Formbuilder is named "validators" instead "Validators".

newFWXForm = this.fb.group(
  {
    ...
  },
  {
    validators: this.atleastOnePortValue("icmp", "tcpPorts", "udpPorts"),
  }
);

The rest of the code looks fine, however you should also check for empty string instead null only, cause when user empties a feld it will not set to null. null is only the initial value of the form

  • Related