1

I'm trying to get this to work but I don't know how, I have several inputs that are only displayed when the user needs them.But if they are activated, it must be necessary to fill them. So i got this

component.ts

    dataForm = new FormControl({
       myInput: new FormControl(null, Validators.required)
    })

component.html

<form [formGroup]="dataForm">
     <input formControlName="myInput" type="number" *ngIf="inputActive">

   <button type="submit" [disabled]="!dataForm.valid">
</form>

The problem I have is that when the inputActive variable is false and the input is not shown, the button is still disabled because the field is empty

And I want that when the input is not shown, its validators are not executed so that the button is enabled

Can anyone help me to achieve this?

3 Answers3

2

What you need to do is disable the control instead of or in addition to removing/hiding the form field. This is done by calling disable() on the control. We will use this together with the related disabled property to achieve the desired effect.

@Component({
  // ...boilerplate 
})
export class MyComponent {
  constructor(readonly formBuilder: FormBuilder) {}

  dataForm = this.formBuilder.group({
    anotherInput: this.formBuilder.control(''), // see note
    myInput: this.formBuilder.control(null, Validators.required)
  });

  disableControl(control: AbstractControl) {
    control.disable();
  }
}

In the template

<form [formGroup]="dataForm">
  <input formControlName="myInput" type="number" 
    [hidden]="dataForm.controls.myInput.disabled">

  <input formControlName="anotherInput">

  <button type="submit" [disabled]="!dataForm.valid">Submit</button>
</form>

<button (click)="disableControl(dataForm.controls.myInput)" type="button"></button>

stackblitz

This also helps use organize the form since we don't have an inputActive property to maintain separately from form state.

Note that the whole form group will be considered disabled if all of its children are disabled.

Aluan Haddad
  • 23,170
  • 5
  • 56
  • 69
1

I had to deal with this recently myself. I ended up creating a custom validator function like this

conditionalRequiredValidator(formControl: AbstractControl) {
    if (!formControl.parent) {
      return null;
    }
    if (inputActive) {
      return Validators.required(formControl);
    }
    return null;
  }

Then reference this function as a validator when you create the FormControl.

Finally, you have to set up a listener for the form control that has the inputActive value, and when its valueChanges call the forms built-in updateValueAndValidity function.

See more here

  • I recently started using angular so I don't know where to put this :c – PacMan Programador Sep 17 '20 at 22:32
  • @PacManProgramador, when you create the form control, should look like this 'myInput: new FormControl(null, [this.conditionalRequiredValidator])`. Might have to use `ViewChild` to get a reference to the form. When you have access to form, you can set up subscription, via `this.formRef.get('controlname').valueChanges.subscribe(value => ...)` – Seth Brotherton Sep 17 '20 at 23:59
0

You are waiting for a directive to behave like a component. An input is a directive when it is not set in the DOM. It is just that. But when you load a component you load all the logic with.
So I propose that you put your input in a component something like app-input than you set Tha validators which you want, any time you shown this component the validators will be automatically active.

Nadhir Houari
  • 393
  • 4
  • 10