Components
customcurrencyformatinput
A monetary amount input that displays comma-formatted values (e.g. 1,000,000 RWF) while preserving the raw formatted string in the model.
A monetary amount input that renders comma thousand-separators on every keystroke (1000000 → "1,000,000"). Use this instead of input type="number" whenever formatted display matters.
Read Form Rules before using this component — keys, labels, required fields, expressions, visibility, and validation all follow shared conventions.
When to use
- Any monetary amount that must display with comma formatting (e.g. vehicle value, net premium, installment amounts in RWF)
- Read-only computed amounts that display a formatted result populated by a fetch
When NOT to use
Instead of customcurrencyformatinput, use… | For… |
|---|---|
input with props.type: "number" | Plain integers with no formatting requirement |
input | Non-monetary reference numbers or free-text quantities |
Important: The stored form control value is the formatted string (
"1,000,000"), not the integer1000000. Strip commas before submitting to an API.
Props
| Prop | Type | Required? | Description |
|---|---|---|---|
label | string | required | Visible label. Must be unique across the form. |
required | boolean | required | Always false. The expression controls the runtime value. |
defaultRequired | boolean | required | true for required fields, false for optional ones. |
currencyCode | string | optional | Currency code displayed alongside the input (e.g. "RWF"). |
currencyFormatting | boolean | optional | Enables comma-formatted display. Defaults to true for this component. |
placeholder | string | optional | Ghost text shown inside the input. |
disabled | boolean | optional | Disables the field. |
readonly | boolean | optional | Renders the field non-editable. Set true for computed/auto-populated amounts. |
hidden | boolean | optional | Hides the field via CSS. Prefer expressions.hide or expressions.props.hideField instead. |
hideField | boolean | optional | Hides the field and excludes its value. Toggle via expressions["props.hideField"]. |
No
min/maxprops. This component has no built-in range validation. Use custom formly validators if range constraints are needed.
Examples
Basic required amount
{
"key": "VEHICLE_VALUE",
"type": "customcurrencyformatinput",
"props": {
"label": "Vehicle Value",
"required": false,
"defaultRequired": true,
"placeholder": "Enter vehicle value",
"currencyCode": "RWF",
"currencyFormatting": true
},
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {
"required": "Vehicle value is required"
}
}
}Read-only computed amount (populated by fetch)
{
"key": "NET_PREMIUM",
"type": "customcurrencyformatinput",
"props": {
"label": "Net Premium",
"required": false,
"defaultRequired": false,
"readonly": true,
"currencyCode": "RWF",
"currencyFormatting": true
},
"expressions": {
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {}
}
}Conditionally visible amount
{
"key": "INSTALLMENT_AMOUNT",
"type": "customcurrencyformatinput",
"props": {
"label": "First Installment Amount",
"required": false,
"defaultRequired": false,
"readonly": true,
"hideField": true,
"currencyCode": "RWF",
"currencyFormatting": true
},
"expressions": {
"hide": "!model?.PAYMENT_PLAN || model?.PAYMENT_PLAN !== 'INSTALLMENTS'",
"props.hideField": "!model?.PAYMENT_PLAN || model?.PAYMENT_PLAN !== 'INSTALLMENTS'",
"props.required": "!(field?.props?.hideField || field?.hide) && field?.props?.defaultRequired"
},
"validation": {
"messages": {}
}
}Common mistakes
- Expecting the form value to be a number — the stored value is the formatted string
"1,000,000", not1000000. Strip commas (value.replace(/,/g, '')) before sending to an API. - Adding
props.minorprops.max— these props are not read by the component and have no effect. - Adding
props.locale— this component has no locale support. Useprops.currencyCodefor the currency symbol. - Setting
props.hidden: truestatically — the field is permanently hidden. Useexpressions.hideorexpressions.props.hideFieldinstead. - Using
input type="number"when formatted display is needed — plaininputstores a raw number without comma formatting.
Checklist
-
keyisUPPER_SNAKE_CASEand unique across the entire form -
props.labelis present, unique, and correctly cased - Field is nested at the correct depth:
sections > formly-group > block > customcurrencyformatinput -
required: false(nevertrue) -
defaultRequiredis set -
expressions["props.required"]is present -
currencyCodeandcurrencyFormattingare set - Downstream APIs strip commas from the value before processing