My App

Monetary Field

Currency field with automatic validation, transformation, and display formatting

The monetary field is for currency data with automatic validation, transformation, and special display formatting. It's nearly identical to the numeric field except it includes currency-specific display options and defaults to 2 decimal places (currency standard).

When to Use

Use monetary when you need:

  • Currency data with display formatting (thousand separators, currency symbols, abbreviations)
  • The display options for numbro.js formatting

Use numeric when you need:

  • Non-currency numeric data without special display formatting
  • Everything else is identical between the two fields

Key difference: Monetary has display options for UI formatting. Numeric does not. That's it.

Basic Usage

{
  type: 'monetary',
  label: 'Price',
  key: 'price',
  order: 0,
  locale: 'English (Australia)'
}

This automatically:

  • Strips currency symbols from input ($, €, £, etc.)
  • Rounds to 2 decimal places
  • Displays with thousand separators and currency symbol
  • Validates as numeric

Properties

  • locale (ILocaleLanguage) - Locale for display formatting (e.g., 'English (Australia)', 'German (Germany)'). Default: 'en-AU' (Australian English) if not specified

Optional

Auto-Clean Options

Controls automatic data transformation on load and cell changes:

  • autoClean (false | object) - Controls automatic data cleaning. Default: enabled with defaults below
    • Set to false to disable auto-cleaning (only smartFix suggestions will be available)
    • Set to object to customize cleaning behavior

When autoClean is enabled (default), you can configure:

  • autoClean.decimalPlaces (number) - Number of decimal places to keep. Default: 2
  • autoClean.decimalHandling ('drop' | 'round' | 'ceil' | 'floor') - How to handle decimals. Default: 'round'
  • autoClean.stripCurrencySymbols (boolean) - Whether to strip currency symbols. Default: true
  • autoClean.stripOnlyTheseCurrencies (string[] | 'any') - Which currencies to strip. Default: 'any' (strips all currency symbols)
  • autoClean.currencyPosition ('prefix' | 'suffix' | 'both') - Where to look for currency symbols. Default: 'both'

See ICleanNumberOptions for all options.

Important: Currency symbols in input data are treated as formatting noise and stripped during cleaning. The field's locale and display.currencySymbol determine how the value is displayed, not the input symbol. For example, "$100" in a field with locale: 'en-GB' becomes 100 (stored) and displays as "£100". To restrict which currency symbols are accepted, use stripOnlyTheseCurrencies: ['£'] instead of 'any'.

Note: SmartFix suggestions always use these same options, even if autoClean: false.

Display Options

Controls how data is displayed in the UI (view-only formatting):

  • display.average (boolean) - Show abbreviated numbers (1234 → 1k). Default: true
  • display.currencySymbol (string) - Currency symbol to display (e.g., '$', '€'). Default: locale-specific
  • display.currencyPosition ('prefix' | 'postfix' | 'infix') - Where to show currency symbol. Default: locale-specific
  • display.thousandSeparated (boolean) - Show thousand separators. Default: true
  • display.spaceSeparated (boolean) - Use spaces as separators. Default: false

Other

  • defaultValue (number) - Default monetary value

Plus all common field properties.

Automatic Behavior

The SDK automatically:

  • Adds a numeric validator (if not present) with autoFixOptions for smartFix suggestions
  • Adds a CleanNumbers transformer (unless autoClean: false) that runs on load and cell changes
  • Formats numbers for display using numbro.js based on your display options and locale

Examples

Basic with Defaults

{
  type: 'monetary',
  label: 'Price',
  key: 'price',
  order: 0,
  locale: 'English (Australia)'
}

Behavior:

  • Input: "$1,234.567" → Stored: 1234.57 → Displayed: "$1.23k"
  • Rounds to 2 decimals, strips currency, shows abbreviated

Custom Auto-Clean Options

{
  type: 'monetary',
  label: 'Precise Amount',
  key: 'amount',
  order: 0,
  locale: 'English (Australia)',
  autoClean: {
    decimalPlaces: 4,
    decimalHandling: 'floor',
    stripOnlyTheseCurrencies: ['$']
  }
}

Behavior:

  • Input: "$1,234.56789" → Stored: 1234.5678 → Displayed: "$1.23k"
  • Keeps 4 decimals (floors), only strips $, rejects € or £

Disable Auto-Clean (Strict Mode)

{
  type: 'monetary',
  label: 'Strict Price',
  key: 'price',
  order: 0,
  locale: 'English (Australia)',
  autoClean: false
}

Behavior:

  • Input: "$1,234.56" → Validation fails (currency symbol not allowed)
  • Input: "1234.56" → Stored: 1234.56 → Displayed: "$1.23k"
  • No automatic cleaning, user must provide clean numbers or use smartFix suggestions

Custom Display Options

{
  type: 'monetary',
  label: 'Full Amount',
  key: 'fullAmount',
  order: 0,
  locale: 'German (Germany)',
  display: {
    average: false,
    currencySymbol: '€',
    currencyPosition: 'postfix',
    spaceSeparated: true
  }
}

Behavior:

  • Input: "1234567.89" → Stored: 1234567.89 → Displayed: "1 234 567,89€"
  • No abbreviation, space-separated, euro suffix

Strict Precision with Validation

