Laravel 10 Ajax Form Validation Example Tutorial

Laravel 10,instead of reloading an entire page, AJAX enables you to update specific sections or elements of a page dynamically. This capability is particularly useful for implementing features like live search, infinite scrolling, or real-time notifications, where only a portion of the page needs to be refreshed.

Step 1: Install Laravel App

composer create-project laravel/laravel example-AJAX

Step 2: Create Migration and Model

php artisan make:migration create_posts_table

database/migrations/2022_02_17_133331_create_posts_table.php

<?php
  
  use Illuminate\Database\Migrations\Migration;
  use Illuminate\Database\Schema\Blueprint;
  use Illuminate\Support\Facades\Schema;
    
  return new class extends Migration
  {
      /**
       * Run the migrations.
       *
       * @return void
       */
      public function up(): void()
      {
          Schema::create('posts', function (Blueprint $table) {
              $table->id();
              $table->string('title');
              $table->text('body');
              $table->timestamps();
          });
      }
    
      /**
       * Reverse the migrations.
       *
       * @return void
       */
      public function down(): void
      {
          Schema::dropIfExists('posts');
      }
  };

migration command as bellow:

php artisan migrate

Now we will create Post model by using following command:

php artisan make:model Post

app/Models/Post.php

<?php
  
  namespace App\Models;
    
  use Illuminate\Database\Eloquent\Factories\HasFactory;
  use Illuminate\Database\Eloquent\Model;
    
  class Post extends Model
  {
      use HasFactory;
      /**
       * Write code on Method
       *
       * @return response()
       */
      protected $fillable = [
          'title', 'body'
      ];
  }

Step 3: Create Controller

php artisan make:controller PostController

app/Http/Controllers/PostController.php

<?php
    
    namespace App\Http\Controllers;
        
    use Illuminate\Http\Request;
    use Illuminate\Support\Facades\Validator;
    use App\Models\Post;
    use Illuminate\View\View;
    use Illuminate\Http\JsonResponse;
        
    class PostController extends Controller
    {
        /**
         * Write code on Method
         *
         * @return response()
         */
        public function index(): View
        {
            $posts = Post::get();
        
            return view('posts', compact('posts'));
        }
        
        /**
         * Write code on Method
         *
         * @return response()
         */
        public function store(Request $request): JsonResponse
        {
            $request->validate([
                'title' => 'required',
                'body' => 'required',
            ]);
             
            Post::create([
                'title' => $request->title,
                'body' => $request->body,
            ]);
        
            return response()->json(['success' => 'Post created successfully.']);
        }
    }

Step 4: Create and Add Routes

routes/web.php 

<?php
  
  use Illuminate\Support\Facades\Route;
    
  use App\Http\Controllers\PostController;
    
  /*
  |--------------------------------------------------------------------------
  | Web Routes
  |--------------------------------------------------------------------------
  |
  | Here is where you can register web routes for your application. These
  | routes are loaded by the RouteServiceProvider within a group which
  | contains the "web" middleware group. Now create something great!
  |
  */
    
  Route::controller(PostController::class)->group(function(){
      Route::get('posts', 'index');
      Route::post('posts', 'store')->name('posts.store');
  });

Step 5: Create Blade File

resources/views/posts.blade.php 

<!DOCTYPE html>
<html>
<head>
    <title>Laravel 10 Ajax Form Validation Example - webthestuff.com</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" ></script>
    <meta name="csrf-token" content="{{ csrf_token() }}" />
</head>
<body>
       
<div class="container">
    <div class="card bg-light mt-3">
        <div class="card-header">
            Laravel 10 Ajax Form Validation Example - webthestuff.com
        </div>
        <div class="card-body">
    
            <table class="table table-bordered mt-3">
                <tr>
                    <th colspan="3">
                        List Of Posts
                        <button type="button" class="btn btn-success float-end" data-bs-toggle="modal" data-bs-target="#postModal">
                          Create Post
                        </button>
                    </th>
                </tr>
                <tr>
                    <th>ID</th>
                    <th>Title</th>
                    <th>Body</th>
                </tr>
                @foreach($posts as $post)
                <tr>
                    <td>{{ $post->id }}</td>
                    <td>{{ $post->title }}</td>
                    <td>{{ $post->body }}</td>
                </tr>
                @endforeach
            </table>
    
        </div>
    </div>
</div>
    
<!-- Modal -->
<div class="modal fade" id="postModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Create Post</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <form id="ajax-form" action="{{ route('posts.store') }}">
            @csrf
    
            <div class="alert alert-danger print-error-msg" style="display:none">
                <ul></ul>
            </div>
      
            <div class="mb-3">
                <label for="titleID" class="form-label">Title:</label>
                <input type="text" id="titleID" name="title" class="form-control" placeholder="Name">
            </div>
    
            <div class="mb-3">
                <label for="bodyID" class="form-label">Body:</label>
                <textarea name="body" class="form-control" id="bodyID"></textarea>
            </div>
       
            <div class="mb-3 text-center">
                <button class="btn btn-success btn-submit">Submit</button>
            </div>
      
        </form>
      </div>
    </div>
  </div>
</div>
       
</body>
    
<script type="text/javascript">
        
    /*------------------------------------------
    --------------------------------------------
    Form Submit Event
    --------------------------------------------
    --------------------------------------------*/
    $('#ajax-form').submit(function(e) {
        e.preventDefault();
       
        var url = $(this).attr("action");
        let formData = new FormData(this);
  
        $.ajax({
                type:'POST',
                url: url,
                data: formData,
                contentType: false,
                processData: false,
                success: (response) => {
                    alert('Form submitted successfully');
                    location.reload();
                },
                error: function(response){
                    $('#ajax-form').find(".print-error-msg").find("ul").html('');
                    $('#ajax-form').find(".print-error-msg").css('display','block');
                    $.each( response.responseJSON.errors, function( key, value ) {
                        $('#ajax-form').find(".print-error-msg").find("ul").append('<li>'+value+'</li>');
                    });
                }
           });
      
    });
    
</script>
    
</html>

Run Laravel App:

php artisan serve

Now, Go to web browser, type the given URL and see the output:

http://localhost:8000/posts