How to Create custom Validation Rule in Laravel 9

Validation is very important when you are allowing the user to submit <form > or data manipulation using AJAX.

Laravel already provided validation rules that you can use to validate the data. You can create your own validation rules if you are not available to apply specific validation using inbuilt rules.

In this tutorial, I show how you can create and use custom validation rule in Laravel 9.

How to Create custom validation rule in Laravel


Contents

  1. Create Validation Rule Class
  2. Create Controller
  3. Routes
  4. Create View
  5. Output
  6. Conclusion

1. Create Validation Rule Class

  • Create Validusername rule to validate username value –
php artisan make:rule Validusername --invokable
  • This will create a new file Validusername.php in app/Rules/ folder.
  • Open it.
  • In the __invoke() method write a validation rule.
  • This method has 3 parameters –
    • $attribute – It has validating element name.
    • $value – It has validating element value.
    • $fail – Return error message.
  • Using preg_match() check if value is valid or not. If not valid then pass an error message in $fail().

Completed Code

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\InvokableRule;

class Validusername implements InvokableRule
{
      /**
      * Run the validation rule.
      *
      * @param string $attribute
      * @param mixed $value
      * @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
      * @return void
      */
      public function __invoke($attribute, $value, $fail){
           $usernamePreg = "/^[a-zA-Z0-9]+$/";

           if( !(preg_match($usernamePreg,$value)) ) {
                 $fail('Please enter valid :attribute.');
           }

      }
}

2. Create Controller

  • Create PagesController Controller –
php artisan make:controller PagesController
  • Include Validator, Session, and also need to include created rule – use App\Rules\Validusername; for using it.
  • Create 2 methods –
    • index() – Load index view.
    • submitform() – Using this method handle <form > submit.

Define validation on submitted values –

      • name – Set required rule.
      • username – Set required and custom rule. To apply the custom rule need to create an instance of Validusername class – new Validusername.
      • minvalue – Set required and integer rule.
      • maxvalue – Set required and interger rule. Also, create a custom rule using closure. Check if value is less than minvalue. If it is then pass an error message in $fail().

If values are not validated then redirect to the page with error messages otherwise set success message in SESSION flash and redirect to /.

Completed Code

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Session;
use App\Rules\Validusername;

class PagesController extends Controller
{
     public function index(){
         return view('index');
     }

     public function submitform(Request $request){

         // Define Validation
         $validator = Validator::make($request->all(), [
              'name' => 'required',
              'username' => ['required', 'string', new Validusername],
              'minvalue' => 'required|integer',
              'maxvalue' => ['required','integer', function ($attribute, $value, $fail)use ($request) {
                    $minvalue = $request->get('minvalue');
                    if ($value < $minvalue) {
                         $fail($attribute.' value must be greater than minvalue');
                    }
              }],
         ]);

         if ($validator->fails()) {
              return redirect()->Back()->withInput()->withErrors($validator); 
         }else{
              Session::flash('message','Form submit Successfully.');
         }
         return redirect('/');
     }

}

3. Routes

  • Open routes/web.php file.
  • Here, create 2 routes –
    • / – Load index view.
    • /submitform – Handle form submit.
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PagesController;

Route::get('/', [PagesController::class, 'index']);
Route::post('/submitform',[PagesController::class,'submitform'])->name('submitform');

4. Create View

Create index.blade.php file in resources/views/ folder.

Create a simple <form >. Set action URL to route('submitform'). Display error message if <form > is not validated.

Completed Code

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>How to Create custom validation rule in Laravel 9</title>

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" >
</head>
<body>

    <div class="container">
         <div class="row">
              <div class="col-md-6 mt-5" style="margin: 0 auto;">

                   <!-- Alert message (start) -->
                   @if(Session::has('message'))
                        <div class="alert alert-success">
                             {{ Session::get('message') }}
                        </div>
                   @endif
                   <!-- Alert message (end) -->

                   <form method="post" action="{{ route('submitform') }}">

                        @csrf

                        <div class="form-group mb-4">

                             <label class="control-label col-sm-2" for="name">Name:</label>

                             <div class="col-sm-10">
                                  <input type="text" class="form-control" id="name" placeholder="Enter Name" name="name" value="{{ old('name') }}">
                             </div>

                             <!-- Error -->
                             @if($errors->has('name'))

                                  <div class='text-danger mt-2'>
                                       * {{ $errors->first('name') }}
                                  </div>

                             @endif
                        </div>

                        <div class="form-group mb-4">

                             <label class="control-label col-sm-2" for="username">Username:</label>
                             <div class="col-sm-10">
                                  <input type="text" class="form-control" id="username" placeholder="Enter Username" name="username" value="{{ old('username') }}">
                             </div>

                             <!-- Error -->
                             @if($errors->has('username'))

                                  <div class='text-danger mt-2'>
                                       * {{ $errors->first('username') }}
                                  </div>

                             @endif
                        </div>

                        <div class="form-group mb-4">

                             <label class="control-label col-sm-2" for="minvalue">Min value:</label>
                             <div class="col-sm-10">
                                  <input type="text" class="form-control" id="minvalue" placeholder="Enter Min value" name="minvalue" value="{{ old('minvalue') }}">
                             </div>

                             <!-- Error -->
                             @if($errors->has('minvalue'))

                                  <div class='text-danger mt-2'>
                                       * {{ $errors->first('minvalue') }}
                                  </div>

                             @endif

                        </div>

                        <div class="form-group mb-4">

                            <label class="control-label col-sm-2" for="maxvalue">Max value:</label>
                            <div class="col-sm-10">
                                 <input type="text" class="form-control" id="maxvalue" placeholder="Enter Max value" name="maxvalue" value="{{ old('maxvalue') }}" >
                            </div>

                            <!-- Error -->
                            @if($errors->has('maxvalue'))

                                 <div class='text-danger mt-2'>
                                      * {{ $errors->first('maxvalue') }}
                                 </div>

                            @endif

                        </div>

                        <div class="form-group "> 
                             <div class="col-sm-offset-2 col-sm-10">
                                  <button type="submit" class="btn btn-info">Submit</button>
                             </div>
                        </div>

                   </form>

              </div>

         </div>

    </div>
</body>
</html>

5. Output

View Output


6. Conclusion

Create a validation rule class if you want to use the same validation more than once. If you want to use a rule only one time then you can create it while defining validation.

If you found this tutorial helpful then don't forget to share.

Leave a Comment