Accessing Values of Disabled Controls in Angular Forms: getRawValue() to the Rescue
Here's a breakdown of the concept:
- Disabled Controls: These are form elements (like input fields, select boxes) that users cannot interact with and modify their values.
form.value
: This property on a form group or the entire form holds the current values of all its enabled controls.
Why Disabled Controls Are Excluded:
- Mimicking Native Forms: Disabling controls in Angular forms mirrors how HTML forms work. Disabled controls don't submit their values when the form is submitted, so excluding them from
form.value
ensures consistency. - Clarity and Predictability: Including disabled controls in
form.value
could lead to confusion, as their values wouldn't be used for form submission or processing. This exclusion keeps the submitted data clear and predictable.
When You Might Want Disabled Control Values:
If you have a specific use case where you need the values of both enabled and disabled controls, you can use the following alternative:
getRawValue()
: This method on a form group or the entire form returns an object containing the values of all controls, regardless of their disabled state.
Example:
import { Component } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
@Component({
selector: 'app-my-form',
template: `
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<input type="text" formControlName="name">
<input type="text" formControlName="email" disabled>
<button type="submit">Submit</button>
</form>
<pre>{{ myForm.value | json }}</pre> // Only name (enabled) will be shown
<pre>{{ myForm.getRawValue() | json }}</pre> // Both name and email (disabled) will be shown
`
})
export class MyFormComponent {
myForm: FormGroup;
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
name: [''],
email: ['']
});
}
onSubmit() {
// Access form values here
console.log(this.myForm.value); // Only contains name
}
}
In this example, clicking the submit button will only include the value of the name
control (which is enabled) in the console.log
output. However, getRawValue()
will provide the values of both enabled and disabled controls.
Additional Considerations:
- Use
disabled
judiciously for controls you want to prevent user interaction with, whilereadonly
allows users to see the value but not change it (and its value is included inform.value
). - If you need more control over disabled control behavior, you can explore custom form validation or implementing your own form submission logic.
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-my-form',
template: `
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<label for="name">Name:</label>
<input type="text" formControlName="name" [required]="true">
<br>
<label for="email">Email:</label>
<input type="email" formControlName="email" [required]="true">
<br>
<label for="comments">Comments (optional):</label>
<textarea formControlName="comments"></textarea>
<br>
<input type="checkbox" id="disableEmail" (change)="toggleEmail()">
<label for="disableEmail">Disable Email</label>
<br>
<button type="submit">Submit</button>
</form>
<pre>{{ myForm.value | json }}</pre> <pre>{{ myForm.getRawValue() | json }}</pre> `
})
export class MyFormComponent {
myForm: FormGroup;
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
name: ['', Validators.required],
email: ['', [Validators.required, Validators.email]],
comments: ['']
});
}
onSubmit() {
// Access form values here, considering only enabled controls might be in form.value
console.log(this.myForm.value); // Only contains values for enabled controls
}
toggleEmail() {
const emailControl = this.myForm.get('email');
if (emailControl.disabled) {
emailControl.enable();
} else {
emailControl.disable();
}
}
}
Explanation:
- We've created a reactive form with three controls:
name
,email
, andcomments
. name
andemail
are required, whilecomments
is optional.- A checkbox lets you toggle the disabled state of the
email
control dynamically. - The template displays the form with labels and input elements.
- We use
form.value
andform.getRawValue()
to demonstrate their behavior.
Functionality:
- Initially, both
name
andemail
are enabled and required. - Clicking the submit button will only include the values of enabled controls (currently
name
and potentiallycomments
) inconsole.log
. - Checking the "Disable Email" checkbox will disable the
email
control. - Submitting the form now will exclude the disabled
email
control's value fromconsole.log
. form.getRawValue()
will always include the values of all controls, regardless of their disabled state.
If you only need a subset of disabled controls, you can create a custom function to filter the form.value
object based on a condition. Here's an example:
getIncludedControls(form: FormGroup): any {
const includedValues = {};
Object.keys(form.controls).forEach(controlName => {
const control = form.get(controlName);
if (control.disabled) {
// Your custom logic to determine if this disabled control should be included
if (/* condition to include disabled control */) {
includedValues[controlName] = control.value;
}
} else {
includedValues[controlName] = control.value;
}
});
return includedValues;
}
In this example, the getIncludedControls
function iterates through all controls in the form group. It checks for disabled controls and then applies your custom logic (/* condition to include disabled control */
) to decide whether to include that specific disabled control's value in the returned object.
Combining form.value and form.controls:
If you need both enabled and disabled values but want to differentiate between them, you can combine form.value
with access to individual controls:
getCombinedValues(form: FormGroup): { enabled: any, disabled: any } {
const enabledValues = form.value;
const disabledValues = {};
Object.keys(form.controls).forEach(controlName => {
const control = form.get(controlName);
if (control.disabled) {
disabledValues[controlName] = control.value;
}
});
return { enabled: enabledValues, disabled: disabledValues };
}
Here, the getCombinedValues
function retrieves the enabled values using form.value
. Then, it iterates through controls again, specifically focusing on disabled ones, and stores their values in a separate disabledValues
object. Finally, it returns an object with both enabled
and disabled
properties containing the respective control values.
Choosing the Right Method:
- Use
getRawValue()
when you need all control values, regardless of their disabled state. - Use a custom filtering function when you only need a specific subset of disabled controls based on your own criteria.
- Use the combination of
form.value
andform.controls
when you need both enabled and disabled values and want to treat them differently.
angular angular2-forms