CxJS

Formatting

CxJS provides built-in support for formatting numbers, dates, and currencies. Formats can be applied to widgets via the format property or programmatically using Format.value().

Using Formats

Widgets like NumberField and DateField accept a format property that controls how values are displayed:

<div class="flex flex-col gap-4">
  <LabelsTopLayout columns={2}>
    <NumberField
      value={bind(m.price, 100)}
      label="Price"
      format="currency;USD;2"
    />
    <NumberField value={bind(m.quantity, 5)} label="Quantity" format="n;0" />
    <DateField
      value={bind(m.date, new Date())}
      label="Date"
      format="d;yyyyMMdd"
    />
  </LabelsTopLayout>
  <table class="w-full text-sm mt-4">
    <thead>
      <tr>
        <th class="text-left py-2 pr-4 border-b border-border">Format</th>
        <th class="text-left py-2 border-b border-border">Result</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td class="py-2 pr-4">
          <code>currency;USD;2</code>
        </td>
        <td class="py-2" text={format(m.price, "currency;USD;2")} />
      </tr>
      <tr>
        <td class="py-2 pr-4">
          <code>n;0</code>
        </td>
        <td class="py-2" text={format(m.quantity, "n;0")} />
      </tr>
      <tr>
        <td class="py-2 pr-4">
          <code>d;yyMd</code>
        </td>
        <td class="py-2" text={format(m.date, "d;yyMd")} />
      </tr>
      <tr>
        <td class="py-2 pr-4">
          <code>d;DDDDyyyyMMMMd</code>
        </td>
        <td
          class="py-2"
          text={expr(m.date, (date) => Format.value(date, "d;DDDDyyyyMMMMd"))}
        />
      </tr>
    </tbody>
  </table>
</div>
FormatResult
currency;USD;2$100.00
n;05
d;yyMd1/28/26
d;DDDDyyyyMMMMdWednesday, January 28, 2026

For formatting bound values in text, see the Formatting Values section in Data Binding.

Culture-Sensitive Formatting

Date, currency, and number formats depend on culture settings. Enable culture-sensitive formatting before use:

import { enableCultureSensitiveFormatting } from "cx/ui";

enableCultureSensitiveFormatting();

This ensures formats respect locale-specific conventions for decimal separators, date order, currency symbols, and month/day names.

Format Syntax

Format strings use semicolons to separate parameters:

formatType;param1;param2

Use a pipe | to specify text for null values:

n;2|N/A

Chain multiple formats with colons (applied left-to-right):

n;2:suffix; USD

Number Formats

Number formats support min and max decimal places, plus optional flags: n;minDecimals;maxDecimals;flags. If only one decimal value is provided, it’s used for both min and max.

FormatDescriptionExample InputExample Output
nNumber1234.51,234.5
n;0No decimals1234.51,235
n;2Exactly 2 decimals1234.51,234.50
n;0;20-2 decimals1234.51,234.5
n;0;0;+Plus sign for positive1234+1,234
n;0;0;aAccounting format-1234(1,234)
n;0;0;cCompact notation105000105K
pPercentage (×100)0.2525%
p;0;2Percentage, 0-2 decimals0.25625.6%
ps;0;2Percent sign only (no ×100)25.625.6%

Currency Format

The currency format supports an optional currency code, decimal places, and flags: currency;code;minDecimals;maxDecimals;flags. The currency code can be omitted to use the default currency.

FormatDescriptionExample InputExample Output
currencyDefault currency1234.5$1,234.50
currency;USDUS Dollars1234.5$1,234.50
currency;EUREuros1234.5€1,234.50
currency;USD;0USD, no decimals1234.5$1,235
currency;;2Default currency, 2 decimals1234.5$1,234.50
currency;USD;2;2;+Plus sign for positive1234.5+$1,234.50
currency;USD;2;2;aAccounting format-1234.5($1,234.50)
currency;;0;0;cCompact notation105000$105K

Format Flags

These flags can be added to number and currency formats:

