> ## Documentation Index
> Fetch the complete documentation index at: https://lopiv2-invenicum-25.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Fields

> Define custom field types and validation for your asset types

## Overview

Custom fields allow you to define specific attributes for your inventory items beyond the standard fields. Each field can have its own data type, validation rules, and display format, enabling you to track exactly the information you need.

## Field Types

Invenicum supports seven custom field types, each optimized for different data:

> **Text**
>
> General text input for names, descriptions, and labels
>
> **Use cases**: Serial numbers, notes, conditions

> **Number**
>
> Numeric values without decimals
>
> **Use cases**: Quantity, year, edition number

> **Price**
>
> Monetary values with decimal precision
>
> **Use cases**: Purchase price, current value, MSRP

> **Date**
>
> Date picker for temporal data
>
> **Use cases**: Purchase date, warranty expiration, release date

> **Dropdown**
>
> Predefined list of options
>
> **Use cases**: Condition, status, category, platform

> **Boolean**
>
> Yes/No or True/False values
>
> **Use cases**: Complete-in-box, working, favorite

> **URL**
>
> Web addresses with validation
>
> **Use cases**: Product page, manual PDF, related links

## Field Type Implementation

Custom field types are defined using an enum:

```dart theme={null}
// From custom_field_definition.dart:5
enum CustomFieldType {
  text,
  number,
  date,
  dropdown,
  boolean,
  url,
  price,
}
```

### Type Properties

Each field type has associated properties:

> **Technical Name (dbName)**
>
> ```dart theme={null}
> // From custom_field_definition.dart:18
> String get dbName {
>   return name.toLowerCase();
> }
> ```
>
> Used for API communication and database storage. Always lowercase.

> **Display Name**
>
> ```dart theme={null}
> // From custom_field_definition.dart:25
> String get displayName {
>   switch (this) {
>     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';
>   }
> }
> ```
>
> User-friendly name shown in the interface.

> **Keyboard Type**
>
> ```dart theme={null}
> // From custom_field_definition.dart:66
> TextInputType get keyboardType {
>   switch (this) {
>     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 data entry.

## Field Validation

Custom fields include built-in validation:

### URL Validation

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

Ensures URLs:

* Start with http\://, https\://, or ftp\://
* Have a valid domain structure
* Don't contain invalid characters

### Price Validation

```dart theme={null}
// From custom_field_definition.dart:94
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;
```

Validates monetary values:

* Must be numeric
* Allows comma or period as decimal separator
* Maximum two decimal places
* No negative values

### Custom Validation

```dart theme={null}
// From custom_field_definition.dart:82
String? validateValue(String? value) {
  if (value == null || value.isEmpty) return null;
  
  // Type-specific validation
  switch (this) {
    // ... validation logic
  }
  return null; // Validation passed
}
```

## Field Formatting

Some field types automatically format values:

### Price Formatting

```dart theme={null}
// From custom_field_definition.dart:108
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;
  }
}
```

Ensures consistent decimal formatting:

* Input: "123" → Output: "123.00"
* Input: "45.6" → Output: "45.60"
* Input: "99,99" → Output: "99.99"

## Creating Custom Field Definitions

When setting up an asset type or template:

**1. Add Field Definition**

Define a new custom field with:

```json theme={null}
{
  "name": "Purchase Price",
  "type": "price",
  "required": false,
  "defaultValue": "0.00"
}
```

**2. Configure Properties**

Set field properties:

* **Name**: Display label for the field
* **Type**: One of the seven field types
* **Required**: Whether the field must be filled
* **Default Value**: Initial value for new items
* **Helper Text**: Guidance for users

**3. Add Dropdown Options (if applicable)**

For dropdown fields, define the available options:

```json theme={null}
{
  "name": "Condition",
  "type": "dropdown",
  "options": [
    "Mint",
    "Near Mint",
    "Excellent",
    "Good",
    "Fair",
    "Poor"
  ]
}
```

**4. Test Validation**

Create a test item to verify:

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

## Using Custom Fields in Asset Types

Custom fields are associated with asset types:

1. **Define the Asset Type** - Create or edit an asset type
2. **Add Custom Fields** - Specify which fields apply to this type
3. **Create Items** - New items will include these custom fields
4. **Modify Later** - You can add or remove fields without affecting existing data

> [!NOTE]
>
> 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 that needs validation (use specific types)
> * Limited options (use dropdown)
> * Numeric calculations (use number or price)

> **When to Use Number vs Price**
>
> **Use Number for:**
>
> * Whole values (quantity, year, count)
> * Non-monetary measurements
> * Integer ranges
>
> **Use Price for:**
>
> * Monetary values
> * Values requiring decimal precision
> * Financial calculations
> * Currency amounts

> **When to Use Dropdown vs Boolean**
>
> **Use Dropdown for:**
>
> * 3+ predefined options
> * Mutually exclusive states
> * Standardized categories
>
> **Use Boolean for:**
>
> * Exactly two states
> * Yes/No questions
> * True/False conditions
> * On/Off settings

> **When to Use URL**
>
> **Best for:**
>
> * External references
> * Documentation links
> * Product pages
> * Media resources
>
> **Features:**
>
> * Automatic validation
> * Clickable in item views
> * Protocol enforcement (http/https/ftp)

## Advanced Field Patterns

### Calculated Fields

While custom fields store static data, you can create calculated values:

```dart theme={null}
// Example: Calculate total value
double totalValue = items
  .map((item) => double.tryParse(item.customFields['purchase_price'] ?? '0') ?? 0)
  .reduce((a, b) => a + b);
