Laravel 12 Ajax Form Submission with Bootstrap Modal: A Step-by-Step Tutorial

Learn how to submit a form using Ajax in Laravel 12. This tutorial covers form validation, database storage, and dynamic post display using Bootstrap modal without page refresh.

Laravel 12 Ajax Form Submission with Bootstrap Modal: A Step-by-Step Tutorial Image

Ajax requests are essential for modern web applications, allowing you to submit data to the server without refreshing the page. In this tutorial, we’ll walk you through how to create and submit a form using Ajax in Laravel 12. You’ll learn how to store data in the database, display it dynamically, and handle form validation—all without reloading the page.

We’ll create a simple "posts" table with title and body columns. Using a Bootstrap modal, users can add new posts via an Ajax request. This tutorial covers everything from setting up the Laravel project to handling Ajax requests and displaying data.

Steps to Implement Ajax Form Submission in Laravel 12

Step 1: Install Laravel 12

If you haven’t already set up a Laravel project, run the following command to create a new Laravel 12 application:

composer create-project laravel/laravel laravel-12-ajax

Step 2: Create Migration and Model

We’ll start by creating a migration for the posts table. Run the following command:

php artisan make:migration create_posts_table

Update the migration file (database/migrations/2024_03_21_133331_create_posts_table.php) with the following code:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};

Run the migration to create the table:

php artisan migrate

Next, create a Post model using this command:

php artisan make:model Post

Update the Post model (app/Models/Post.php) to include the fillable attributes:

<?php

namespace App\Models;

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

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title', 'body'
    ];
}

Step 3: Create Controller

We’ll create a PostController to handle the logic for displaying posts and storing new ones via Ajax. Run the following command:

php artisan make:controller PostController

Update the PostController (app/Http/Controllers/PostController.php) with the following code:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Post;
use Illuminate\View\View;
use Illuminate\Http\JsonResponse;

class PostController extends Controller
{
    public function index(): View
    {
        $posts = Post::get();
        return view('posts', compact('posts'));
    }

    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 Routes

Define routes for handling the GET and POST requests in routes/web.php:

<?php

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

Route::get('posts', [PostController::class, 'index']);
Route::post('posts', [PostController::class, 'store'])->name('posts.store');

Step 5: Create Blade File

Create a posts.blade.php file in the resources/views directory. This file will display the list of posts and include the Bootstrap modal for creating new posts.

<!DOCTYPE html>
<html>
<head>
    <title>Laravel 12 Ajax Form Submission with Bootstrap Modal</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"></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 mt-5">
            <h3 class="card-header p-3">Laravel 12 Ajax Form Submission</h3>
            <div class="card-body">
                <table class="table table-bordered">
                    <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>

    <!-- Bootstrap Modal -->
    <div class="modal fade" id="postModal" tabindex="-1" aria-labelledby="postModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="postModalLabel">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="title" class="form-label">Title</label>
                            <input type="text" name="title" class="form-control" required>
                        </div>
                        <div class="mb-3">
                            <label for="body" class="form-label">Body</label>
                            <textarea name="body" class="form-control" required></textarea>
                        </div>
                        <button type="submit" class="btn btn-primary">Submit</button>
                    </form>
                </div>
            </div>
        </div>
    </div>

    <script>
        $('#ajax-form').submit(function(e) {
            e.preventDefault();
            let formData = new FormData(this);

            $.ajax({
                type: 'POST',
                url: $(this).attr('action'),
                data: formData,
                contentType: false,
                processData: false,
                success: (response) => {
                    alert('Post created successfully!');
                    location.reload();
                },
                error: function(response) {
                    $('.print-error-msg').find('ul').html('');
                    $('.print-error-msg').css('display', 'block');
                    $.each(response.responseJSON.errors, function(key, value) {
                        $('.print-error-msg').find('ul').append('<li>' + value + '</li>');
                    });
                }
            });
        });
    </script>
</body>
</html>

Run the Application

Start the Laravel development server:

php artisan serve

Visit http://localhost:8000/posts in your browser to see the application in action. You can now add new posts using the Bootstrap modal without refreshing the page!

Output:

laravel 12 ajax page

I hope it can help you...

Do you Like?