Content Overview 

  • 1 Laravel 6 Validation Example
  • 2 Writing A Validation Logic
  • 3 Displaying Validation Errors
  • 4 The @error Directive
  • 5 Optional Fields
  • 6 AJAX Requests & Validation
  • 7 Form Request Validation In Laravel 6
  • 8 Manually Creating Validators
  • 9 Named Error Bags
  • 10 Working With The Error Messages
    10.1 Retrieving The First Error Message For The Field10.2 Retrieving All Error Messages For A Field* 11 Recommended Posts

You may also like: Tutorial Laravel 6 with Docker and Docker-Compose


Laravel 6 Validation Example

Our first step is to install the Laravel 6.

If you are new to Laravel 6, then check out my Laravel 6 CRUD tutorial on this blog.

Right now, Laravel 6 is the latest version. In the future, you may need to specify the version while installing the Laravel 6.

So, install the Laravel 6 using the following command.

composer create-project --prefer-dist laravel/laravel6

// or

laravel new laravel6

Create the FormController.php file.

php artisan make:controller FormController

Add two methods inside the **FormController.php **file.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class FormController extends Controller
{
    public function create()
    {

    }

    public function store(Request $request)
    {
        
    }
}

Now, write the two routes inside the **routes >> web.php **file, which handles URI of our application.

// web.php

Route::get('form', 'FormController@create')->name('form.create');
Route::post('form', 'FormController@store')->name('form.store');

Now, create the model and migration file using the following command.

php artisan make:model Form -m

Write a following code inside the** create_forms_table.php** file.

public function up()
{
        Schema::create('forms', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('item_name');
            $table->string('sku_no');
            $table->integer('price');
            $table->timestamps();
        });
}

Now, create the table using the following command.

php artisan migrate

Also, we can prevent mass assignment exception, add the $fillable property.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Form extends Model
{
    protected $fillable = ['item_name', 'sku_no', 'price'];
}

Inside the **views **folder, create a layout file called **layout.blade.php file **and add the following code.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Laravel 6 Validation Example</title>
  <link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css" />
</head>
<body>
  <div class="container">
    @yield('content')
  </div>
  <script src="{{ asset('js/app.js') }}" type="text/js"></script>
</body>
</html>

Now, in the same views folder, create a file called **create.blade.php **and add the following code.

@extends('layout')

@section('content')
<style>
  .uper {
    margin-top: 40px;
  }
</style>
<div class="card uper">
  <div class="card-header">
    Add Item
  </div>
  <div class="card-body">
      <form method="post" action="{{ route('form.store') }}">
          <div class="form-group">
              @csrf
              <label for="name">Item Name:</label>
              <input type="text" class="form-control" name="item_name"/>
          </div>
          <div class="form-group">
              <label for="price">SKU Number :</label>
              <input type="text" class="form-control" name="sku_no"/>
          </div>
          <div class="form-group">
              <label for="quantity">Item Price :</label>
              <input type="text" class="form-control" name="price"/>
          </div>
          <button type="submit" class="btn btn-primary">Create Item</button>
      </form>
  </div>
</div>
@endsection

Now, write the **FormController’s create() **function.

// FormController.php

public function create()
{
    return view('create');
}

Now, you can see the form on this URL: http://localhost:8000/form.

Writing A Validation Logic

Write the validation logic inside the **FormController’s store() **function.

public function store(Request $request)
{
        $validatedData = $request->validate([
            'item_name' => 'required|max:255',
            'sku_no' => 'required|alpha_num',
            'price' => 'required|numeric',
        ]);
        \App\Form::create($validatedData);

        return response()->json('Form is successfully validated and data has been saved');
}

Now, go to the form and try to submit the form. It won’t send, but you do not see any errors.

Displaying Validation Errors

Okay, so now, we need to write the following snippet inside the **create.blade.php **file.

@if ($errors->any())
      <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
              <li>{{ $error }}</li>
            @endforeach
        </ul>
      </div><br />
@endif

If an incoming request parameters do not pass the given validation rules, then as mentioned previously, Laravel will automatically redirect a user back to their previous location.

All the validation errors will automatically be flashed to a session.

One thing to notice here that we did not have to explicitly bind all the error messages to a view in the GET route.

It is because Laravel will check for the errors in the session data, and automatically attach them to a view if they are available.

The $errors variable will be the instance of Illuminate\Support\MessageBag.

So, final **create.blade.php **file is following.

@extends('layout')

@section('content')
<style>
  .uper {
    margin-top: 40px;
  }
</style>
<div class="card uper">
  <div class="card-header">
    Add Item
  </div>
  <div class="card-body">
    @if ($errors->any())
      <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
              <li>{{ $error }}</li>
            @endforeach
        </ul>
      </div><br />
    @endif
      <form method="post" action="{{ route('form.store') }}">
          <div class="form-group">
              @csrf
              <label for="name">Item Name:</label>
              <input type="text" class="form-control" name="item_name"/>
          </div>
          <div class="form-group">
              <label for="price">SKU Number :</label>
              <input type="text" class="form-control" name="sku_no"/>
          </div>
          <div class="form-group">
              <label for="quantity">Item Price :</label>
              <input type="text" class="form-control" name="price"/>
          </div>
          <button type="submit" class="btn btn-primary">Create Item</button>
      </form>
  </div>
</div>
@endsection

