/form-builder-fork

A basic form builder for filament that allows you to create forms for any of your models.

Primary LanguagePHP

Form Builder for Filament & Laravel

Form Builder is a Laravel package built on top of Filament v4, allowing you to visually build and manage dynamic forms from your admin panel.
It lets you attach custom forms to any Eloquent model in your application with minimal setup.


Features

  • Built entirely with Filament v4 components
  • Dynamic form rendering using form_content + form_response
  • All form fields are stored in a single JSON column
  • Visually design sections + fields with nested repeaters
  • Automatically bind values via custom_id
  • Smart versioning support (form_version)
  • Seamlessly plug into any Eloquent model using a trait
  • Custom Filament resource base for auto-form handling
  • Install via form-builder:install command

Installation

Requires Laravel 12+ and Filament 4+

Step 1: Install via Composer

composer require dayne-valourite/form-builder

Step 2: Run the installer

php artisan form-builder:install

This will:

  • Publish the config file to config/form-builder.php
  • Run the required database migrations

Register the plugin

In your PanelProvider:

use Valourite\FormBuilder\FormBuilderPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            FormBuilderPlugin::make(),
        ]);
}

Usage

1. Setup your Eloquent model

Use the HasFormBuilder trait:

use Valourite\FormBuilder\Concerns\HasFormBuilder;

class Client extends Model
{
    use HasFormBuilder;
}

This enables:

  • form_id
  • form_content
  • form_response
  • form_version

No need to add these to $fillable.

Note: Ensure your model has those columns

  • We can update the column names by implementing the following functions:
public static function getFormContentColumn(): string

public static function getFormIdColumn(): string

public static function getFormResponseColumn(): string

public static function getFormVersionColumn(): string

2. Create a resource using the base class

use Valourite\FormBuilder\Filament\Resources\FormBuilderResource;

class ClientResource extends FormBuilderResource
{
    protected static string $model = \App\Models\Client::class;

    /**
     * Optional: Define your base schema fields
     * If omitted, these will be auto-generated from `$fillable` and `$casts`
     */
    public static function customSchemaFields(): array
    {
        return [
            TextInput::make('name')->required(),
            TextInput::make('email')->email()->required(),
        ];
    }

    /**
     * Optional: Define your base infolist schema fields
     * If omitted. these will be auto-generated from `$fillable` and `$casts`
     */
    public static function customInfolistFields(): array
    {
        return [
            TextEntry::make('name'),
            TextEntry::make('email'),
        ];
    }
}

3. Use the base page class

use Valourite\FormBuilder\Filament\Pages\FormBuilderCreateRecord;

class CreateClient extends FormBuilderCreateRecord
{
    protected static string $resource = ClientResource::class;
}

This handles:

  • Dynamic rendering of the form schema
  • Saving the form response into form_response
  • Linking the correct form_id, version, and structure

And inside your Edit page class

use Valourite\FormBuilder\Filament\Pages\FormBuilderEditRecord;

class EditClient extends FormBuilderEditRecord
{
    protected static string $resource = ClientResource::class;
}

This handles:

  • Dynamic rendering of the form schema
  • Allowing updates to be made to the form values

How It Works

  • Selecting a form from the dropdown dynamically renders its fields
  • Values are bound using each field’s custom_id
  • Saved response values are stored as form_response[field_id] => value
  • form_content is stored alongside the record for replay/version safety

Configuration

In config/form-builder.php:

return [
    'models' => [
        App\Models\Client::class,
        App\Models\Project::class,
    ],

    'versioning' => [
        'mode' => 'increment', // or 'clone'
        'auto_increment' => true,
    ],
];

Testing & Contributing

Pull requests, issues, and improvements are welcome!

To test form saving logic:

$this->assertDatabaseHas('clients', [
    'form_response' => json_encode([...]),
]);

🚧 Roadmap

  • Attach forms to any model
  • Store form definitions in DB
  • Save submissions as JSON
  • Versioning support (increment/clone)
  • Better handling of form creation without page extending
  • More Fields
  • Multi-page/wizard forms

📄 License

MIT © Dayne Valourite