kris/laravel4-form-builder
kris/laravel4-form-builder is a Laravel 4 package for building HTML forms programmatically from reusable PHP definitions, reducing repetitive markup and keeping fields consistent. It helps scaffold and maintain forms in Laravel 4 applications.
Install it as a Laravel 4 package: require "kris/laravel4-form-builder": "dev-master" in composer.json, run composer update, then register the service provider and facade alias in app/config/app.php:
'providers' => [
// ...
'Kris\LaravelFormBuilder\FormBuilderServiceProvider',
],
'aliases' => [
// ...
'FormBuilder' => 'Kris\LaravelFormBuilder\Facades\FormBuilder',
],
Publish the package config so you can inspect the defaults:
php artisan config:publish kris/laravel4-form-builder
The file lands under app/config/packages/kris/laravel4-form-builder/. Read that first, then the package README and src/Kris/LaravelFormBuilder/Form.php — those three tell you almost everything about field registration, rendering, and validation.
The first useful use case is a single create form with server-side validation. Define a form class:
// app/Forms/PostForm.php
namespace App\Forms;
use Kris\LaravelFormBuilder\Form;
class PostForm extends Form
{
public function buildForm()
{
$this
->add('title', 'text', ['rules' => 'required|max:255'])
->add('body', 'textarea', ['rules' => 'required'])
->add('save', 'submit', ['label' => 'Save post']);
}
}
Then build it in a controller, pass it to a view, and render it:
$form = \FormBuilder::create('App\Forms\PostForm', [
'method' => 'POST',
'url' => route('posts.store'),
]);
return view('posts.create', compact('form'));
{!! $form->render() !!}
That gives you a complete <form> with fields, old-input repopulation, CSRF token and validation error display, assuming your view has access to $errors.
One form class per resource, plus a base class for shared fields. Put common fields (timestamps, publish toggles, SEO fields) in an abstract BaseForm and extend it per resource. buildForm() is just a fluent chain of add() calls, so composition stays readable.
Use model for edit forms. Pass the Eloquent model in the form options and the builder prefills every matching field:
$form = \FormBuilder::create('App\Forms\PostForm', [
'method' => 'PUT',
'url' => route('posts.update', $post->id),
'model' => $post,
]);
Then $form->getData() gives you only the form’s fields, already keyed for create() or update().
Validate through the form, not a separate validator. Field-level rules options are collected and run by the form. In the controller:
if (! $form->isValid()) {
return redirect()->back()
->withErrors($form->getErrors())
->withInput();
}
Newer tags expose isValid(); earlier tags use validate(). Check the method on your pinned version.
Render all, some, or the rest. For custom layouts, render the form tag and individual fields, then call renderRest() so hidden inputs and unrendered fields are not lost:
{!! $form->renderForm() !!}
<div class="col-md-6">{!! $form->renderField('title') !!}</div>
<div class="col-md-6">{!! $form->renderField('body') !!}</div>
{!! $form->renderRest() !!}
This is the pattern to use when Bootstrap grid classes need to sit between fields rather than inside a single generated block.
Use child forms for repeated structures. The builder supports nested form fields ($this->add('address', 'form', ['class' => 'App\Forms\AddressForm')]), which is useful for address blocks and settings panels. Keep nesting shallow; debugging a three-level form is not pleasant.
Register project-specific field types. Extend Kris\LaravelFormBuilder\Fields\FormField, point getTemplate() at a Blade partial, and register the type in the package config (custom_fields) or through the form builder service. This is the cleanest extension point for things like a map picker, slug preview, or WYSIWYG wrapper.
Wire view overrides through the package view namespace. Publish or override the package views under app/views/packages/kris/laravel4-form-builder/ when you need to change wrappers, error markup, or label rendering globally.
{!! !!} is mandatory. The renderer returns HTML; using {{ }} will show markup to users.render(), not by individual fields. If you render field-by-field, make sure you still emit the form opening tag and hidden inputs, or use renderRest(). Symptoms are 419/TokenMismatch errors or PUT routes receiving POST.withInput() values are used instead of the model. That is usually correct, but check file fields — browsers cannot repopulate them, so the model value may flash back.getData() can include submit buttons depending on version. Filter or remove buttons before mass assignment if you pass the array straight to Model::create().buildForm(). unique:posts,slug,{$id} needs the current model ID. Either generate rules in the controller and inject them via form options, or use a base form that reads $this->getModel() inside buildForm().tags[] and nested names render fine, but validation rules, old-input lookups, and getData() flattening behave differently. Test the round trip explicitly.'files' => true on the form (and verify the generated tag includes enctype="multipart/form-data"); otherwise uploads silently arrive empty.value => label. Pass 'choices' => [...] and an 'empty_value' when you need a placeholder. Do not pass an Eloquent collection directly unless you map it to key/value pairs.config:publish, not vendor:publish. The Laravel 4 path differs from later Laravel conventions and trips people up when following modern tutorials.dd($form->getFields()) shows each field’s type and options; $form->getField('title')->getOption('rules') confirms rules were registered. When rendering looks wrong, inspect the resolved field template name before editing CSS.Overall: a lightweight, Symfony-flavored abstraction that is genuinely pleasant for CRUD forms on Laravel 4, but treat it as legacy. Budget time for custom field work, and avoid coupling business logic to its rendering layer.
How can I help you explore Laravel packages today?