Building a Simple AJAX CRUD Application in Laravel: Add, Edit, Delete, and List

Simple AJAX CRUD Application in Laravel: Add, Edit, Delete, and List

Loading

In modern web applications, CRUD operations CRUD operationsβ€”Create, Read, Update, and Deleteβ€”are fundamental features. With Laravel, developing these functionalities is straightforward, In this blog we walk through the manner of building a simple AJAX-based totally CRUD software in Laravel. We will cover everything from putting in database to the Laravel challenge to writing the code for AJAX-primarily based operations.

Ajax Methods with Laravel Crud

AJAX (Asynchronous JavaScript and XML) allows you to send and receive data from a server asynchronously, without refreshing the page. This leads to a smoother user experience, as users can interact with the application while data is being processed in the background. In this tutorial, we’ll demonstrate how to implement AJAX-based CRUD operations in a Laravel application.

Setting Up the Laravel Project

First, ensure you have Composer installed on your system. Then, create a new Laravel project using the following command:

composer create-project --prefer-dist laravel/laravel ajax-crud-app

Navigate to the project directory:

cd ajax-crud-app

Database Configuration

Open the .env file and configure your database connection settings:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=ajax_crud_db
DB_USERNAME=root
DB_PASSWORD=your_password

After setting up the database, create it in your MySQL

Creating the Model and Migration

Next, create a model along with a migration for the entity we will manage. For this example, let’s create a model called Post:

php artisan make:model Post -m

This command creates a Post model and a migration file. Open the migration file located at database/migrations and define the schema for the posts table:

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

Run the migration to create the posts table in the database:

php artisan migrate

Setting Up Routes

Open the routes/web.php file and define the necessary routes for your CRUD operations:

use App\Http\Controllers\PostController;

Route::get('/', [PostController::class, 'index'])->name('posts.index');
Route::get('/posts', [PostController::class, 'getPosts'])->name('posts.get');
Route::post('/posts', [PostController::class, 'store'])->name('posts.store');
Route::get('/posts/{id}', [PostController::class, 'edit'])->name('posts.edit');
Route::put('/posts/{id}', [PostController::class, 'update'])->name('posts.update');
Route::delete('/posts/{id}', [PostController::class, 'destroy'])->name('posts.destroy');

Creating the Controller

Next, create a PostController to handle the logic for our CRUD operations:

php artisan make:controller PostController

In the PostController, add the following methods to handle the CRUD operations:

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\Request;
use Response;

class PostController extends Controller
{
    public function index()
    {
        return view('posts.index');
    }

    public function getPosts()
    {
        $posts = Post::all();
        return response()->json($posts);
    }

    public function store(Request $request)
    {
        $post = Post::create([
            'title' => $request->title,
            'body' => $request->body,
        ]);
        
        return response()->json($post);
    }

    public function edit($id)
    {
        $post = Post::find($id);
        return response()->json($post);
    }

    public function update(Request $request, $id)
    {
        $post = Post::find($id);
        $post->update([
            'title' => $request->title,
            'body' => $request->body,
        ]);

        return response()->json($post);
    }

    public function destroy($id)
    {
        Post::destroy($id);
        return response()->json(['success' => 'Post deleted successfully.']);
    }
}

Building the Blade View

Create a Blade template to serve as the frontend for the CRUD operations. In the resources/views directory, create a file named index.blade.php:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>Laravel AJAX CRUD</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>

<div class="container mt-5">
    <h2 class="text-center">Laravel AJAX CRUD</h2>
    <div class="row">
        <div class="col-md-6">
            <form id="postForm">
                <div class="form-group">
                    <label for="title">Title:</label>
                    <input type="text" class="form-control" id="title" name="title" required>
                </div>
                <div class="form-group">
                    <label for="body">Body:</label>
                    <textarea class="form-control" id="body" name="body" required></textarea>
                </div>
                <button type="submit" id="saveBtn" class="btn btn-success">Save</button>
            </form>
        </div>
        <div class="col-md-6">
            <table class="table table-bordered">
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>Title</th>
                        <th>Body</th>
                        <th>Action</th>
                    </tr>
                </thead>
                <tbody id="postList">
                    <!-- Data will be loaded here via AJAX -->
                </tbody>
            </table>
        </div>
    </div>
</div>

