How to Create a CRUD Application Using Ajax in Laravel 9

 

តម្រូវការមុនតម្លើង

Before creating the Laravel 9 application, please make sure of the below configuration.

  • PHP >=8.0.2
  • Composer
  • Apache/Nginx Server
  • VS Code Editor (Optional)
  • MySQL (version > 5)

បង្កើត App Laravel 9 Ajax CRUD

This step is not recommended if you already have the project setup. If not then create the application using the below command.

composer create-project --prefer-dist laravel/laravel blog

Let the installation finish and then we will move to the next step.

កំណត់ Database សម្រាប់ Laravel 9 Application

Create a database and navigate to the root of the project directory. Find the .env file and configure the database as shown below. Replace your credentials in the database option.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=DATABASE_NAME
DB_USERNAME=DATABASE_USERNAME
DB_PASSWORD=DATABASE_PASSWORD

Next, you have to create a model, a migration, and a controller.


php artisan make:model Post -mcr

After creating the files, let’s start with the migration file. Open the migration and add the below snippets.

timestamp_create_posts_table.php
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('posts', function (Blueprint $table) { $table->id(); $table->string('title')->nullable(); $table->text('description')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('posts'); } };

We have added a few fields to the table. Now, run the migration to have a table.

php artisan migrate

Next, you have to add the mass assignment to the Model.

បន្ថែម Mass Assignment ក្នុង​Laravel 9 Model

Navigate to the model and add the fillable property as shown below.

Post.php
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Post extends Model { use HasFactory; protected $fillable = [ 'title', 'description' ]; }


That’s it for this. Now, move to the controller for implementing the functionalities.

Laravel 9 Ajax CRUD Functionality

For Ajax CRUD operations, you will have to add the CRUD functionality to the controller. Therefore add the below code.

PostController.php
<?php namespace App\Http\Controllers; use App\Models\Post; use Illuminate\Http\Request; class PostController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $posts = Post::orderBy('id', 'desc')->get(); return view('posts.index', compact('posts')); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $post = Post::updateOrCreate( [ 'id' => $request->postId ], [ 'title' => $request->title, 'description' => $request->description ] ); if ($post) { return response()->json(['status' => 'success', 'data' => $post]); } return response()->json(['status' => 'failed', 'message' => 'Failed! Post not created']); } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show(Post $post) { if ($post) { return response()->json(['status' => 'success', 'data' => $post]); } return response()->json(['status' => 'failed', 'message' => 'No post found']); } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy(Post $post) { $post->delete(); return response()->json(['status' => 'success', 'data' => $post]); } }

Respectively you will need to add the routes.

បន្ថែមRoutes សម្រាប់​Laravel 9 Ajax CRUD


Navigate to the web.php and add the below routes.

web.php
<?php use App\Http\Controllers\PostController; use Illuminate\Support\Facades\Route; Route::resource('posts', PostController::class);

Next, you have to create the views for data and form handling.

បង្កើត​Views For Ajax CRUD

Create the following blade file inside the views folder.

  • master.blade.php
  • index.blade.php


After creating the blades file, let’s start by adding the master layout in the master.blade.php file.

