Value Exclusion
Value exclusion controls which field values are included in the form submission output based on the field's reactive state (hidden, disabled, readonly).
Overview
By default, field values are excluded from the (submitted) output when the field is hidden, disabled, or readonly. This prevents stale or irrelevant data from being sent to the server.
Key point: Value exclusion only affects the submission output. Internal form controls retain their values so they can be restored when a field becomes visible, enabled, or editable again. Two-way binding via [value] / [(value)] is not affected.
Default Behavior
When no configuration is specified, the defaults are:
| Rule | Default | Effect |
|---|---|---|
excludeValueIfHidden | true | Hidden field values are excluded from submission |
excludeValueIfDisabled | true | Disabled field values are excluded from submission |
excludeValueIfReadonly | true | Read-only field values are excluded from submission |
Breaking change from pre-1.0: Previously, all field values were always included. To restore the old behavior, see
Migration from Previous Versions .
3-Tier Configuration
Value exclusion supports a 3-tier configuration hierarchy. The most specific level wins for each property:
| Priority | Level | Where to set |
|---|---|---|
| 1 (wins) | Field | excludeValueIf* on individual |
| 2 | Form | excludeValueIf* on |
| 3 | Global | feature function |
If a property is undefined at a given level, the next level down is checked.
Global Configuration
Use in your provider setup to configure global defaults:
import { provideDynamicForm , withValueExclusionDefaults } from '@ng-forge/dynamic-forms';
// All exclusions enabled (same as default)
provideDynamicForm (...withMaterialFields (), withValueExclusionDefaults ());
// Disable readonly exclusion globally
provideDynamicForm (...withMaterialFields (), withValueExclusionDefaults ({ excludeValueIfReadonly: false }));
// Disable all exclusions globally (pre-1.0 behavior)
provideDynamicForm (
...withMaterialFields (),
withValueExclusionDefaults ({
excludeValueIfHidden: false,
excludeValueIfDisabled: false,
excludeValueIfReadonly: false,
}),
);Form-Level Configuration
Override the global setting for a specific form using :
const config: FormConfig = {
fields: [...],
options: {
// Include hidden field values for this form only
excludeValueIfHidden: false,
// Use global default for disabled and readonly
}
};Field-Level Configuration
Override both global and form settings for a specific field:
const config: FormConfig = {
fields: [
{
type: 'input',
key: 'internalId',
label: 'Internal ID',
readonly: true,
// Always include this field 's value, even when readonly
excludeValueIfReadonly: false,
},
{
type: 'input',
key: 'notes',
label: 'Notes',
// This field uses the form/global defaults
},
],
};Resolution Example
Given these settings:
- Global:
excludeValueIfHidden: true - Form:
excludeValueIfHidden: false - Field A:
excludeValueIfHidden: undefined(not set) - Field B:
excludeValueIfHidden: true
Resolution:
- Field A uses form-level (
false) because field-level isundefined→ value is included when hidden - Field B uses field-level (
true) → value is excluded when hidden
HiddenField Type
The type (type: 'hidden') is not affected by value exclusion. These fields:
- Store values without rendering any UI
- Have a
hidden()reactive state offalse(they are part of the form, just not rendered) - Are always included in submission output
Value exclusion applies to the hidden property on regular fields (e.g., { type: 'input', hidden: true } or fields hidden via conditional logic), not to the type.
What's Excluded vs Retained
| Aspect | Affected by exclusion? | Details |
|---|---|---|
(submitted) output | Yes | Excluded fields are omitted |
filteredFormValue signal | Yes | Same filtering as submission |
formValue signal | No | Always contains all values |
[(value)] binding | No | Two-way binding retains all values |
| Internal form controls | No | Fields keep their values for restoration |
Migration from Previous Versions
If you relied on all field values being present in (submitted) output, disable exclusion globally:
provideDynamicForm (
...withMaterialFields (),
withValueExclusionDefaults ({
excludeValueIfHidden: false,
excludeValueIfDisabled: false,
excludeValueIfReadonly: false,
}),
);Or disable per-form via :
const config: FormConfig = {
fields: [...],
options: {
excludeValueIfHidden: false,
excludeValueIfDisabled: false,
excludeValueIfReadonly: false,
}
};