Angular Reactive Form Disabled Control is not valid
Asked Answered
P

2

13

I thought that a disabled control would not get validated. But I'm facing this issue.

I have reproduced using the official Angular reactive form sample:

https://stackblitz.com/edit/angular-hyvj24?file=src/app/dynamic-form-question.component.ts

If you type something in the email field and focus out, this will trigger the change event in which I'm doing :

this.form.controls['firstName'].disable();

enter image description here

And although, firstname is NOT a required field, it gets validated and we see a red message. Without this line of code, firstName can be blank and we'll still be able to save.

Why is that ?

Precedence answered 12/1, 2021 at 23:4 Comment(0)
F
23

When you disabled a control, the control will be valid or not, is the form which is valid although the control is invalid. e.g.

form=new FormGroup({
    control1:new FormControl({value:null,disabled:true},Validators.required),
    control2:new FormControl()
  })

{{form.valid}} //true
{{form.get('control1').valid}}  //false

In your particular case you can change the function isValid for some like:

get isValid() {  
   return this.form.controls[this.question.key].disabled || 
          !this.form.controls[this.question.key].invalid; 
}

Updated Sorry, my bad, in the docs we can see that status can be

  • VALID
  • INVALID
  • PENDING
  • DISABLED

a form control is valid when status is valid -so if status is disabled valid is false. We need use the "oposite" of invalid

get isValid() {  
   return !this.form.controls[this.question.key].invalid; 
}
Fly answered 13/1, 2021 at 8:18 Comment(6)
Thanks. I'm not sure i understand. You are saying that the form is valid, although my disabled control is invalid, right ? But what I'm confused with is why my disabled control is invalid. Why the textbox, although it is not required, is invalid ? And if it is enabled, the validation passes, although there is no value.Precedence
sorry, @Sam, my answer was wrong, you need use invalid to check itFly
Perfect ! Thank you it works. I have to say this behavior is a bit strange though.Precedence
It may work but not right!! The control is not checked at all when it is disabled because it has only one status and necessarily when it is disabled it is not valid/invalid/pendingNeedlefish
What if a required field should not be user-editable but gets updated by another field based on the selection? Then how do we set the whole form as invalid if a disabled field becomes invalid? (The exact problem I am facing now)Evaluate
Update: I guess I can just modify the function to iterate over the ".errors" attribute of the form's controls, and check if there are no errors for each form control... And avoid using ".invalid" entirelyEvaluate
W
0

You are correct that .disable() would not get validated. From the official Angular documentation:

Disables the control. This means the control is exempt from validation checks and excluded from the aggregate value of any parent. Its status is DISABLED. If the control has children, all children are also disabled.

It is the check that is wrong. In the stackbiz it is:

get isValid() { return this.form.controls[this.question.key].valid; }

while it should be:

  get isValid() {
    return this.form.valid;
  }
Whiskey answered 19/12, 2022 at 11:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.