<script>
    $(document).ready(function() {
        // Fetch posts
        fetchPosts();

        // Save post
        $('#postForm').on('submit', function(e) {
            e.preventDefault();
            let id = $('#post_id').val();
            let url = id ? `/posts/${id}` : '/posts';
            let type = id ? 'PUT' : 'POST';
            let formData = {
                title: $('#title').val(),
                body: $('#body').val(),
            };

            $.ajax({
                type: type,
                url: url,
                data: formData,
                dataType: 'json',
                success: function(response) {
                    $('#postForm').trigger("reset");
                    $('#saveBtn').text('Save');
                    fetchPosts();
                },
                error: function(error) {
                    console.log(error);
                }
            });
        });

        // Edit post
        $(document).on('click', '.edit-post', function() {
            let id = $(this).data('id');
            $.get(`/posts/${id}`, function(data) {
                $('#title').val(data.title);
                $('#body').val(data.body);
                $('#post_id').val(data.id);
                $('#saveBtn').text('Update');
            });
        });

        // Delete post
        $(document).on('click', '.delete-post', function() {
            let id = $(this).data('id');
            if(confirm("Are you sure want to delete this post?")) {
                $.ajax({
                    type: "DELETE",
                    url: `/posts/${id}`,
                    success: function(response) {
                        fetchPosts();
                    },
                    error: function(error) {
                        console.log(error);
                    }
                });
            }
        });

        // Fetch posts
        function fetchPosts() {
            $.ajax({
                type: "GET",
                url: "/posts",
                success: function(data) {
                    let rows = '';
                    $.each(data, function(key, post) {
                        rows += `
                            <tr>
                                <td>${post.id}</td>
                                <td>${post.title}</td>
                                <td>${post.body}</td>
                                <td>
                                    <button data-id="${post.id}" class="btn btn-primary btn-sm edit-post">Edit</button>
                                    <button data-id="${post.id}" class="btn btn-danger btn-sm delete-post">Delete</button>
                                </td>
                            </tr>
                        `;
                    });
                    $('#postList').html(rows);
                },
                error: function(error) {
                    console.log(error);
                }
            });
        }
    });
</script>

</body>
</html>

Implementing AJAX CRUD Operations

AJAX for Adding Data

When the user submits the form, the #postForm‘s submit event triggers an AJAX request to either store or update the post. This is determined by whether there is an ID present:

$('#postForm').on('submit', function(e) {
    e.preventDefault();
    let id = $('#post_id').val();
    let url = id ? `/posts/${id}` : '/posts';
    let type = id ? 'PUT' : 'POST';
    let formData = {
        title: $('#title').val(),
        body: $('#body').val(),
    };

    $.ajax({
        type: type,
        url: url,
        data: formData,
        dataType: 'json',
        success: function(response) {
            $('#postForm').trigger("reset");
            $('#saveBtn').text('Save');
            fetchPosts();
        },
        error: function(error) {
            console.log(error);
        }
    });
});

AJAX for Editing Data

When a user clicks the “Edit” button, an AJAX request is sent to fetch the post data, which is then populated into the form fields:

$(document).on('click', '.edit-post', function() {
    let id = $(this).data('id');
    $.get(`/posts/${id}`, function(data) {
        $('#title').val(data.title);
        $('#body').val(data.body);
        $('#post_id').val(data.id);
        $('#saveBtn').text('Update');
    });
});

AJAX for Deleting Data

When a user clicks the “Delete” button, an AJAX request is sent to delete the post, followed by refreshing the list of posts:

$(document).on('click', '.delete-post', function() {
    let id = $(this).data('id');
    if(confirm("Are you sure want to delete this post?")) {
        $.ajax({
            type: "DELETE",
            url: `/posts/${id}`,
            success: function(response) {
                fetchPosts();
            },
            error: function(error) {
                console.log(error);
            }
        });
    }
});

AJAX for Listing Data

The fetchPosts function sends a GET request to retrieve and display all posts:

function fetchPosts() {
    $.ajax({
        type: "GET",
        url: "/posts",
        success: function(data) {
            let rows = '';
            $.each(data, function(key, post) {
                rows += `
                    <tr>
                        <td>${post.id}</td>
                        <td>${post.title}</td>
                        <td>${post.body}</td>
                        <td>
                            <button data-id="${post.id}" class="btn btn-primary btn-sm edit-post">Edit</button>
                            <button data-id="${post.id}" class="btn btn-danger btn-sm delete-post">Delete</button>
                        </td>
                    </tr>
                `;
            });
            $('#postList').html(rows);
        },
        error: function(error) {
            console.log(error);
        }
    });
}

Testing the Application

To test your application, start the Laravel development server:

php artisan serve

Visit http://localhost:8000 to view your application. You should be able to add, edit, and delete posts without refreshing the page.

In this article, we’ve built a simple CRUD application in Laravel enhanced with AJAX. By using AJAX, we’ve improved the user experience by making our application more responsive and eliminating the need for page reloads.

About Post Author