The $errors variable is bound to a view by the Illuminate\View\Middleware\ShareErrorsFromSession middleware, which is provided by a web middleware group.

When this middleware is applied, the $errors variable will always be available in the views, allowing us to conveniently assume the $errors variable is always defined and can be safely used inside your HTML code.

The @error Directive

You can also use the @error Blade directive to quick check if the validation error messages exist for a given attribute.

Within the @error directive, you may echo the $message variable to display the error message:

<div class="form-group">
   @csrf
   <label for="name">Item Name:</label>
   <input type="text" class="form-control" name="item_name"/>
    @error('item_name')
          <div class="alert alert-danger">{{ $message }}</div>
    @enderror
</div>

Optional Fields

Out of the box, Laravel includes the TrimStrings and ConvertEmptyStringsToNull middleware in your app’s global middleware array.

These middleware are included in the stack by an App\Http\Kernel class.

Because of this middleware, you will often need to mark your “optional” request fields as nullable if you do not want a validator to consider the null values as invalid.

For instance:

$request->validate([
    'item_name' => 'required|max:255',
    'sku_no' => 'required|alpha_num',
    'price' => 'required|numeric',
    'publish_at' => 'nullable|date',
]);

In this example, we are specifying that a publish_at field may be either null or the valid date representation.

If a nullable modifier is not added to the rule definition, a validator would consider null the invalid date.

AJAX Requests & Validation

In this example, we used the traditional form to send data to an app.

However, many applications use the AJAX requests.

When using the validate() method during the AJAX request, Laravel will not generate the redirect response.

Instead, Laravel generates the JSON response containing all of the validation errors. That JSON response will be sent with a 422 HTTP status code.

Form Request Validation In Laravel 6

For more complex validation cases, you may wish to create the “form request”.

Form requests are a custom request classes that contain all the validation logic.

If we need to create the form request class, use the make: request Artisan CLI command:

php artisan make:request ValidateRequest

The generated class will be placed in an app/Http/Requests directory.

If the directory does not exist, it will be generated when you run the make: request command.

Let’s add the few validation rules to the rules method:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class ValidateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'item_name' => 'required|max:255',
            'sku_no' => 'required|alpha_num',
            'price' => 'required|numeric',
        ];
    }
}

So, how are the validation rules evaluated?

All you need to do is type-hint a request on your controller method.

An incoming form request is validated before the controller method is called, meaning we do not need to clutter the controller with any validation logic.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Requests\ValidateRequest;

class FormController extends Controller
{
    public function create()
    {
        return view('create');
    }

    public function store(ValidateRequest $request)
    {
        $validatedData = $request->validated();
        \App\Form::create($validatedData);

        return response()->json('Form is successfully validated and data has been saved');
    }
}

Manually Creating Validators

If we do not want to use the validate() method on the request, you may create the validator object manually using the Validator facade.

The make method on a facade generates the new validator instance.

See the following function inside **FormController.php **file.

public function store(ValidateRequest $request)
{
        $validator = \Validator::make($request->all(), [
            'item_name' => 'required|max:255',
            'sku_no' => 'required|alpha_num',
            'price' => 'required|numeric',
        ]);

        if ($validator->fails()) {
            return redirect('form')
                        ->withErrors($validator)
                        ->withInput();
        }

        \App\Form::create([
            'item_name' => $request->item_name, 
            'sku_no' => $request->sku_no,
            'price' => $request->sku_no
        ]);

        return response()->json('Form is successfully validated and data has been saved');
}

The first argument passed to a make method is the data under validation.

The second argument is the validation rules that should be applied to the data.

After checking if a request validation failed, you may use the withErrors method to flash the error messages to a session.

When using that method, the $errors variable will automatically be shared with your views after redirection, allowing us to display them back to a user easily.

The withErrors method accepts the validator, the MessageBag, or a PHP array.

Named Error Bags

If you have the multiple forms on the single page, you may wish to name the MessageBag of errors, allowing us to retrieve the error messages for the particular form.

Pass the name as the second argument to withErrors:

return redirect('register')
            ->withErrors($validator, 'login');

You may then access the named MessageBag object from the $errors variable.

{{ $errors->login->first('email') }}

Working With The Error Messages

After calling the errors method on a Validator instance, you will receive the **Illuminate\Support\MessageBag **instance, which has the variety of convenient methods for working with error messages.

The $errors variable which is automatically made available to all the views is also the instance of the MessageBag class.

Retrieving The First Error Message For The Field

If we want to retrieve the first error message for the given field, use the first method:

$errors = $validator->errors();

echo $errors->first('email');

Retrieving All Error Messages For A Field

If you need to retrieve the array of all of the messages for the given field, use the get method.

foreach ($errors->get('email') as $message) {
    //
}

If you are validating the array form field, you may retrieve all the messages for each of the array items using the ***** character.

foreach ($errors->get('attachments.*') as $message) {
    //
}

So, we have lots of options to add validation in the form in Laravel 6.

Finally, Laravel 6 Validation Example | Validation In Laravel Tutorial is over.

Further Reading

How to Laravel 6 Database Migrations - Add Admin Role to Users

Laravel 6 Release New Features and Upgrade

Laravel 6 Image Upload Tutorial

#laravel #php #web-development

Laravel 6 Form Validation Tutorial With Example
4 Likes140.60 GEEK