Installation:
composer require kris/laravel-form-builder
Publish the config (optional, for customization):
php artisan vendor:publish --provider="Kris\LaravelFormBuilder\FormBuilderServiceProvider"
Basic Usage:
Register the FormBuilderFacade in config/app.php under aliases:
'Form' => Kris\LaravelFormBuilder\FormBuilderFacade::class,
First Form: In a controller or blade template:
use Form;
$form = Form::open()->action('/submit')->method('POST');
$form->text('name', 'John Doe')->required();
$form->submit('Submit');
echo $form->close();
Blade Integration:
Use @form directive in Blade templates:
@form(['action' => '/submit', 'method' => 'POST'])
@text('name', null, ['label' => 'Your Name'])
@submit('Save')
@endform
Reusable Form Components: Create a form builder service to encapsulate logic:
class UserFormBuilder {
public static function buildCreateForm() {
$form = Form::open()->action('/users')->method('POST');
$form->text('name')->required();
$form->email('email')->required();
$form->password('password')->required();
$form->submit('Create User');
return $form;
}
}
Conditional Fields: Use closures for dynamic fields:
$form->text('field_name')->if(function() {
return Auth::user()->hasPermission('edit');
});
Form Request Validation:
Sync fields with Laravel's FormRequest:
// In UserCreateRequest.php
public function rules() {
return [
'name' => 'required|string|max:255',
'email' => 'required|email',
];
}
// In Controller
$form = Form::model($request)->open()->action('/users');
Model Binding: Bind forms to Eloquent models:
$form = Form::model($user)->open()->action('/users/' . $user->id);
$form->text('name', $user->name)->required();
Collective Integration:
Combine with laravelcollective/html for enhanced HTML generation:
use Collective\Html\FormFacade as HtmlForm;
$form = Form::open();
$form->text('name', null, ['class' => 'form-control']);
echo $form->close();
Nested Forms: For nested resources (e.g., user addresses):
$form->section('address', function($form) {
$form->text('street')->required();
$form->text('city')->required();
});
Field Arrays: For repeated fields (e.g., tags):
$form->text('tags[]')->required();
Custom Field Types: Extend the builder for domain-specific fields:
Form::extend('phone', function($form) {
return $form->text('phone')->addAttribute('class', 'phone-input');
});
CSRF Token:
Always include @csrf in Blade forms or use Form::open()->withCsrf() to avoid CSRF errors.
Model Binding:
Forgetting to pass the model to Form::model() will reset all fields to null.
Bootstrap Version Conflicts:
Ensure consistent Bootstrap JS/CSS versions. For Bootstrap 4, use the laravel-form-builder-bs4 package.
Field Naming:
Dynamic field names (e.g., tags[]) require proper handling in controllers to avoid array indexing issues.
Validation Errors:
Use Form::model($request)->open() to automatically populate errors:
@error('name')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
Dump Form Data:
Use Form::model($request)->open()->getData() to inspect submitted data.
Check Field Attributes: Debug attributes with:
$form->text('name')->addAttribute('data-test', 'value')->getAttributes();
Form Events:
Listen for form events (e.g., form.created) via:
Form::macro('onCreate', function($callback) {
Form::extend('custom', function($form) use ($callback) {
$callback($form);
return $form->text('custom_field');
});
});
Default Options:
Override defaults in config/formbuilder.php:
'default_options' => [
'method' => 'POST',
'class' => 'form-horizontal',
],
Custom Field Types:
Register new field types in AppServiceProvider@boot():
Form::extend('custom_field', function($form) {
return $form->text('custom_field')->addAttribute('data-custom', 'true');
});
Asset Paths: Customize asset paths (e.g., for Bootstrap) in the config:
'assets' => [
'bootstrap_css' => 'vendor/bootstrap/css/bootstrap.min.css',
],
Cache Forms: For static forms, cache the builder output:
$cachedForm = Cache::remember('form_key', 3600, function() {
return Form::open()->text('name')->submit('Submit')->close();
});
Lazy Loading: Defer field rendering until needed:
$form = Form::open();
if ($shouldRenderField) {
$form->text('dynamic_field');
}
Avoid Over-Extending: Limit custom field types to reduce memory overhead in large forms.
Custom Renderers: Override the default renderer for full control:
Form::setRenderer(new CustomRenderer());
Field Transformers: Transform field data before rendering:
Form::extend('currency', function($form) {
return $form->text('amount')->addAttribute('data-format', 'currency');
});
Event Hooks: Attach hooks to form lifecycle events:
Form::macro('onRender', function($callback) {
Form::extend('hookable', function($form) use ($callback) {
$callback($form);
return $form->text('field');
});
});
How can I help you explore Laravel packages today?