1
votes

I am building a form with reactive form, but i have some nested group inside group, and for that nested group i have only validation required on input. The problem I have is that inside that nested group, i have to have validation that if user enters in one input something, others inputs in that group are not required anymore.

This is what i have for now, i have tried to add Validators.required instead RequiredValidatonOnlyOne(). Is it possible to add some custom validation that will validate that user has enters something in just one input

 this.formGroup = this.formBuilder.group({
      lastName: [{ value: '', disabled: false }, [Validators.maxLength(50), Validators.required]],
      phones: this.formBuilder.group({
        phone: [{ value: '', disabled: false }],
        phone2: [{ value: '', disabled: false }],
        mobile: [{ value: '', disabled: false }],
      }, this.RequiredValidatonOnlyOne())
    });


  private RequiredValidatonOnlyOne(){
    return (controlGroup) => {
      const controls = controlGroup.controls;
      if (controls) {
        const theOne = Object.keys(controls).find(key => controls[key].valid);
        if (!theOne) {
          return {
            atLeastOneRequired: {
              text: 'At least one should be selected'
            }
          };
        }
      }
      return null;
    };
  }
2
Is it possible to add some custom validation that will validate that user has enters something in just one input?: Isn't that exactly what you did with the RequiredValidatonOnlyOne() custom validator options? Is there a problem with the above code? If so, what is the problem? - JB Nizet
can you share code of your RequiredValidatonOnlyOne() so we can help? it is custom validator and probably something wrong with it. - Nikola Stekovic
Added RequiredValidatonOnlyOne - Miomir Dancevic
So the problem is that the code doesn't compile, right? Have you read the error message from the compiler? Have you read the documentation of FormBuilder.group(). Its second argument is not a validator. Read the documentation. angular.io/api/forms/FormBuilder#group - JB Nizet
Code compiles, but validation on phones does not works :( - Miomir Dancevic

2 Answers

2
votes
RequiredValidatonOnlyOne()
  {
    return (controlGroup:FormGroup)=>{
      const controls = controlGroup.controls;
      let valid:boolean=false;
      return Object.keys(controls).find(key => controlGroup.get(key).value)?null
             :{requiredOne:"required one"}
    }
  }

Sorry and updated: in Angular 8 formBuilder has changed, use {validator:this.RequiredValidatonOnlyOne()} to add a validator to a formGroup, see stackblitz

this.formGroup = this.formBuilder.group({
      lastName: [{ value: '', disabled: false }, [Validators.maxLength(50), Validators.required]],
      phones: this.formBuilder.group({
        phone: [{ value: '', disabled: false }],
        phone2: [{ value: '', disabled: false }],
        mobile: [{ value: 'aaa', disabled: false }],
      }, {validator:this.RequiredValidatonOnlyOne()})
    });
  }

You need search a control with value, not if is valid (valid are always, because the controls has not validators inside -and they must not have any-)

0
votes

the approach i see is clearValidators(). set (change) event listener on all controls. call a function on change, pass the formcontrol itself as argument and clearvalidators of other controls execept for this one. if input is empty then setvalidators() again on all controls.