FlagDescription
+Display plus sign for positive numbers
aAccounting format (negative values in parentheses)
cCompact notation (e.g., 105K, 1M)

Flags can be combined, e.g., +ac for all three options. The default currency is determined by culture settings.

String Formats

String formats allow adding prefixes, suffixes, and wrapping values:

FormatDescriptionExample InputExample Output
prefix;Hi Add prefix"John""Hi John"
suffix; cmAdd suffix180"180 cm"
wrap;(;)Wrap with delimiters5"(5)"

These can be chained with other formats:

Format.value(5, "n;2:wrap;(;)"); // "(5.00)"
Format.value(180, "n;0:suffix; cm"); // "180 cm"

Date Formats

Date formats use pattern codes concatenated together. Separators are provided by the culture settings, not the pattern.

FormatDescriptionExample Output
dDefault date2/1/2024
d;yyMdShort year2/1/24
d;yyMMdd2-digit year, padded02/01/24
d;yyyyMMddFull date, padded02/01/2024
d;yyyyMMMdAbbreviated monthFeb 1, 2024
d;yyyyMMMMddFull month nameFebruary 01, 2024
d;DDDyyyyMdShort weekdayThu, 2/1/2024
d;DDDDyyyyMMMddFull weekday, short monthThursday, Feb 01, 2024
d;DDDDyyyyMMMMdFull weekday and monthThursday, February 1, 2024

Date Pattern Characters

Pattern codes are concatenated without separators. Four characters means full name, three is abbreviated, two is padded, one is numeric.

CharacterDescription
yyyy4-digit year
yy2-digit year
MMMMFull month name
MMMAbbreviated month
MM2-digit month
MMonth number
dd2-digit day
dDay number
DDDDFull weekday name
DDDAbbreviated weekday

Time Pattern Characters

CharacterDescription
HHHours (padded)
HHours
mmMinutes (padded)
mMinutes
ssSeconds (padded)
sSeconds
a / AAM/PM indicator
N24-hour format flag

Date and time patterns can be combined: d;yyyyMMddHHmm formats both date and time. Add N for 24-hour format: d;yyyyMMddNHHmm.

For more details on culture-sensitive formatting, see intl-io.

Programmatic Formatting

Use Format.value() to format values in code:

import { Format } from "cx/util";

Format.value(1234.5, "n;2"); // "1,234.50"
Format.value(0.15, "p;0"); // "15%"
Format.value(new Date(), "d;yyyyMMdd"); // "02/01/2024"

Use the format helper to format bound values:

import { format } from "cx/ui";

<span text={format(m.price, "currency;USD")} />;

Alternatively, use expr with Format.value for more control:

import { expr } from "cx/ui";
import { Format } from "cx/util";

<span text={expr(m.price, (price) => Format.value(price, "currency;USD"))} />;

String Templates

Use StringTemplate.format when you need to combine multiple values into a single formatted string:

import { StringTemplate } from "cx/util";

// Positional arguments
StringTemplate.format(
  "{0} bought {1} items for {2:currency;USD}",
  "John",
  5,
  49.99,
);
// "John bought 5 items for $49.99"

// Named properties with an object
StringTemplate.format("{name} - {date:d;yyyyMMdd}", {
  name: "Report",
  date: new Date(),
});
// "Report - 02/01/2024"

Use StringTemplate.compile to create a reusable formatter function:

const formatter = StringTemplate.compile("{name}: {value:currency;USD}");
formatter({ name: "Total", value: 99.99 }); // "Total: $99.99"
formatter({ name: "Tax", value: 7.5 }); // "Tax: $7.50"

Custom Formats

Register custom formats using Format.register:

import { Format } from "cx/util";

// Simple format
Format.register("brackets", (value) => `(${value})`);

// Use it
Format.value("test", "brackets"); // "(test)"

For formats with parameters, use Format.registerFactory:

Format.registerFactory("suffix", (format, suffix) => {
  return (value) => value + suffix;
});

// Use it
Format.value(100, "suffix; kg"); // "100 kg"