Preset Custom Fields allow developers to programmatically define, deploy, and manage custom fields for Filament resources using migrations.
This approach ensures consistency, version control, and easy deployment across different environments.
To create a new custom fields migration, use the dedicated Artisan command:
php artisan make:custom-fields-migration create_general_fields_for_order
This command generates a new migration file in your database/custom-fields/ directory with a timestamp prefix and the name you specified.
The system uses string-based field type identifiers. Here are the available field types:
'text' - Single line text input'textarea' - Multi-line text area'rich-editor' - Rich text editor'markdown-editor' - Markdown editor'email' - Email input with validation'phone' - Phone number input'number' - Numeric input'currency' - Currency formatted input'date' - Date picker'date-time' - Date and time picker'checkbox' - Single checkbox'toggle' - Toggle switch'select' - Dropdown selection'radio' - Radio buttons'multi-select' - Multiple selection dropdown'checkbox-list' - Checkbox list'toggle-buttons' - Toggle button group'tags-input' - Tag input field'color-picker' - Color selection'link' - URL input'file-upload' - File upload with validation'record' - Polymorphic model lookupIn your migration file, use the new() method with CustomFieldData objects to create new custom fields:
<?php
use App\Models\Shop\Order;
use Relaticle\CustomFields\Data\CustomFieldData;
use Relaticle\CustomFields\Data\CustomFieldSectionData;
use Relaticle\CustomFields\Data\CustomFieldSettingsData;
use Relaticle\CustomFields\Enums\CustomFieldSectionType;
use Relaticle\CustomFields\Enums\CustomFieldWidth;
use Relaticle\CustomFields\Filament\Integration\Migrations\CustomFieldsMigration;
return new class extends CustomFieldsMigration
{
public function up(): void
{
$this->migrator->new(
model: Order::class,
fieldData: new CustomFieldData(
name: 'Additional Information',
code: 'additional_information',
type: 'text',
section: new CustomFieldSectionData(
name: 'General',
code: 'general',
type: CustomFieldSectionType::SECTION,
),
systemDefined: true,
width: CustomFieldWidth::_100,
settings: new CustomFieldSettingsData(
list_toggleable_hidden: false
)
)
)->create();
}
};
For choice-based field types, add options using the options() method:
$this->migrator->new(
model: Product::class,
fieldData: new CustomFieldData(
name: 'Product Status',
code: 'product_status',
type: 'select',
section: new CustomFieldSectionData(
name: 'Status',
code: 'status',
type: CustomFieldSectionType::SECTION,
),
systemDefined: true,
)
)
->options([
'draft' => 'Draft',
'active' => 'Active',
'discontinued' => 'Discontinued'
])
->create();
For fields that reference other models, use the record field type with the lookupType() method:
$this->migrator->new(
model: Order::class,
fieldData: new CustomFieldData(
name: 'Sales Representative',
code: 'sales_rep',
type: 'record',
section: new CustomFieldSectionData(
name: 'Sales',
code: 'sales',
type: CustomFieldSectionType::SECTION,
),
systemDefined: true,
)
)
->lookupType(User::class)
->create();
Control field layout using CustomFieldWidth enum:
use Relaticle\CustomFields\Enums\CustomFieldWidth;
// Available widths:
CustomFieldWidth::_25 // 25% width
CustomFieldWidth::_33 // 33% width
CustomFieldWidth::_50 // 50% width
CustomFieldWidth::_66 // 66% width
CustomFieldWidth::_75 // 75% width
CustomFieldWidth::_100 // 100% width (full width)
To update existing fields, create a new migration and use the update() method:
use App\Models\Shop\Order;
use Relaticle\CustomFields\Filament\Integration\Migrations\CustomFieldsMigration;
return new class extends CustomFieldsMigration
{
public function up(): void
{
$this->migrator
->find(Order::class, 'additional_information')
->update([
'name' => 'Updated Field Name',
'settings' => new CustomFieldSettingsData(
list_toggleable_hidden: true
)
]);
}
};
To remove preset fields, create a migration that uses the delete() method:
<?php
use App\Models\Shop\Order;
use Relaticle\CustomFields\Filament\Integration\Migrations\CustomFieldsMigration;
return new class extends CustomFieldsMigration
{
public function up(): void
{
$this->migrator->find(Order::class, 'additional_information')->delete();
}
};
Control field visibility without deletion:
<?php
use App\Models\Shop\Order;
use Relaticle\CustomFields\Filament\Integration\Migrations\CustomFieldsMigration;
return new class extends CustomFieldsMigration
{
public function up(): void
{
// Deactivate a field
$this->migrator->find(Order::class, 'field_code')->deactivate();
// Activate a field
$this->migrator->find(Order::class, 'field_code')->activate();
}
};
Here's a comprehensive example creating multiple fields for a Customer model:
<?php
use App\Models\Shop\Customer;
use App\Models\User;
use Relaticle\CustomFields\Data\CustomFieldData;
use Relaticle\CustomFields\Data\CustomFieldSectionData;
use Relaticle\CustomFields\Data\CustomFieldSettingsData;
use Relaticle\CustomFields\Enums\CustomFieldSectionType;
use Relaticle\CustomFields\Enums\CustomFieldWidth;
use Relaticle\CustomFields\Filament\Integration\Migrations\CustomFieldsMigration;
return new class extends CustomFieldsMigration
{
public function up(): void
{
// Link field
$this->migrator->new(
model: Customer::class,
fieldData: new CustomFieldData(
name: 'Company Website',
code: 'company_website',
type: 'link',
section: new CustomFieldSectionData(
name: 'Company Info',
code: 'company_info',
type: CustomFieldSectionType::SECTION,
),
systemDefined: true,
width: CustomFieldWidth::_50,
)
)->create();
// Choice field with options
$this->migrator->new(
model: Customer::class,
fieldData: new CustomFieldData(
name: 'Customer Type',
code: 'customer_type',
type: 'select',
section: new CustomFieldSectionData(
name: 'Company Info',
code: 'company_info',
type: CustomFieldSectionType::SECTION,
),
systemDefined: true,
width: CustomFieldWidth::_50,
)
)
->options([
'individual' => 'Individual',
'small_business' => 'Small Business',
'enterprise' => 'Enterprise'
])
->create();
// Boolean field
$this->migrator->new(
model: Customer::class,
fieldData: new CustomFieldData(
name: 'VIP Customer',
code: 'is_vip',
type: 'toggle',
section: new CustomFieldSectionData(
name: 'Status',
code: 'status',
type: CustomFieldSectionType::SECTION,
),
systemDefined: true,
width: CustomFieldWidth::_25,
settings: new CustomFieldSettingsData(
list_toggleable_hidden: false
)
)
)->create();
}
};
Custom fields migrations are run using Laravel's standard migration system:
# Run all custom fields migrations
php artisan migrate --path=database/custom-fields
# Run a specific migration file
php artisan migrate --path=database/custom-fields/2025_08_15_022226_create_general_fields_for_order.php
'Customer Type' instead of 'Type''customer_type' instead of 'CustomerType'systemDefined: true for preset fields