Laravel 12 AJAX CRUD Operations: A Complete Step-by-Step Guide

Author

Kritim Yantra

Mar 26, 2025

Laravel 12 AJAX CRUD Operations: A Complete Step-by-Step Guide

Building a CRUD (Create, Read, Update, Delete) application with AJAX in Laravel 12 allows for seamless, dynamic interactions without page reloads. This guide will walk you through setting up AJAX-based CRUD operations in Laravel 12 with jQuery.


Prerequisites

Before starting, ensure you have:

  • Laravel 12 installed
  • jQuery (included via CDN or npm)
  • Basic knowledge of Laravel MVC & AJAX

Step 1: Set Up Laravel Project & Database

1.1 Create a Model & Migration

Generate a Product model and migration:

php artisan make:model Product -m

Edit the migration (database/migrations/xxxx_create_products_table.php):

public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->text('description')->nullable();
        $table->decimal('price', 8, 2);
        $table->timestamps();
    });
}

Run the migration:

php artisan migrate

Step 2: Create a Controller

Generate a controller:

php artisan make:controller ProductController --resource

Update app/Http/Controllers/ProductController.php:

<?php

namespace App\Http\Controllers;

use App\Models\Product;
use Illuminate\Http\Request;

class ProductController extends Controller
{
    // Fetch all products (for AJAX GET)
    public function index()
    {
        $products = Product::latest()->get();
        return response()->json($products);
    }

    // Store a new product (AJAX POST)
    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string',
            'price' => 'required|numeric',
        ]);

        $product = Product::create($request->all());
        return response()->json(['success' => 'Product created successfully.']);
    }

    // Update a product (AJAX PUT)
    public function update(Request $request, Product $product)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'description' => 'nullable|string',
            'price' => 'required|numeric',
        ]);

        $product->update($request->all());
        return response()->json(['success' => 'Product updated successfully.']);
    }

    // Delete a product (AJAX DELETE)
    public function destroy(Product $product)
    {
        $product->delete();
        return response()->json(['success' => 'Product deleted successfully.']);
    }
}

Step 3: Define Routes

Update routes/web.php:

use App\Http\Controllers\ProductController;

Route::get('/', function () {
    return view('products.index');
});

Route::resource('products', ProductController::class)->except(['create', 'edit', 'show']);

Step 4: Create a Blade View

Create resources/views/products/index.blade.php:

<!DOCTYPE html>
<html>
<head>
    <title>Laravel 12 AJAX CRUD</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <div class="container mt-5">
        <h1 class="mb-4">Product Management (AJAX CRUD)</h1>
        
        <!-- Add Product Form -->
        <form id="productForm">
            @csrf
            <input type="hidden" id="productId">
            <div class="mb-3">
                <input type="text" class="form-control" id="name" placeholder="Product Name" required>
            </div>
            <div class="mb-3">
                <textarea class="form-control" id="description" placeholder="Description"></textarea>
            </div>
            <div class="mb-3">
                <input type="number" step="0.01" class="form-control" id="price" placeholder="Price" required>
            </div>
            <button type="submit" class="btn btn-primary" id="saveButton">Save</button>
        </form>

        <!-- Product List -->
        <table class="table mt-4">
            <thead>
                <tr>
                    <th>Name</th>
                    <th>Description</th>
                    <th>Price</th>
                    <th>Actions</th>
                </tr>
            </thead>
            <tbody id="productTable">
                <!-- Products will be loaded here via AJAX -->
            </tbody>
        </table>
    </div>

    <script>
        $(document).ready(function() {
            // Load products on page load
            loadProducts();

            // Add or Update Product
            $('#productForm').submit(function(e) {
                e.preventDefault();
                const id = $('#productId').val();
                const url = id ? `/products/${id}` : '/products';
                const method = id ? 'PUT' : 'POST';

                $.ajax({
                    url: url,
                    method: method,
                    data: {
                        _token: $('input[name="_token"]').val(),
                        name: $('#name').val(),
                        description: $('#description').val(),
                        price: $('#price').val(),
                    },
                    success: function(response) {
                        $('#productForm').trigger("reset");
                        $('#productId').val('');
                        $('#saveButton').text('Save');
                        loadProducts();
                    },
                    error: function(xhr) {
                        console.error(xhr.responseText);
                    }
                });
            });

            // Edit Product
            $(document).on('click', '.edit-btn', function() {
                const id = $(this).data('id');
                $.get(`/products/${id}`, function(product) {
                    $('#productId').val(product.id);
                    $('#name').val(product.name);
                    $('#description').val(product.description);
                    $('#price').val(product.price);
                    $('#saveButton').text('Update');
                });
            });

            // Delete Product
            $(document).on('click', '.delete-btn', function() {
                const id = $(this).data('id');
                if (confirm('Are you sure?')) {
                    $.ajax({
                        url: `/products/${id}`,
                        method: 'DELETE',
                        data: { _token: $('input[name="_token"]').val() },
                        success: function(response) {
                            loadProducts();
                        }
                    });
                }
            });

            // Load Products via AJAX
            function loadProducts() {
                $.get('/products', function(products) {
                    let tableRows = '';
                    products.forEach(product => {
                        tableRows += `
                            <tr>
                                <td>${product.name}</td>
                                <td>${product.description || 'N/A'}</td>
                                <td>$${product.price.toFixed(2)}</td>
                                <td>
                                    <button class="btn btn-sm btn-warning edit-btn" data-id="${product.id}">Edit</button>
                                    <button class="btn btn-sm btn-danger delete-btn" data-id="${product.id}">Delete</button>
                                </td>
                            </tr>
                        `;
                    });
                    $('#productTable').html(tableRows);
                });
            }
        });
    </script>
</body>
</html>

Step 5: Test the AJAX CRUD Operations

  1. Create a Product

    • Fill the form and click Save (AJAX POST).
  2. Edit a Product

    • Click Edit, modify data, and click Update (AJAX PUT).
  3. Delete a Product

    • Click Delete (AJAX DELETE).
  4. View Products

    • The table updates dynamically without page reloads.

Key Features Implemented

Create (POST) – Add new products via AJAX
Read (GET) – Fetch and display products dynamically
Update (PUT) – Edit existing products without page reload
Delete (DELETE) – Remove products with confirmation
Form Validation – Server-side validation in Laravel
Real-time Updates – Table refreshes automatically


Conclusion

You’ve successfully built a Laravel 12 AJAX CRUD system! This approach provides a smooth, dynamic user experience without full page reloads.

Further Improvements

  • Add client-side validation (e.g., using Laravel’s @error directives).
  • Implement pagination for large datasets.
  • Use SweetAlert for better alerts.

Now you can integrate AJAX-based CRUD in your Laravel applications efficiently! 🚀

Let me know if you need any clarifications. Happy coding! 😊

Tags

Comments

No comments yet. Be the first to comment!

Please log in to post a comment:

Sign in with Google

Related Posts

Laravel 12 Multi-Auth System: Implementing Separate Admin and User Tables
Kritim Yantra Kritim Yantra
Feb 28, 2025
Laravel 12 Roles and Permissions Setup: Complete Guide
Kritim Yantra Kritim Yantra
Feb 28, 2025
Laravel 12 & AdminLTE Integration: Setup Your Stunning Admin Dashboard
Kritim Yantra Kritim Yantra
Feb 28, 2025