Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Custom Fields Laravel Package

relaticle/custom-fields

Laravel/Filament plugin to add dynamic custom fields to any Eloquent model without migrations. Includes 20+ field types, conditional visibility, tenant isolation, admin UI integration (forms/tables/infolists), CSV import/export, optional encryption, and extensible field types.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require relaticle/custom-fields:^3.1.7
   php artisan vendor:publish --provider="Relaticle\CustomFields\CustomFieldsServiceProvider"

Publish the config and migrations (if needed for encryption).

  1. Enable for a Model: Add the HasCustomFields trait to your Eloquent model:

    use Relaticle\CustomFields\Traits\HasCustomFields;
    
    class Product extends Model
    {
        use HasCustomFields;
    }
    
  2. First Field Definition: Define fields in a customFields() method (auto-discovered via naming conventions):

    public function customFields(): array
    {
        return [
            'description' => [
                'type' => 'textarea',
                'label' => 'Product Description',
                'required' => true,
            ],
            'spec_sheet' => [
                'type' => 'file',
                'label' => 'Specification Sheet',
                'upload_path' => 'products/specs',
            ],
        ];
    }
    
  3. Filament Integration: Use the CustomFieldsWidget in Filament forms/tables:

    use Relaticle\CustomFields\Widgets\CustomFieldsWidget;
    
    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                CustomFieldsWidget::make('product')
            ]);
    }
    

First Use Case: Adding a Dynamic Field

  1. Define a new field (e.g., release_date for a Product):
    public function customFields(): array
    {
        return [
            'release_date' => [
                'type' => 'date',
                'label' => 'Release Date',
                'default' => now()->format('Y-m-d'),
            ],
        ];
    }
    
  2. Migrate existing data (if needed):
    php artisan custom-fields:migrate --model=Product --fields=release_date
    
  3. Use in Filament: The field appears automatically in forms/tables via CustomFieldsWidget.

Implementation Patterns

Core Workflows

  1. Field Definition Patterns:

    • Grouped Fields: Use nested arrays for logical grouping:
      'shipping_info' => [
          'type' => 'group',
          'fields' => [
              'weight' => ['type' => 'number', 'label' => 'Weight (kg)'],
              'dimensions' => ['type' => 'text', 'label' => 'Dimensions (LxWxH)'],
          ],
      ],
      
    • Repeater Fields: For dynamic lists (e.g., product features):
      'features' => [
          'type' => 'repeater',
          'fields' => [
              'name' => ['type' => 'text'],
              'value' => ['type' => 'text'],
          ],
      ],
      
  2. Conditional Logic:

    • Hide/show fields based on other values. Note: Fixed bug in v3.1.7 for repeater fields in visibility conditions:
      'warranty' => [
          'type' => 'select',
          'label' => 'Warranty',
          'options' => ['1-year', '2-year', 'lifetime'],
          'visible' => ['field' => 'is_premium', 'operator' => '==', 'value' => true],
      ],
      
    • For repeater fields, ensure field_code is correctly referenced:
      'features' => [
          'type' => 'repeater',
          'visible' => ['field' => 'has_features', 'operator' => '==', 'value' => true],
      ],
      
  3. Multi-Tenancy:

    • Isolate fields per tenant using the tenant_id column (auto-handled):
      // In config/custom-fields.php
      'tenant_column' => 'tenant_id',
      
  4. Validation:

    • Leverage Laravel’s validation rules:
      'price' => [
          'type' => 'number',
          'rules' => 'required|min:0.01',
      ],
      

Integration Tips

  1. Filament Tables:

    • Customize column display:
      use Relaticle\CustomFields\Columns\CustomFieldsColumn;
      
      public static function table(Table $table): Table
      {
          return $table
              ->columns([
                  CustomFieldsColumn::make('product')
                      ->fields(['description', 'release_date']),
              ]);
      }
      
  2. API Responses:

    • Serialize custom fields in API resources:
      public function toArray($request)
      {
          return [
              'id' => $this->id,
              'custom_fields' => $this->customFields->toArray(),
          ];
      }
      
  3. Events:

    • Listen for field updates:
      use Relaticle\CustomFields\Events\FieldUpdated;
      
      FieldUpdated::listen(function (FieldUpdated $event) {
          // Log or trigger side effects
      });
      
  4. Encryption:

    • Protect sensitive fields (e.g., api_keys):
      'api_key' => [
          'type' => 'text',
          'encrypted' => true,
      ],
      
    • Configure encryption in config/custom-fields.php:
      'encryption' => [
          'enabled' => true,
          'key' => env('CUSTOM_FIELDS_ENCRYPTION_KEY'),
      ],
      

Gotchas and Tips

Common Pitfalls

  1. Field Name Collisions:

    • Avoid duplicate field names across models or tenants. Use unique prefixes (e.g., product_sku vs. user_sku).
  2. Migration Issues:

    • If adding fields to an existing table, run:
      php artisan custom-fields:migrate --model=Product --fields=*
      
    • Warning: This may fail if the table lacks the custom_fields JSON column. Add it manually if needed:
      Schema::table('products', function (Blueprint $table) {
          $table->json('custom_fields')->nullable();
      });
      
  3. Conditional Logic Bugs:

    • Test visibility rules thoroughly. Debug with:
      $field->isVisible($model); // Manually check visibility
      
    • Tip: Use visible for static conditions, visible_if for dynamic checks:
      'visible_if' => ['field' => 'is_active', 'operator' => '!=', 'value' => false],
      
    • Note: Fixed issue in v3.1.7 where repeater fields could incorrectly clear their own field_code in visibility conditions.
  4. Performance:

    • Avoid overusing repeater or group fields in large datasets. Consider denormalizing for Filament tables.
    • Optimization: Cache field definitions:
      // In a service provider
      Cache::rememberForever('custom-fields:Product', fn() => Product::first()->customFields());
      

Debugging

  1. Field Not Showing?:

    • Check the model’s customFields() method is autoloaded (use php artisan optimize:clear if stale).
    • Verify the field type exists (list types in config/custom-fields.php under field_types).
    • Note: Laravel 13 compatibility improvements in v3.1.7 for type safety.
  2. Encryption Errors:

    • Ensure CUSTOM_FIELDS_ENCRYPTION_KEY is set in .env and matches the config.
    • Decrypt manually for testing:
      $decrypted = decrypt($model->custom_fields->api_key);
      
  3. Filament Widget Issues:

    • Clear Filament’s cache:
      php artisan filament:cache-reset
      
    • Check for JavaScript errors in the browser console (e.g., missing field components).

Extension Points

  1. Custom Field Types:

    • Create a new field type by extending Relaticle\CustomFields\FieldTypes\BaseField:
      namespace App\CustomFields;
      
      use Relaticle\CustomFields\FieldTypes\BaseField;
      
      class CustomSlider extends BaseField
      {
          public static function getType(): string { return 'custom_slider'; }
      
          public function getWidget(): string { return 'custom-slider'; }
      }
      
    • Register in config/custom-fields.php:
      'field_types' => [
          'custom_slider' => \App\CustomFields\CustomSlider::class,
      ],
      
  2. Field Components:

    • Override Filament widgets by publishing assets:
      php artisan vendor:publish --tag=custom-fields-assets
      
    • Extend the default Vue components in resources/js/custom-fields.
  3. Database Backend:

    • Switch from JSON to a relational model by implementing `Relaticle\CustomFields\Contracts
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver