AdvancedCustom Fields

ADVANCED

Custom Fields

Define specific attributes for your inventory items beyond the standard fields — with their own data type, validation rules, and display format.


Overview

Custom fields allow you to track exactly the information you need for each item type. Each field can have its own data type, validation rules, and display format, enabling rich and structured inventory data.

custom_field_definition.dartenum CustomFieldType
enum CustomFieldType {
text,       // General text input
number,     // Numeric without decimals
date,       // Date picker
dropdown,   // Predefined list of options
boolean,    // Yes / No
url,        // Web address with validation
price,      // Monetary value with decimal precision
}

Field Types

text

Text

General text input for names, descriptions, and labels

Serial numbersNotesConditionsLabels

TextInputType.text

number

Number

Numeric values without decimals

QuantityYearEdition numberCount

TextInputType.number

price

Price

Monetary values with decimal precision

Purchase priceCurrent valueMSRP

TextInputType.numberWithOptions(decimal: true)

date

Date

Date picker for temporal data

Purchase dateWarranty expiryRelease date

TextInputType.datetime

dropdown

Dropdown

Predefined list of selectable options

ConditionStatusCategoryPlatform

N/A (picker)

boolean

Boolean

Yes / No or True / False values

Complete-in-boxWorkingFavourite

N/A (toggle)

url

URL

Web addresses with format validation

Product pageManual PDFRelated links

TextInputType.url

Field Type Implementation

Each field type exposes several computed properties used by the UI and API:

Technical Name (dbName)

String get dbName {
return name.toLowerCase();
}

Used for API communication and database storage. Always lowercase.

Display Name

case CustomFieldType.text:
return 'Texto';
case CustomFieldType.number:
return 'Número';
case CustomFieldType.date:
return 'Fecha';
case CustomFieldType.dropdown:
return 'Desplegable';
case CustomFieldType.boolean:
return 'Sí/No (Booleano)';
case CustomFieldType.url:
return 'URL';
case CustomFieldType.price:
return 'Precio';

Keyboard Type

case CustomFieldType.number:
return TextInputType.number;
case CustomFieldType.price:
return TextInputType.numberWithOptions(
  decimal: true, signed: false);
case CustomFieldType.url:
return TextInputType.url;
case CustomFieldType.date:
return TextInputType.datetime;
default:
return TextInputType.text;

Optimizes mobile keyboard for each data type.

Field Validation

Custom fields include built-in validation triggered when items are saved:

URL Validation
case CustomFieldType.url:
final urlPattern = RegExp(
  r'^(https?|ftp)://[^s/$.?#].[^s]*$');
if (!urlPattern.hasMatch(value)) {
  return 'Introduce una URL válida';
}
break;

Rules

Must start with http://, https://, or ftp://
Valid domain structure required
No whitespace or invalid characters
Rendered as clickable link in item views
Price Validation
case CustomFieldType.price:
final pricePattern = RegExp(r'^d+([.,]d{0,2})?$');
if (!pricePattern.hasMatch(value)) {
  return 'Introduce un precio válido (ej: 123.45)';
}
break;

Rules

Must be numeric
Comma or period accepted as decimal separator
Maximum two decimal places
No negative values
custom_field_definition.dart:82 — validateValue
String? validateValue(String? value) {
if (value == null || value.isEmpty) return null;

// Type-specific validation
switch (this) {
  // ... validation logic per type
}
return null; // Validation passed
}

Price Formatting — Auto-applied on save

String formatValue(String value) {
switch (this) {
  case CustomFieldType.price:
    final double? number = double.tryParse(value.replaceAll(',', '.'));
    if (number != null) {
      return number.toStringAsFixed(2);
    }
    return value;
  default:
    return value;
}
}
"123""123.00"
"45.6""45.60"
"99,99""99.99"

Creating Custom Field Definitions

Step 01

Add Field Definition

Define a new custom field with its name, type, and optional properties:

{
"name": "Purchase Price",
"type": "price",
"required": false,
"defaultValue": "0.00"
}
Step 02

Configure Properties

Name

Display label for the field

Type

One of the seven field types

Required

Must the field be filled?

Default Value

Initial value for new items

Helper Text

Guidance shown to users

Step 03

Add Dropdown Options (if applicable)

{
"name": "Condition",
"type": "dropdown",
"options": [
  "Mint",
  "Near Mint",
  "Excellent",
  "Good",
  "Fair",
  "Poor"
]
}
Step 04

