Installation
composer require tapp/filament-form-builder
Publish the config and migrations:
php artisan vendor:publish --provider="TappNetwork\FilamentFormBuilder\FilamentFormBuilderServiceProvider"
php artisan migrate
Register the Plugin
Add to app/Providers/Filament/AdminPanelProvider.php:
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
\TappNetwork\FilamentFormBuilder\FilamentFormBuilderPlugin::make(),
]);
}
First Form Creation
TextInput, Select, etc.)required|email).Frontend Usage
Use the form Blade directive in your frontend view:
@form('contact-us')
@include('forms.contact-us')
@endform
Or via JavaScript:
document.addEventListener('DOMContentLoaded', () => {
const form = new FilamentFormBuilder.Form('contact-us');
form.render('#form-container');
});
Dynamic Form Building
RichEditor, FileUpload) or extend with custom components.visibleOn/requiredIf attributes in the admin panel to create dynamic forms.Data Handling
FormResponse model (extendable via php artisan make:filament-form-builder-model).Form model’s saveResponse() method.Frontend Integration
@form('slug') for server-rendered forms.FilamentFormBuilder.loadForm('contact-us', '#container').then(form => {
form.on('submit', (data) => {
console.log('Submitted:', data);
});
});
Exporting Data
// Customize export columns in the Form model:
protected static function getExportableColumns(): array
{
return [
'name',
'email',
'created_at',
];
}
Multi-Step Forms
steps configuration in the admin panel to split forms into tabs/sections.form.on('stepChange', (stepName) => {
console.log('Current step:', stepName);
});
FilamentFormBuilderField to create reusable components:
namespace App\Filament\Forms\Fields;
use TappNetwork\FilamentFormBuilder\Fields\FilamentFormBuilderField;
class CustomField extends FilamentFormBuilderField
{
protected static ?string $view = 'filament-form-builder::fields.custom';
}
Form model’s afterSave event:
public static function booted()
{
static::afterSave(function ($model) {
event(new FormSubmitted($model));
});
}
// In Form model:
public static function getTranslatableAttributes(): array
{
return ['title', 'description'];
}
Field Serialization
getState() and setState() in your custom field:
public function getState(): array
{
return ['value' => $this->value];
}
public function setState(array $state): void
{
$this->value = $state['value'];
}
Validation Overrides
validation_rules in the admin panel or override the rules() method in your Form model:
public function rules(): array
{
return [
'email' => 'required|email|unique:form_responses,email',
];
}
CSRF Token Mismatch
VerifyCsrfToken middleware:
protected $except = [
'filament-form-builder/*',
];
Database Bloat
// In FormResponse model:
use Illuminate\Database\Eloquent\SoftDeletes;
class FormResponse extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
}
JavaScript Conflicts
<script src="/vendor/filament-form-builder/js/form-builder.js" defer></script>
Log Form Data
Add a FormSubmitted listener to inspect payloads:
Form::afterSave(function ($model) {
\Log::info('Form submitted:', $model->data);
});
Check Field States Dump field states during form rendering:
// In a custom field:
public function mount(): void
{
\Log::debug('Field state:', $this->getState());
}
Validate Admin Panel Config
Ensure the config/filament-form-builder.php settings match your environment:
'default_form_model' => \App\Models\Form::class,
'default_response_model' => \App\Models\FormResponse::class,
Clear Cached Views If forms render incorrectly after updates:
php artisan view:clear
php artisan cache:clear
Custom Storage
Override the saveResponse() method in your Form model to store data in a queue or external service:
public function saveResponse(array $data): void
{
FormResponse::create([
'form_id' => $this->id,
'data' => $data,
]);
// Send to external API
Http::post('https://api.example.com/webhooks', $data);
}
Field Presets
Create reusable field configurations via FormField models:
// app/Models/FormField.php
public function getDefaultConfig(): array
{
return [
'label' => 'Full Name',
'field' => 'text_input',
'required' => true,
];
}
Frontend Theming
Override Blade views in resources/views/vendor/filament-form-builder/ to customize styling:
<!-- resources/views/vendor/filament-form-builder/forms/render.blade.php -->
<div class="my-custom-form">
@foreach($fields as $field)
{!! $field->render() !!}
@endforeach
</div>
API Endpoints Expose form submissions via a custom API route:
Route::post('/api/forms/{form}/submit', [FormController::class, 'submit'])->middleware('auth:sanctum');
// In FormController:
public function submit(Request $request, Form $form)
{
return $form->submit($request->all());
}
How can I help you explore Laravel packages today?