Field Formatting
Field formatting controls how values appear in your tools. You can format numbers as currencies, add colours to status badges, mask sensitive data, and create consistent displays across all your tools.
Formatting is configured in the _fields.json file, which applies formatting globally. When you format a field like Order.totalAmount as currency, that formatting appears everywhere the field is displayed: in tables, record views, and embedded lists.
The _fields.json file
Create a _fields.json file in your tools/ directory to define field formatting:
your-project/
├── schema.keel
└── tools/
└── _fields.jsonThe file contains an array of field configurations:
[
{
"id": "Order.totalAmount",
"format": {
"number_config": {
"mode": "CURRENCY",
"currency_code": "GBP"
}
}
},
{
"id": "OrderStatus",
"format": {
"enum_config": {
"values": [
{ "value": "Pending", "colour": "#f59e0b" },
{ "value": "Shipped", "colour": "#3b82f6" },
{ "value": "Delivered", "colour": "#22c55e" }
]
}
}
}
]Field identifiers
The id field uses one of two formats:
| Format | Use case | Example |
|---|---|---|
ModelName.fieldName | Model fields | Order.totalAmount, StockItem.quantity |
EnumName | Enum types | OrderStatus, PaymentMethod |
Enum formatting applies to all fields that use that enum, regardless of which model they belong to.
Number formatting
Number fields support five display modes, plus options for colours, prefixes, and sensitive data handling.
Format modes
| Mode | Description | Input | Output |
|---|---|---|---|
DECIMAL | Standard decimal with locale formatting (default) | 1234.56 | 1,234.56 |
RAW | No formatting applied | 1234.56 | 1234.56 |
CURRENCY | Currency with symbol from currency_code | 1234.56 | £1,234.56 |
PERCENTAGE | Percentage display | 0.125 | 12.5% |
UNIT | Display with unit from unit_code | 150 | 150 kg |
Currency formatting
Display monetary values with the appropriate currency symbol and formatting:
[
{
"id": "Order.totalAmount",
"format": {
"number_config": {
"mode": "CURRENCY",
"currency_code": "GBP"
}
}
},
{
"id": "Order.shippingCost",
"format": {
"number_config": {
"mode": "CURRENCY",
"currency_code": "USD",
"locale": "en-US"
}
}
}
]The currency_code uses ISO 4217 (opens in a new tab) codes. Common codes include:
| Code | Currency |
|---|---|
GBP | British Pound |
USD | US Dollar |
EUR | Euro |
JPY | Japanese Yen |
CAD | Canadian Dollar |
AUD | Australian Dollar |
Currency formatting uses the browser's locale by default. Set locale explicitly if you need consistent formatting regardless of user location.
Percentage formatting
Display decimal values as percentages:
[
{
"id": "Product.discountRate",
"format": {
"number_config": {
"mode": "PERCENTAGE"
}
}
},
{
"id": "Order.taxRate",
"format": {
"number_config": {
"mode": "PERCENTAGE"
}
}
}
]A value of 0.15 displays as 15%.
Unit formatting
Display quantities with measurement units:
[
{
"id": "StockItem.weight",
"format": {
"number_config": {
"mode": "UNIT",
"unit_code": "kilogram"
}
}
},
{
"id": "Shipment.distance",
"format": {
"number_config": {
"mode": "UNIT",
"unit_code": "kilometer"
}
}
}
]The unit_code supports compound units like meter-per-second for derived measurements.
Conditional colouring
Colour numbers based on whether they're positive or negative. This is useful for financial data where gains and losses need visual distinction:
[
{
"id": "Order.profitMargin",
"format": {
"number_config": {
"mode": "CURRENCY",
"currency_code": "GBP",
"colourise": "NORMAL"
}
}
},
{
"id": "StockItem.quantityVariance",
"format": {
"number_config": {
"mode": "DECIMAL",
"colourise": "INVERTED"
}
}
}
]| Mode | Positive values | Negative values |
|---|---|---|
NONE | No colour (default) | No colour |
NORMAL | Green | Red |
INVERTED | Red | Green |
Use INVERTED when negative values are good (like cost reductions) and positive values indicate problems.
Prefix and suffix
Add text before or after the formatted number:
[
{
"id": "Order.reference",
"format": {
"number_config": {
"prefix": "ORD-",
"mode": "RAW"
}
}
},
{
"id": "Product.leadTime",
"format": {
"number_config": {
"suffix": " days",
"mode": "DECIMAL"
}
}
}
]Sensitive number data
Mask financial or confidential numeric values:
[
{
"id": "Supplier.creditLimit",
"format": {
"number_config": {
"mode": "CURRENCY",
"currency_code": "GBP",
"sensitive": true
}
}
}
]Sensitive fields display as masked content until the user hovers over them.
Number formatting options
| Option | Type | Description |
|---|---|---|
mode | string | DECIMAL, RAW, CURRENCY, PERCENTAGE, or UNIT |
currency_code | string | ISO 4217 currency code (required for CURRENCY mode) |
unit_code | string | Unit identifier (required for UNIT mode) |
locale | string | Locale code for formatting (auto-detected by default) |
prefix | string | Text prepended to the value |
suffix | string | Text appended to the value |
sensitive | boolean | Masks the value until hovered |
colourise | string | Colour mode: NONE, NORMAL, or INVERTED |
A CUSTOM colourise mode exists in the schema but is not yet implemented.
Enum formatting
Enum fields can display custom labels and colours for each value. This is particularly useful for status fields where visual distinction helps users scan data quickly.
Basic enum colours
[
{
"id": "OrderStatus",
"format": {
"enum_config": {
"values": [
{ "value": "Pending", "colour": "#f59e0b" },
{ "value": "Processing", "colour": "#3b82f6" },
{ "value": "Shipped", "colour": "#8b5cf6" },
{ "value": "Delivered", "colour": "#22c55e" },
{ "value": "Cancelled", "colour": "#ef4444" }
]
}
}
}
]Colours display as coloured badges in tables and record views.
Custom display labels
Show user-friendly labels instead of the schema enum values:
[
{
"id": "PaymentStatus",
"format": {
"enum_config": {
"values": [
{
"value": "AwaitingPayment",
"display_value": "Awaiting Payment",
"colour": "#f59e0b"
},
{
"value": "PaymentReceived",
"display_value": "Payment Received",
"colour": "#22c55e"
},
{
"value": "PaymentFailed",
"display_value": "Payment Failed",
"colour": "#ef4444"
},
{
"value": "Refunded",
"display_value": "Refunded",
"colour": "#6b7280"
}
]
}
}
}
]Ordering enum values
Control the order of enum values in dropdowns and filters:
[
{
"id": "Priority",
"format": {
"enum_config": {
"values": [
{ "value": "Critical", "colour": "#ef4444", "display_order": 1 },
{ "value": "High", "colour": "#f59e0b", "display_order": 2 },
{ "value": "Medium", "colour": "#3b82f6", "display_order": 3 },
{ "value": "Low", "colour": "#6b7280", "display_order": 4 }
]
}
}
}
]Enum value options
| Option | Type | Description |
|---|---|---|
value | string | The actual enum value in your schema |
display_value | string | Label shown in the UI (defaults to value) |
colour | string | Hex colour code for the badge |
display_order | number | Order in dropdowns and filters |
Use colours with good contrast and consider accessibility. Avoid relying solely on colour to convey meaning. The display label should also indicate the status.
Boolean formatting
Boolean fields can display custom labels and colours for true and false states:
[
{
"id": "StockItem.inStock",
"format": {
"bool_config": {
"positive_value": "In Stock",
"positive_colour": "#22c55e",
"negative_value": "Out of Stock",
"negative_colour": "#ef4444"
}
}
},
{
"id": "Order.isPriority",
"format": {
"bool_config": {
"positive_value": "Priority",
"positive_colour": "#ef4444",
"negative_value": "Standard",
"negative_colour": "#6b7280"
}
}
}
]Boolean formatting options
| Option | Type | Description |
|---|---|---|
positive_value | string | Label when value is true |
positive_colour | string | Hex colour when value is true |
negative_value | string | Label when value is false |
negative_colour | string | Hex colour when value is false |
String formatting
String fields support prefixes, suffixes, text colours, URL previews, and sensitive data masking.
Prefix and suffix
Add consistent formatting to text values:
[
{
"id": "Order.reference",
"format": {
"string_config": {
"prefix": "ORD-"
}
}
},
{
"id": "Product.sku",
"format": {
"string_config": {
"prefix": "SKU-"
}
}
}
]Text colour
Apply a consistent colour to text values:
[
{
"id": "Order.internalNotes",
"format": {
"string_config": {
"text_colour": "#6b7280"
}
}
}
]URL previews
Render string fields containing URLs as clickable links:
[
{
"id": "Product.websiteUrl",
"format": {
"string_config": {
"show_url_preview": true
}
}
},
{
"id": "Shipment.trackingUrl",
"format": {
"string_config": {
"show_url_preview": true
}
}
}
]Sensitive string data
Mask confidential text values:
[
{
"id": "Customer.apiKey",
"format": {
"string_config": {
"sensitive": true
}
}
},
{
"id": "Supplier.accountNumber",
"format": {
"string_config": {
"sensitive": true
}
}
}
]Sensitive fields show masked content until the user hovers over them.
String formatting options
| Option | Type | Description |
|---|---|---|
prefix | string | Text prepended to the value |
suffix | string | Text appended to the value |
text_colour | string | Hex colour for the text |
show_url_preview | boolean | Renders URLs as clickable links |
sensitive | boolean | Masks the value until hovered |
Date and time display
Date and time fields (Date, Timestamp) are automatically formatted based on the user's browser locale. Keel handles timezone conversions and displays dates in a human-readable format appropriate for the user's region.
Date and time formatting is automatic and locale-aware. There's no configuration needed. Fields display appropriately based on each user's browser settings.
Additional field options
Beyond formatting, _fields.json also supports these display options that apply globally:
[
{
"id": "Order.internalCode",
"visible": false
},
{
"id": "Product.thumbnail",
"image_preview": true
},
{
"id": "StockItem.location",
"display_name": "Storage Location",
"help_text": "The warehouse location where this item is stored"
}
]| Option | Type | Description |
|---|---|---|
visible | boolean | Whether the field is shown by default |
display_name | string | Label shown instead of the field name |
help_text | string | Explanatory text shown with the field |
image_preview | boolean | For file fields, shows inline image previews |
Complete ERP example
Here's a comprehensive example for an order management system:
[
{
"id": "Order.reference",
"format": {
"string_config": {
"prefix": "ORD-"
}
}
},
{
"id": "Order.totalAmount",
"format": {
"number_config": {
"mode": "CURRENCY",
"currency_code": "GBP"
}
}
},
{
"id": "Order.discountAmount",
"format": {
"number_config": {
"mode": "CURRENCY",
"currency_code": "GBP",
"colourise": "INVERTED"
}
}
},
{
"id": "Order.taxRate",
"format": {
"number_config": {
"mode": "PERCENTAGE"
}
}
},
{
"id": "Order.isPriority",
"format": {
"bool_config": {
"positive_value": "Priority",
"positive_colour": "#ef4444",
"negative_value": "Standard",
"negative_colour": "#6b7280"
}
}
},
{
"id": "OrderStatus",
"format": {
"enum_config": {
"values": [
{ "value": "Draft", "colour": "#9ca3af", "display_order": 1 },
{ "value": "Pending", "colour": "#f59e0b", "display_order": 2 },
{ "value": "Confirmed", "colour": "#3b82f6", "display_order": 3 },
{ "value": "Processing", "colour": "#8b5cf6", "display_order": 4 },
{ "value": "Shipped", "colour": "#06b6d4", "display_order": 5 },
{ "value": "Delivered", "colour": "#22c55e", "display_order": 6 },
{ "value": "Cancelled", "colour": "#ef4444", "display_order": 7 }
]
}
}
},
{
"id": "StockItem.sku",
"format": {
"string_config": {
"prefix": "SKU-"
}
}
},
{
"id": "StockItem.quantity",
"format": {
"number_config": {
"mode": "DECIMAL",
"colourise": "NORMAL"
}
}
},
{
"id": "StockItem.unitCost",
"format": {
"number_config": {
"mode": "CURRENCY",
"currency_code": "GBP"
}
}
},
{
"id": "StockItem.weight",
"format": {
"number_config": {
"mode": "UNIT",
"unit_code": "kilogram"
}
}
},
{
"id": "StockItem.inStock",
"format": {
"bool_config": {
"positive_value": "In Stock",
"positive_colour": "#22c55e",
"negative_value": "Out of Stock",
"negative_colour": "#ef4444"
}
}
},
{
"id": "Shipment.trackingUrl",
"format": {
"string_config": {
"show_url_preview": true
}
}
},
{
"id": "ShipmentStatus",
"format": {
"enum_config": {
"values": [
{ "value": "Preparing", "colour": "#f59e0b" },
{ "value": "AwaitingPickup", "display_value": "Awaiting Pickup", "colour": "#3b82f6" },
{ "value": "InTransit", "display_value": "In Transit", "colour": "#8b5cf6" },
{ "value": "OutForDelivery", "display_value": "Out for Delivery", "colour": "#06b6d4" },
{ "value": "Delivered", "colour": "#22c55e" },
{ "value": "Failed", "colour": "#ef4444" }
]
}
}
},
{
"id": "PaymentMethod",
"format": {
"enum_config": {
"values": [
{ "value": "Card", "display_value": "Credit/Debit Card" },
{ "value": "BankTransfer", "display_value": "Bank Transfer" },
{ "value": "Invoice", "display_value": "Invoice (Net 30)" },
{ "value": "Cash", "display_value": "Cash on Delivery" }
]
}
}
}
]This configuration:
- Adds "ORD-" and "SKU-" prefixes to reference numbers
- Formats all monetary values as British pounds
- Shows discounts in red (using inverted colouring)
- Displays tax rates as percentages
- Colours order and shipment status badges for quick scanning
- Shows stock availability with clear in/out of stock labels
- Makes tracking URLs clickable
- Provides user-friendly labels for payment methods