```

### Conditional Fields

Show fields based on other field values:

```dart theme={null}
// Example: Show "Region" only if "Platform" is set
if (item.customFields['platform'] != null) {
  // Display region field
}
```

### Field Dependencies

Create relationships between fields:

```dart theme={null}
// 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**
>
> * Use descriptive field names
> * Choose the most specific type
> * Provide helpful defaults
> * Add clear helper text
> * Keep required fields minimal

> **Data Consistency**
>
> * Use 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
> * Use appropriate keyboard types
> * Show examples in helper text
> * Make common fields easily accessible

> **Performance**
>
> * Don't create excessive fields
> * Index searchable fields
> * Use appropriate data types
> * Cache field definitions
> * Optimize validation logic

## Common Field Combinations

> **Purchase Information**
>
> ```json theme={null}
> [
>   {
>     "name": "Purchase Date",
>     "type": "date"
>   },
>   {
>     "name": "Purchase Price",
>     "type": "price"
>   },
>   {
>     "name": "Retailer",
>     "type": "text"
>   },
>   {
>     "name": "Receipt",
>     "type": "url"
>   }
> ]
> ```

> **Condition Tracking**
>
> ```json theme={null}
> [
>   {
>     "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 Specifications**
>
> ```json theme={null}
> [
>   {
>     "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**
>
> If field validation isn't being enforced:
>
> 1. Check that the field type is correct
> 2. Verify validation rules in field definition
> 3. Ensure the app is updated to latest version
> 4. Test with explicit invalid values
> 5. Review console logs for validation errors

> **Field Not Appearing**
>
> If a custom field doesn't show up:
>
> 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**
>
> If values aren't formatting correctly:
>
> 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
> 5. Clear cached field definitions

## Next Steps

> **[Asset Types](https://lopiv2-invenicum-25.mintlify.site/collections/asset-types)**
>
> Configure asset types with custom fields

> **[Templates](https://lopiv2-invenicum-25.mintlify.site/advanced/templates.md)**
>
> Use templates with pre-defined custom fields

> **[Import Data](https://lopiv2-invenicum-25.mintlify.site/items/importing)**
>
> Import items with custom field values

> **[Reports](https://lopiv2-invenicum-25.mintlify.site/analytics/reports)**
>
> Generate reports using custom field data


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.