derafu/form
derafu/form is a lightweight PHP/Laravel package for building and handling HTML forms more easily. It provides helpers to define fields, render form elements, and manage form input/validation in a cleaner, reusable way across your application.
Installation
composer require derafu/form
Publish the config (if needed):
php artisan vendor:publish --provider="Derafu\Form\FormServiceProvider"
Define a Form
Create a form class (e.g., app/Forms/ContactForm.php):
use Derafu\Form\Form;
class ContactForm extends Form
{
public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email',
'message' => 'required|string',
];
}
public function fields()
{
return [
'name' => 'text',
'email' => 'email',
'message' => 'textarea',
];
}
}
First Use Case: Rendering In a controller or blade template:
$form = new ContactForm();
return view('contact', ['form' => $form]);
Blade template (resources/views/contact.blade.php):
{!! $form->render() !!}
Group Fields Logically
Use nested arrays in fields() for sections:
public function fields()
{
return [
'user' => [
'name' => 'text',
'email' => 'email',
],
'preferences' => [
'newsletter' => 'checkbox',
],
];
}
Dynamic Field Generation
Override fields() to conditionally include fields:
public function fields()
{
$fields = ['name' => 'text', 'email' => 'email'];
if ($this->user->isAdmin()) {
$fields['role'] = 'select|admin,user';
}
return $fields;
}
Custom Validation Logic
Extend the validate() method:
public function validate(array $data)
{
$validator = parent::validate($data);
if ($data['email'] === 'test@example.com') {
$validator->errors()->add('email', 'Test email not allowed.');
}
return $validator;
}
Form Submission Handling In a controller:
public function store(ContactForm $form)
{
$validated = $form->validate(request()->all());
if ($validated->fails()) {
return back()->withErrors($validated)->withInput();
}
// Process data...
}
Laravel Collective Integration
Use collective/html for enhanced field rendering:
public function fields()
{
return [
'name' => 'text|class=form-control',
];
}
Form Requests
Combine with Laravel’s FormRequest for API-like validation:
use Illuminate\Foundation\Http\FormRequest;
class StoreContactFormRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return (new ContactForm())->rules();
}
}
Field Naming Conflicts
Ensure field names in fields() match validation rules exactly. Use unique keys for nested fields (e.g., user.name).
CSRF Token Handling The package does not auto-generate CSRF tokens. Include it manually in your blade template:
{!! csrf_field() !!}
{!! $form->render() !!}
Asset Paths
If using custom assets (e.g., class=form-control), ensure paths are absolute or use Laravel mix:
public function fields()
{
return [
'name' => 'text|class=' . mix('css/form.css'),
];
}
Validation Errors Dump the validator for debugging:
$validator = $form->validate($data);
dd($validator->errors());
Field Rendering Issues
Check if the render() method is being called correctly. Override it for custom logic:
public function render()
{
return view('custom.form', ['form' => $this]);
}
Custom Field Types
Extend the package by creating a Field class:
namespace App\Form\Fields;
use Derafu\Form\Field;
class CustomField extends Field
{
public function render()
{
return '<input type="custom" value="' . $this->value . '">';
}
}
Register it in the config:
'fields' => [
'custom' => \App\Form\Fields\CustomField::class,
],
Form Events
Listen for form events (e.g., form.rendering):
Form::macro('rendering', function ($callback) {
$this->events['rendering'] = $callback;
return $this;
});
How can I help you explore Laravel packages today?