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! 😊

LIVE MENTORSHIP ONLY 5 SPOTS

Laravel Mastery
Coaching Class Program

KritiMyantra

Transform from beginner to Laravel expert with our personalized Coaching Class starting June 21, 2025. Limited enrollment ensures focused attention.

Daily Sessions

1-hour personalized coaching

Real Projects

Build portfolio applications

Best Practices

Industry-standard techniques

Career Support

Interview prep & job guidance

Total Investment
$200
Duration
30 hours
1h/day

Enrollment Closes In

Days
Hours
Minutes
Seconds
Spots Available 5 of 10 remaining
Next cohort starts:
June 21, 2025

Join the Program

Complete your application to secure your spot

Application Submitted!

Thank you for your interest in our Laravel mentorship program. We'll contact you within 24 hours with next steps.

What happens next?

  • Confirmation email with program details
  • WhatsApp message from our team
  • Onboarding call to discuss your goals

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