Submit Form Using Ajax in Laravel with Form Validation

You can submit a form using Ajax in Laravel without a page reload. This is required when you do not want to refresh the whole page, instead, you want to use a small part of the page to submit a form without disturbing the other elements on the same page.

In this topic, we will create a Laravel project to submit a form using Ajax. It will send form data using Ajax and also do the form validation. It will submit the form without a page reload.

This small Laravel application will display a list of submitted user applications, you can add new applications using a form. The form will be submitted using Ajax with Laravel form validation.

 

Development Steps for Ajax form submission in LaravelWatch YouTube Video

Create the project in Laravel

We will create a project named "ajax_form" using the below command.


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

Create Migration

We will create a new table named 'applications'. This table will store the details of each application submitted. Create a model, controller and migration using the below command.


php artisan make:model Application -mcr

The above command will create the model, the controller and the migration file.

Update .env file for database details. We will be using a MySQL database named 'lara_demo', so we updated our .env file as below:


DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=lara_demo
DB_USERNAME=root
DB_PASSWORD=

Migration for the custom table

Update the migration file for the 'applications' table as below:


public function up()
    {
        Schema::create('applications', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->string('address')->nullable();
            $table->timestamps();
        });
    }

So, our custom table will have name, email and address columns and the data will be populated by our Ajax form submission.

Run the migration using the artisan command php artisan migrate to create the default Laravel tables and our custom table.

Below is the model:

app/Models/Application.php


<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Application extends Model
{
    use HasFactory;

    protected $fillable = ['name','email','address'];
}

Create a Laravel form and submit using Ajax

We will create two views, one for displaying all the applications and the other for adding a new application.

Below are the files in the resources/views folder:

Submit form using Ajax in Laravel

There are layouts for the header, footer and master. application.blade.php is the form to submit a new application and index.php is for the listing of all applications.

resources/views/layouts/header.blade.php


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Application Form</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1">
    <meta name="_token" content="{{ csrf_token() }}">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="{{asset('css/style.css')}}" />

</head>

resources/views/layouts/footer.blade.php


<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/js/bootstrap.min.js"></script>

resources/views/layouts/master.blade.php


@include("layouts.header")

<body>
    @yield("main-content")
    @include("layouts.footer")
    @stack("js")
</body>

</html>

resources/views/application.blade.php


@extends('layo@uts.master')
@section('main-content')
    <div class="container">
        <div class="col-md-12">
            <div class="form-appl">
                <div class="title-class">
                    <h2>Submit Your Application</h2>
                </div>
                <div class="error" id="message"></div>

                <form id="frmAppl" class="frmAppl">
                    @csrf
                    <div class="form-group col-md-12 mb-3">
                        <label for="">Your Name</label>
                        <input class="form-control" type="text" name="name" id="name" placeholder="Enter Your Name">
                    </div>

                    <div class="form-group col-md-12 mb-3">
                        <label for="">Your Email</label>
                        <input class="form-control" type="text" name="email" id="email" placeholder="Enter Your Email">
                    </div>
                    <div class="form-group col-md-12 mb-5">
                        <label for="">Address</label>
                        <textarea class="form-control" name="address" id="address" cols="90" rows="3"
                            placeholder="Enter Your Address"></textarea>
                    </div>

                    <button type="submit" id="submitBtn" class="btn btn-primary">Submit</button>
                    <a class="btn btn-danger" href="{{route('applications.list')}}">Cancel</a>
                </form>
            </div>
        </div>
    </div>

    <!-- Modal -->
    <div class="modal fade" tabindex="-1" role="dialog" id="showMsg">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-body" style="text-align: center;">
                    <h4>Thank you for submitting the form</h4>
                </div>
                <div class="modal-footer" style="border: none;">

                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>