master.blade.php
<!doctype html> <html lang="en"> <head> <title>Laravel 9 CRUD Application @yield('title')</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <meta name="csrf-token" content="{{ csrf_token() }}"/> <style> .error { color: #ca0505; } </style> </head> <body> <div class="container py-5"> @yield('content') </div> <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.3/jquery.validate.min.js" integrity="sha512-37T7leoNS06R80c8Ulq7cdCDU5MNQBwlYoy1TX/WUsLFC2eYNqtKlV0QjH7r8JpG/S0GUMZwebnVFLPd6SU5yg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="{{ asset('assets/js/script.js') }}"></script> </body> </html>

In the footer, I have added a script for AJAX handling. So, for that, I have created a separate file with the name script.js inside the public folder.

index.blade.php
@extends('posts.master') @section('content') @section('title') | Posts Listing @endsection <div class="row"> <div class="col-xl-9 col-lg-9 col-md-9 col-12"> <h3 class="text-center"> Laravel 9 Ajax CRUD </h3> </div> <div class="col-xl-3 col-lg-3 col-md-3 col-sm-12 text-end"> <a href="javascript:void(0)" id="create-post-btn" class="btn btn-primary"> Create Post </a> </div> </div> <div class="card my-3"> <table class="table" id="postsTable"> <thead> <tr> <th width="10%">Id</th> <th width="20%">Title</th> <th width="30%">Description</th> <th width="20%">Action</th> <tr> </thead> <tbody> @forelse ($posts as $post) <tr id="post_{{$post->id}}"> <td>{{ $post->id }}</td> <td>{{ $post->title }}</td> <td>{{ $post->description }}</td> <td> <a href="javascript:void(0)" data-id="{{$post->id}}" title="View" class="btn btn-sm btn-info btn-view"> View </a> <a href="javascript:void(0)" data-id="{{$post->id}}" title="Edit" class="btn btn-sm btn-success btn-edit"> Edit </a> <a href="javascript:void(0)" data-id="{{$post->id}}" title="Delete" class="btn btn-sm btn-danger btn-delete"> Delete </a> </td> </tr> @empty <tr> <td colspan="4"> <p class="text-danger text-center"> No post found! </p> </td> </tr> @endforelse </tbody> </table> </div> <!-- modal --> <div class="modal fade" id="postModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content "> <form method="post" id="postForm"> <div class="modal-header"> <h5 class="modal-title" id="modalTitle"> AJAX CRUD Application</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <div class="mb-3"> <label for="title" class="form-label">Title</label> <input type="text" name="title" class="form-control" id="title" placeholder="Post Title"> </div> <div class="mb-3"> <label for="description" class="form-label">Body</label> <textarea class="form-control" name="description" placeholder="Description" id="description" rows="3"></textarea> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="submit" class="btn btn-primary">Save</button> </div> </form> </div> </div> </div> @endsection

Add the below snippet in the script.js file.

script.js
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); $(document).ready(function () { // create post $('#create-post-btn').click(function() { $('.error').remove(); $('#postId').remove(); $('#postModal #modalTitle').text('Create Post'); $('#postForm')[0].reset(); $('#postModal').modal('toggle'); }); // form validate and submit $('#postForm').validate({ rules: { title: 'required', description: 'required', }, messages: { title: 'Please enter the title', description: 'Please enter the description', }, submitHandler: function(form) { const id = $('input[name=postId]').val(); const formData = $(form).serializeArray(); $.ajax({ url: 'posts', type: 'POST', data: formData, success: function(response) { if (response && response.status === 'success') { // clear form $('#postForm')[0].reset(); // toggle modal $('#postModal').modal('toggle'); $('#postsTable p').empty(); const data = response.data; if (id) { $("#post_"+id+" td:nth-child(2)").html(data.title); $("#post_"+id+" td:nth-child(3)").html(data.description); } else { $('#postsTable').prepend(`<tr id=${'post_'+data.id}><td>${data.id}</td><td>${data.title}</td><td>${data.description}</td><td> <a href="javascript:void(0)" data-id=${data.id} title="View" class="btn btn-sm btn-info btn-view"> View </a> <a href="javascript:void(0)" data-id=${data.id} title="Edit" class="btn btn-sm btn-success btn-edit"> Edit </a> <a href="javascript:void(0)" data-id=${data.id} title="Delete" class="btn btn-sm btn-danger btn-delete"> Delete </a></td></tr>`); } } } }); } }) }); // view button click $('.btn-view').click(function() { const id = $(this).data('id'); $('label.error').remove(); $('input[name=title]').removeClass('error'); $('textarea[name=description]').removeClass('error'); $('input[name=title]').attr('disabled', 'disabled'); $('textarea[name=description]').attr('disabled', 'disabled'); $('#postModal button[type=submit]').addClass('d-none'); $.ajax({ url: `posts/${id}`, type: 'GET', success: function(response) { if (response && response.status === 'success') { const data = response.data; $('#postModal #modalTitle').text('Post Detail'); $('#postModal input[name=title]').val(data.title); $('#postModal textarea[name=description]').val(data.description); $('#postModal').modal('toggle'); } } }) }); // edit button click $('.btn-edit').click(function() { const id = $(this).data('id'); $('label.error').remove(); $('input[name=title]').removeClass('error'); $('input[name=title]').after('<input type="hidden" name="postId" value="'+id+'" />') $('textarea[name=description]').removeClass('error'); $('input[name=title]').removeAttr('disabled'); $('textarea[name=description]').removeAttr('disabled'); $('#postModal button[type=submit]').removeClass('d-none'); $.ajax({ url: `posts/${id}`, type: 'GET', success: function(response) { if (response && response.status === 'success') { const data = response.data; $('#postModal #modalTitle').text('Update Post'); $('#postModal input[name=title]').val(data.title); $('#postModal textarea[name=description]').val(data.description); $('#postModal').modal('toggle'); } } }) }); // delete button click $('.btn-delete').click(function() { const id = $(this).data('id'); if (id) { const result = window.confirm('Do you want to delete?'); if (result) { $.ajax({ url: `posts/${id}`, type: 'DELETE', success: function(response) { if (response && response.status === 'success') { const data = response.data; $(`#post_${data.id}`).remove(); } } }); } else { console.log('error', 'Post not found'); } } });


Conclusion

We covered the Ajax form handling in Laravel 9. We created a demo app for the blog using the CRUD operations. I hope you will find helpful to this post.



អត្ថបទបន្ទាប់ អត្ថបទមុន