Validation
Basics
Since version 1.6.20 validation is added to the Form class. It automatically gets the rules that are specified through field options, and validates the form. Here’s a short example:
// app/Forms/PostForm.php
<?php namespace App\Forms;
use Kris\LaravelFormBuilder\Form;
class PostForm extends Form
{
public function buildForm()
{
$this
->add('title', 'text', [
'label' => 'Post title',
'rules' => 'required|min:5',
'error_messages' => [
'title.required' => 'The title field is mandatory.'
]
])
->add('body', 'textarea', [
'label' => 'Post body',
'rules' => 'max:5000'
]);
}
}
// app/Http/Controllers/PostController.php
<?php
namespace App\Http\Controllers;
use Kris\LaravelFormBuilder\FormBuilderTrait;
use App\Forms\PostForm;
class PostController extends Controller
{
use FormBuilderTrait;
public function create()
{
$form = $this->form(PostForm::class, [
'method' => 'POST',
'route' => 'PostController@store'
]);
return view('posts.create', compact('form'));
}
public function store(Request $request)
{
$form = $this->form(PostForm::class);
// It will automatically use current request, get the rules, and do the validation
if (!$form->isValid()) {
return redirect()->back()->withErrors($form->getErrors())->withInput();
}
// Or automatically redirect on error. This will throw an HttpResponseException with redirect
$form->redirectIfNotValid();
Post::create($form->getFieldValues());
return redirect()->route('posts');
}
}
NOTE: Form class will automatically use labels as attributes in error messages: For example when required validation fails:
* The title field is mandatory.
* The Post body is required.
First error message is from error_messages
property, and 2nd is automatically generated.
Overriding rules
By default when you call isValid
method on the Form class, it will call validate
method,
and use rules provided in form options. If you want to override some rules, you can call validate
by yourself and change what you need.
It will override rules only for fields that you pass, and for other will use default ones provided in buildForm.
Let’s take example from basics part:
// app/Http/Controllers/PostController.php
<?php
namespace App\Http\Controllers;
use Kris\LaravelFormBuilder\FormBuilderTrait;
use App\Forms\PostForm;
class PostController extends Controller
{
use FormBuilderTrait;
public function store(Request $request)
{
$form = $this->form(PostForm::class);
$form->validate(['title' => 'required|alpha_num']);
if (!$form->isValid()) {
return redirect()->back()->withErrors($form->getErrors())->withInput();
}
Post::create($form->getFieldValues());
return redirect()->route('posts');
}
}
Custom messages
In some situations there is a need for a custom message per field. Custom messages can be provided in 2 ways:
- through
error_messages
property on field (See PostForm above) - 2nd argument to
validate
method.
Let’s use the example from above:
// app/Http/Controllers/PostController.php
<?php
namespace App\Http\Controllers;
use Kris\LaravelFormBuilder\FormBuilderTrait;
use App\Forms\PostForm;
class PostController extends Controller
{
use FormBuilderTrait;
public function store(Request $request)
{
$form = $this->form(PostForm::class);
$form->validate(['title' => 'required|alpha_num'], [
'title.required' => 'Please provide valid title for this post.'
]);
if (!$form->isValid()) {
return redirect()->back()->withErrors($form->getErrors())->withInput();
}
Post::create($form->getFieldValues());
return redirect()->route('posts');
}
}
For more informations how to override messages, check Laravel docs http://laravel.com/docs/5.1/validation#custom-error-messages
Getting the rules from Form
Some people like to use Exceptions when validating the form. That can be easily done in Laravel 5.1 with ValidatesRequests trait.
The problem is that validate
method from this trait requires 2 parameters:
Request and rules.
If you want to use this method, you can just call getRules
from Form class, and it will give you back properly formatted rules in array.
// app/Http/Controllers/PostController.php
<?php
namespace App\Http\Controllers;
use Kris\LaravelFormBuilder\FormBuilderTrait;
use App\Forms\PostForm;
use Illuminate\Foundation\Validation\ValidatesRequests;
class PostController extends Controller
{
use FormBuilderTrait;
use ValidatesRequests;
public function store(Request $request)
{
$form = $this->form(PostForm::class);
$rulesToOverride = [
'body' => 'max:10000'
];
$this->validate($request, $form->getRules($rulesToOverride));
Post::create($form->getFieldValues());
return redirect()->route('posts');
}
}
Different request
By default, Form class will use latest request that it got when form was created.
That request is always the same as the one that use use in the controller method, so there is no need to override it with the same request in those situations.
If for some reason request needs to be changed, it can be done with setRequest
// app/Http/Controllers/PostController.php
<?php
namespace App\Http\Controllers;
use Kris\LaravelFormBuilder\FormBuilderTrait;
use App\Forms\PostForm;
class PostController extends Controller
{
use FormBuilderTrait;
public function store(Request $request)
{
$form = $this->form(PostForm::class);
$somePreviousRequest = $this->getPreviousRequest();
// DO NOT DO THIS, SAME REQUEST IS ALREADY AVAILABLE IN FORM CLASS
$form->setRequest($request);
$form->setRequest($somePreviousRequest);
if (!$form->isValid()) {
return redirect()->back()->withErrors($form->getErrors())->withInput();
}
Post::create($form->getFieldValues());
return redirect()->route('posts');
}
}