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.
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
General text input for names, descriptions, and labels
TextInputType.text
Number
Numeric values without decimals
TextInputType.number
Price
Monetary values with decimal precision
TextInputType.numberWithOptions(decimal: true)
Date
Date picker for temporal data
TextInputType.datetime
Dropdown
Predefined list of selectable options
N/A (picker)
Boolean
Yes / No or True / False values
N/A (toggle)
URL
Web addresses with format validation
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:
case CustomFieldType.url:
final urlPattern = RegExp(
r'^(https?|ftp)://[^s/$.?#].[^s]*$');
if (!urlPattern.hasMatch(value)) {
return 'Introduce una URL válida';
}
break;Rules
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
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;
}
}Creating Custom Field Definitions
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"
}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
Add Dropdown Options (if applicable)
{
"name": "Condition",
"type": "dropdown",
"options": [
"Mint",
"Near Mint",
"Excellent",
"Good",
"Fair",
"Poor"
]
}Test Validation
Create a test item to verify that everything works:
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
// 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);
// Example: Show "Region" only if "Platform" is set
if (item.customFields['platform'] != null) {
// Display region field
}// 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
[
{ "name": "Purchase Date",
"type": "date" },
{ "name": "Purchase Price",
"type": "price" },
{ "name": "Retailer",
"type": "text" },
{ "name": "Receipt",
"type": "url" }
][
{ "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" }
][
{ "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
Next Steps