{
  type: 'monetary',
  label: 'Payment',
  key: 'payment',
  order: 0,
  locale: 'English (Australia)',
  autoClean: {
    decimalPlaces: 2,
    decimalHandling: 'round'
  },
  display: {
    average: false
  },
  validators: [
    { type: 'required' },
    { type: 'min', value: 0 }
  ]
}

Behavior:

  • Input: "$99.999" → Stored: 100.00 → Displayed: "$100.00"
  • Rounds to 2 decimals, no abbreviation, validates positive

Currency Symbol Handling

{
  type: 'monetary',
  label: 'Price (GBP)',
  key: 'price',
  order: 0,
  locale: 'English (United Kingdom)',
  display: {
    currencySymbol: '£'
  }
}

Behavior (default - strips all currencies):

  • Input: "$100" → Stored: 100 → Displayed: "£100"
  • Input: "€100" → Stored: 100 → Displayed: "£100"
  • Input: "£100" → Stored: 100 → Displayed: "£100"

Note: Currency symbols are stripped during cleaning. The display currency is determined by the field's locale and display.currencySymbol, not the input.

Strict Currency Validation

{
  type: 'monetary',
  label: 'Price (GBP only)',
  key: 'price',
  order: 0,
  locale: 'English (United Kingdom)',
  autoClean: {
    stripCurrencySymbols: true,
    stripOnlyTheseCurrencies: ['£'] // Only accept pounds
  },
  display: {
    currencySymbol: '£'
  }
}

Behavior (strict - only accepts £):

  • Input: "£100" → Stored: 100 → Displayed: "£100"
  • Input: "$100" → Error: "Must be a number" ($ not in whitelist) ✗
  • Input: "€100" → Error: "Must be a number" (€ not in whitelist) ✗

How Locale Works

The locale property controls everything related to number handling:

1. Input Parsing

Numbers are parsed according to the locale's delimiter rules:

  • 'English (Australia)' → Accepts 1,234.56 (comma thousands, dot decimal)
  • 'German (Germany)' → Accepts 1.234,56 (dot thousands, comma decimal)
  • 'French (France)' → Accepts 1 234,56 (space thousands, comma decimal)

2. Validation

Validators automatically use the field's locale:

  • German locale: 1.234,56 passes validation
  • German locale: 1,234.56 fails validation (wrong format)

3. Transformation

The CleanNumbers transformer uses the locale to parse and clean data.

4. Display

Numbers are formatted for display using the locale's conventions:

  • Australian: $1,234.56
  • German: 1.234,56 €
  • French: 1 234,56 €

One locale controls all four stages. This ensures consistency throughout the data pipeline.

Locale-Aware Number Parsing

The monetary field automatically parses numbers according to the locale's delimiter rules:

Supported Delimiter Patterns

PatternThousandsDecimalExampleLocales
Australian/US-style,.1,234.56en-AU, en-GB, es-MX, ja-JP, zh-CN
EU-style.,1.234,56de-DE, es-ES, it-IT, nl-NL, pt-PT
Space-style (space),1 234,56fr-FR, fr-CA, sv-SE, ru-RU, pl-PL
Swiss-style'.1'234.56de-CH, de-LI, it-CH
Swiss-French (space).1 234.56fr-CH

How It Works

// German locale
{
  type: 'monetary',
  locale: 'German (Germany)',
  key: 'amount'
}

Input validation:

  • "1.234,56" → Parsed as 1234.56
  • "€1.234,56" → Parsed as 1234.56 (currency stripped)
  • "1,234.56" → Rejected (wrong format for German locale)
// US locale
{
  type: 'monetary',
  locale: 'English (Australia)',
  key: 'amount'
}

Input validation:

  • "1,234.56" → Parsed as 1234.56
  • "$1,234.56" → Parsed as 1234.56 (currency stripped)
  • "1.234,56" → Rejected (wrong format for US locale)

Benefits

  • User-friendly: Users can paste data from their local Excel/Google Sheets without reformatting
  • Validation: Prevents incorrect number formats from being accepted
  • Automatic: No configuration needed - locale determines parsing rules

Transform vs Display

Transform options affect the actual data:

transform: {
  decimalPlaces: 2  // Data will have exactly 2 decimals
}
  • Input: 1234.56789
  • Stored: 1234.57
  • Submitted to backend: 1234.57

Display options only affect the UI:

display: {
  average: true  // Shows "1k" but data is still 1234.57
}
  • Stored: 1234.57
  • Displayed: "$1.23k"
  • Submitted to backend: 1234.57

Equivalent Numeric Field

This monetary field:

{
  type: 'monetary',
  locale: 'English (Australia)',
  transform: { decimalPlaces: 2 }
}

Is equivalent to:

{
  type: 'numeric',
  validators: [
    {
      type: 'numeric',
      allowDecimals: true,
      autoFixOptions: {
        decimalPlaces: 2,
        decimalHandling: 'round',
        stripCurrencySymbols: true,
        stripOnlyTheseCurrencies: 'any'
      }
    }
  ],
  transformers: [
    {
      action: 'cleanNumbers',
      payload: {
        options: {
          decimalPlaces: 2,
          decimalHandling: 'round',
          stripCurrencySymbols: true,
          stripOnlyTheseCurrencies: 'any'
        }
      }
    }
  ]
}

But monetary also adds currency display formatting that numeric doesn't provide.

On this page