Test Validation

Create a test item to verify that everything works:

Validation works correctly
Formatting is applied
Default values appear
Required fields enforced

Adding new fields to an asset type doesn’t modify existing items. The new fields will appear empty for existing items until you edit them.

Field Type Selection Guide

When to Use Text

Best for

  • Short descriptive content
  • Identifiers and codes
  • Notes and comments
  • Names and labels

Avoid for

  • Data needing validation
  • Limited options (use dropdown)
  • Numeric calculations

Number vs Price

Use Number for

  • Whole values (quantity, year)
  • Non-monetary measurements
  • Integer ranges

Use Price for

  • Monetary values
  • Decimal precision needed
  • Financial calculations

Dropdown vs Boolean

Use Dropdown for

  • 3+ predefined options
  • Mutually exclusive states
  • Standardized categories

Use Boolean for

  • Exactly two states
  • Yes/No questions
  • On/Off settings

When to Use URL

Best for

  • External references
  • Documentation links
  • Product pages
  • Media resources

Features

  • Auto-validation on save
  • Clickable in item views
  • Protocol enforcement

Advanced Field Patterns

Calculated Fieldsaggregate values across items
// Example: Calculate total value across all items
double totalValue = items
.map((item) =>
  double.tryParse(item.customFields['purchase_price'] ?? '0') ?? 0)
.reduce((a, b) => a + b);
Conditional Fieldsshow/hide based on other values
// Example: Show "Region" only if "Platform" is set
if (item.customFields['platform'] != null) {
// Display region field
}
Field Dependenciesauto-populate from related fields
// Example: Auto-populate "Estimated Value" based on "Condition"
String estimateValue(String condition, String basePrice) {
final base = double.tryParse(basePrice) ?? 0;
switch (condition) {
  case 'Mint':
    return (base * 1.5).toStringAsFixed(2);
  case 'Good':
    return base.toStringAsFixed(2);
  case 'Fair':
    return (base * 0.6).toStringAsFixed(2);
  default:
    return basePrice;
}
}

Best Practices

Field Design

  • Descriptive field names
  • Choose the most specific type
  • Provide helpful defaults
  • Add clear helper text
  • Keep required fields minimal

Data Consistency

  • Dropdowns for standardized values
  • Implement validation where needed
  • Format values consistently
  • Document field purposes
  • Review fields periodically

User Experience

  • Group related fields
  • Order fields logically
  • Appropriate keyboard types
  • Show examples in helper text
  • Make common fields accessible

Performance

  • Avoid excessive fields
  • Index searchable fields
  • Use appropriate data types
  • Cache field definitions
  • Optimize validation logic

Common Field Combinations

Purchase Information
[
{ "name": "Purchase Date",
  "type": "date" },
{ "name": "Purchase Price",
  "type": "price" },
{ "name": "Retailer",
  "type": "text" },
{ "name": "Receipt",
  "type": "url" }
]
Condition Tracking
[
{ "name": "Overall Condition",
  "type": "dropdown",
  "options": ["Mint","Near Mint",
    "Good","Fair","Poor"] },
{ "name": "Complete in Box",
  "type": "boolean" },
{ "name": "Includes Manual",
  "type": "boolean" },
{ "name": "Condition Notes",
  "type": "text" }
]
Technical Specs
[
{ "name": "Model Number",
  "type": "text" },
{ "name": "Serial Number",
  "type": "text" },
{ "name": "Manufacturer",
  "type": "text" },
{ "name": "Year Manufactured",
  "type": "number" },
{ "name": "Product Page",
  "type": "url" }
]

Troubleshooting

Validation Not Working
  • 1. Check that the field type is correct
  • 2. Verify validation rules in field definition
  • 3. Ensure the app is updated to the latest version
  • 4. Test with explicit invalid values
  • 5. Review console logs for validation errors
Field Not Appearing
  • 1. Verify field is added to the asset type definition
  • 2. Check that the asset type is assigned to the item
  • 3. Refresh the item detail view
  • 4. Ensure the field isn’t hidden by conditional logic
  • 5. Verify you have permission to view the field
Formatting Issues
  • 1. Confirm the field type matches the data
  • 2. Check regional settings (decimal separators)
  • 3. Verify the formatting function is being called
  • 4. Test with standard format inputs first
  • 5. Clear cached field definitions