michalkortas/laravelforms
Blade form components for Laravel 7–8 that generate Bootstrap-styled inputs fast, with built-in validation error support. Includes text, select, textarea, checkbox, radio, file, date/time, color, and more, with easy model binding for values.
Installation:
Run composer require michalkortas/laravelforms and register the service provider in config/app.php if not auto-registered.
First Component:
Use the <x-form-text> component in a Blade view:
<x-form-text label="Username" name="username" value="{{ old('username') }}" />
This renders a Bootstrap-styled text input with validation error support.
First Use Case:
Replace a manual <select> with <x-form-select> for a model-based dropdown:
<x-form-select :model="$user" name="role_id" label="User Role" :options="$roles" />
Automatically binds to the model and handles validation errors.
Key Files:
/resources/views/vendor/laravelforms/ (component templates)/config/laravelforms.php (customization options)Model Binding:
Use :model="$model" to auto-populate fields from Eloquent models:
<x-form-textarea :model="$post" name="content" label="Post Content" />
Supports nested relations via model-key (e.g., model-key="author.name").
Validation Integration: Laravel’s validation errors are automatically applied to inputs. No extra code needed:
<x-form-email name="email" label="Email" />
Shows errors if email fails validation.
Dynamic Options:
Pass collections or arrays to options for dynamic selects/checkboxes:
<x-form-checkbox :model="$user" :options="$permissions" model-key="permissions.id" label="Permissions" />
Custom Placeholders:
Override defaults via placeholder attribute:
<x-form-text name="search" placeholder="Search users..." />
Conditional Attributes:
Use required, disabled, or readonly directly:
<x-form-select name="status" :options="$statuses" required />
Rich Select (v1.9.0+): Enable searchable selects with API integration:
<x-form-rich-select
name="department"
api-url="{{ route('api.departments') }}"
label="Department"
/>
Form Requests:
Pair with Laravel’s FormRequest for centralized validation:
public function rules() {
return ['username' => 'required|string|max:255'];
}
Livewire/Alpine:
Sync with frontend frameworks using wire:model or Alpine stores:
<x-form-select wire:model="roleId" :options="$roles" />
Custom Styling:
Extend Bootstrap classes via class attribute:
<x-form-text name="title" class="form-control-lg" />
Model Key Mismatch:
If model-key doesn’t match the model’s structure, values won’t bind. Use data_get()-compatible paths (e.g., user.role.id).
Validation Error Overrides:
Manually setting value overrides validation errors. Use {{ old('field') }} or :model instead.
Rich Select API:
Ensure the api-url returns JSON with data key:
{ "data": [{ "id": 1, "text": "Option 1" }] }
Hidden Inputs:
<x-form-hidden> may render unwanted spacing. Use class="d-none" to hide:
<x-form-hidden name="token" value="{{ csrf_token() }}" class="d-none" />
Check Component Output:
Inspect rendered HTML to verify attributes (e.g., selected, checked).
Validation Errors:
Ensure error messages are published in resources/lang/{locale}/validation.php.
Rich Select Console: Open browser dev tools to check API calls and errors (e.g., CORS, 404s).
Custom Components:
Extend the package by creating new Blade components in /app/View/Components/Form.
Template Overrides: Publish views and modify them:
php artisan vendor:publish --tag=laravelforms.views
Configuration:
Override defaults in config/laravelforms.php (e.g., error_class, wrapper_class).
JavaScript Events:
Listen for Rich Select events (e.g., richSelect:selected) via:
document.addEventListener('richSelect:selected', (e) => {
console.log('Selected:', e.detail.value);
});
Partial Updates:
Use model-key to update nested model attributes without full reloads.
Accessibility:
Add aria-* attributes to labels for screen readers:
<x-form-text name="name" label="Full Name" aria-required="true" />
Testing:
Test components with Laravel’s assertSeeInOrder:
$this->get('/form')->assertSeeInOrder([
'<input type="text" name="username"',
'<label>Username</label>',
]);
Performance:
For large selects, use lazy loading with Rich Select’s load-on-focus option.
How can I help you explore Laravel packages today?