Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get all Angular form controls that have changed from enabled to disabled, or vice versa?

TL,DR; A FormGroup is not considered dirty when a nested FormControl is changed from disabled to enabled, or vice versa.

Detail; What is a good way of getting all form controls belonging to a FormGroup, that have changed from enabled to disabled, or vice versa?

As this Stackblitz shows, the pristine, dirty, touched, and untouched properties remain unchanged when a control changes from enabled to disabled, or vice versa.

export class AppComponent implements OnInit {
  person: FormGroup;
  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.person = this.fb.group({
      name: this.fb.control(''),
      age: this.fb.control(100),
    });
  }
}

The Typescript above defines a single FormGroup (person) with two FormControls (name and age).

The HTML below allows the name control to be enabled and disabled by clicking a button. Some properties are output too.

<form [formGroup]="person">
    <input type="text" placeholder="Name" formControlName="name">
    <button (click)="person.controls['name'].disable()">Disable</button>
    <button (click)="person.controls['name'].enable()">Enable</button>
    <br />
    <br />
    <input type="text" placeholder="Age" formControlName="age">
</form>

<pre>{{person.value | json}}</pre>

disabled: {{ person.disabled }}<br />
pristine: {{ person.pristine }}<br />
dirty: {{ person.dirty }}<br />
touched: {{ person.touched }}<br />
untouched: {{ person.untouched }}<br />

enter image description here

I'd expected it to be easy to detect when a control is:

  • enabled (where it was previously disabled)
  • disabled (where it was previously enabled)

Unlike the pristine, dirty, touched, and untouched properties, the enabled and disabled state seems transient.

It seems there is no property of a FormGroup that reflects if child controls have been enabled or disabled away from their original state? The FormGroup remains pristine and untouched.

It has been suggested to use statusChanges. However, this only provides four possible validation status values (VALID, INVALID, PENDING, DISABLED). There is no clear way to map the status to a control and subsequently determine whether is has changed from enabled to disabled or vice versa. I've created another Stackblitz demonstrating this.

EDIT

I've opened a bug FormGroup not dirty when a nested FormControl changes from disabled to enabled, or vice versa.

like image 297
Jack Avatar asked Sep 17 '25 20:09

Jack


1 Answers

You can try to give a shot to listen for control status changes - one of them is disabled

https://angular.io/api/forms/AbstractControl#status

https://angular.io/api/forms/AbstractControl#statusChanges

EDIT:

There is obvious method for that, but it is called registerOnDisabledChange

https://angular.io/api/forms/FormControl#registerOnDisabledChange

Showcase forked form your stackblitz https://stackblitz.com/edit/formbuilder-soydhk

If you need to listen for that on controll level, nothing stands in your way to write aggregating listener.

like image 177
Antoniossss Avatar answered Sep 19 '25 12:09

Antoniossss