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