Miomir Dancevic
Miomir Dancevic

Reputation: 6852

Reactive forms Angular formGroup

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

Upvotes: 1

Views: 1167

Answers (2)

kcsujeet
kcsujeet

Reputation: 522

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.

Upvotes: 0

Eliseo
Eliseo

Reputation: 58029

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

Upvotes: 2

Related Questions