@endsection
@push("js")
<script>       
$("#frmAppl").on("submit", function(event) {
    event.preventDefault();
    var error_ele = document.getElementsByClassName('err-msg');
    if (error_ele.length > 0) {
        for (var i=error_ele.length-1;i>=0;i--){
            error_ele[i].remove();
        }
    }
   
    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
        }
    });
   
    $.ajax({
        url: "{{ route('application.store') }}",
        type: "POST",
        data: new FormData(this),
        dataType: 'json',
        contentType: false,
        processData: false,
        cache: false,
        beforeSend: function() {
            $("#submitBtn").prop('disabled', true);
        },
        success: function(data) {
            if (data.success) {
                $("#frmAppl")[0].reset();
                $("#showMsg").modal('show');
                
            } 
            else {
                $.each(data.error, function(key, value) {
                    var el = $(document).find('[name="'+key + '"]');
                    el.after($('<span class= "err-msg">' + value[0] + '</span>'));
                    
                });
            }
            $("#submitBtn").prop('disabled', false);
        },
        error: function (err) {
            $("#message").html("Some Error Occurred!")
            }
        });
    });
</script>
@endpush

In the above code, we have a simple form with a submit and a cancel button. Then a Modal is defined to display the success message. Let us see the Ajax scripts for the form submission.

First, we remove the existing error messages using the remove() method. Then after using ajaxSetup, we create a FormData instance to submit the form. It will send form data using Ajax. If the submission is successful, we will display a modal. If there is any validation error, it loops through the errors for each form input and adds a span element to display the error message corresponding to the input field.

Below is the view for displaying the applications.

resources/views/index.blade.php


@extends('layouts.master')
@section('main-content')
<h1>List of Applications</h1>
<div class="container">
    <div class="text-end mb-5"><a class="btn btn-info" href="{{route('application.store')}}">New Applicants</a>
    </div>
 <table class="table table-bordered table-striped">
    <thead style="">
        <th>Name</th><th>Email</th><th>Address</th>
    </thead>
    <tbody>
        @forelse($applicants as $appl)
        <tr>
            <td>{{$appl->name}}</td><td>{{$appl->email}}</td><td>{{$appl->address}}</td>
        </tr>
        @empty
        <tr>
            <td colspan="3">No data Found</td>
        </tr>
        @endforelse
    </tbody>
</table>
@endsection()

Routes


Route::get('/', [ApplicationController::class, 'index'])->name('applications.list');
Route::get('/application',[ApplicationController::class,'create'])->name('application.create');
Route::post('/application',[ApplicationController::class,'store'])->name('application.store');

The Controller

app/Http/Controllers/ApplicationController.php


<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Application;
use Illuminate\Support\Facades\Validator;

class ApplicationController extends Controller
{
    public function index(){
        $applicants = Application::latest('id')->get();
        return view('index', compact('applicants'));
    }
    public function create(Request $request) {
        return view ('application');
    }

    public function store(Request $request){
        $validator = Validator::make($request->all(), ['name' => 'required', 'email' => 'required|email|unique:applications']);

        if ($validator->fails()) {
            return response()->json([
                        'error' => $validator->errors()
                    ]);
        }

        $result = Application::create($request->all());
        
        return response()->json(['success' => 'Form submitted successfully.']);
    }
}

Check the store() method. Validations are done for the name and email fields, if validation fails, it returns a response with validator errors. If validation is successful, a success message is returned.

Use the below stylesheet:

public/css/style.css


* {box-sizing: border-box;
}
body {
  margin: 0;
  font-family: Helvetica, sans-serif;;
}
h1,h4, h3 {
  text-align: center;
  margin-bottom: 20px;
  margin-top: 10px;
}

.container{
    min-height: 600px;;
}
footer{
    text-align: center;
}
.frmAppl{
    width:50%;
    margin: auto;
}

.error{
  color:red;
  text-align:center;
}

.modal-content{
color:#fff;
background: #32243c;
}
table{
  width: 70%!important;
  margin: auto;
}
table>thead{
  background-color:#2b5171;
  color:#fff;
}

.form-appl{
  padding:5px; 
  margin-top:50px;
}
.title-class{
font-size:30px; 
text-align:center;
}
.err-msg{
  color: red;
}

Test the application

From the project root, run the php development server:


php artisan serve

In the browser run localhost:8000. Test all the validations and successful submission.

Hope it will be useful to you.

download code for submit form using Ajax in Laravel Download code from Github.

Post a Comment

Save my Name and Email id for future comments