Laravel 11 Ajax CRUD Example Tutorial

Laravel 11 Ajax CRUD Example Tutorial

Hello and welcome dev; In this tutorial guide, we will teach you how to make Laravel 11 AJAX CRUD operation application with a popup modal and validation.

In this tutorial guide, we will build Ajax blog post crud operation example application using DataTables js, jQuery ajax and bootstrap popup modal without refreshing web page

Steps on Laravel 11 Ajax Crud with Popup Modal Example

 Here are steps:

Step 1 – Download New Laravel Application

Run composer create-project --prefer-dist laravel/laravel AjaxCrudApp command on cmd or terminal window to download and set up new laravel 11 application into your system:

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

Step 2 – Configure Database with Application

Open .env file from the laravel application root folder, and then add your database details in it, like the following:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_db_name
DB_USERNAME=your_db_user
DB_PASSWORD=your_db_pass

Step 3 – Install and Setup Yajra Datatables

Run the composer require yajra/laravel-datatables-oracle command on cmd to install yajra dataTables into your laravel project:

cd AjaxCrudApp
composer require yajra/laravel-datatables-oracle

Step 4 – Create Model & Migration File

Run the php artisan make:model Blog -m command to create model and migration file:

php artisan make:model Blog -m

To create_blogs_table.php file in /database/migrations/ folder, and add the following line in up() function:

   public function up(): void
    {
        Schema::create('blogs', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('detail');
            $table->timestamps();
        });
    }

Next open your Blog.php model file from app/models folder and add filable property in it; something like this:

   protected $fillable = [
        'title',
        'detail'
    ];

Run php artisan migrate command on cmd to create tables in the configured database with application:

php artisan migrate

Step 5 – Define Ajax Routes

Open web.php file from routes folder, and make the routes in it to handle Ajax requests on controller; like the following:

use App\Http\Controllers\BlogCRUDController;

Route::get('blog-list', [BlogCRUDController::class, 'index']);
Route::post('store-blog', [BlogCRUDController::class, 'store']);
Route::post('edit-blog', [BlogCRUDController::class, 'edit']);
Route::post('delete-blog', [BlogCRUDController::class, 'destroy']);

Step 6 – Create CRUD AJAX Controller

Run php artisan make:controller BlogCRUDController command on cmd to create controller file, which handle crud operation from database:

php artisan make:controller BlogCRUDController

Open BlogCRUDController.php file from app/http/controllers folder, create some methods in it to perform crud (create, read, update and delete) from database; like the following:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Models\Blog;

use Datatables;

class BlogCRUDController extends Controller
{
	/**
	 * Display a listing of the resource.
	 *
	 * @return \Illuminate\Http\Response
	 */
	public function index()
	{
	    if(request()->ajax()) {
	        return datatables()->of(Blog::select('*'))
	        ->addColumn('action', 'blog-action')
	        ->rawColumns(['action'])
	        ->addIndexColumn()
	        ->make(true);
	    }
	    return view('blogs');
	}
	 
	 
	/**
	 * Store a newly created resource in storage.
	 *
	 * @param  \Illuminate\Http\Request  $request
	 * @return \Illuminate\Http\Response
	 */
	public function store(Request $request)
	{  

	    $blog_id = $request->id;

	    $blog   =   Blog::updateOrCreate(
	    	        [
	    	         'id' => $blog_id
	    	        ],
	                [
	                'title' => $request->title, 
	                'detail' => $request->detail
	                ]);    
	                    
	    return Response()->json($blog);

	}
	 
	 
	/**
	 * Show the form for editing the specified resource.
	 *
	 * @param  \App\blog  $blog
	 * @return \Illuminate\Http\Response
	 */
	public function edit(Request $request)
	{   
	    $where = array('id' => $request->id);
	    $blog  = Blog::where($where)->first();
	 
	    return Response()->json($blog);
	}
	 
	 
	/**
	 * Remove the specified resource from storage.
	 *
	 * @param  \App\blog  $blog
	 * @return \Illuminate\Http\Response
	 */
	public function destroy(Request $request)
	{
	    $blog = Blog::where('id',$request->id)->delete();
	 
	    return Response()->json($blog);
	}
}

Step 7 – Create Blade Views File

Now go to resources/views folder and create blogs.blade.php and blog-action.blade.php in it to show list of records with add, edit and delete blog button:

Now, open blogs.blade.php and add the following code into it; like the following:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Laravel 11 Ajax CRUD Operation Example Tutorial - Tutsmake.com</title>
    

    <meta name="csrf-token" content="{{ csrf_token() }}">
    
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>

    <script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
    
    <link  href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css" rel="stylesheet">

    <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>

</head>
<body>

<div class="container" style="
    margin: 60px;
    padding: 22px;
">

<div class="row">
        <div class="col-lg-12 margin-tb">
            <div class="pull-left mt-1 mb-1" style="
    text-align: center;
    border: 15px solid yellow;">
                <h2>Laravel 11 Ajax CRUD Operation Example Tutorial - Tutsmake.com</h2>
            </div>
            <div class="pull-right mb-2 mt-1">
                <a class="btn btn-success" onClick="add()" href="javascript:void(0)"> Add Blog Post</a>
            </div>
        </div>
    </div>
   
    @if ($message = Session::get('success'))
        <div class="alert alert-success">
            <p>{{ $message }}</p>
        </div>
    @endif

    <div class="card-body">

        <table class="table table-bordered" id="blogs">
           <thead>
              <tr>
                 <th>Id</th>
                 <th>Title</th>
                 <th>Detail</th>
                 <th>Created at</th>
                 <th>Action</th>
              </tr>
           </thead>
        </table>

    </div>
   
</div>
  <!-- boostrap blog model -->
    <div class="modal fade" id="blog-modal" aria-hidden="true">
      <div class="modal-dialog modal-lg">
        <div class="modal-content">
          <div class="modal-header">
            <h4 class="modal-title" id="BlogModal"></h4>
          </div>
          <div class="modal-body">
            <form action="javascript:void(0)" id="blogForm" name="blogForm" class="form-horizontal" method="POST" enctype="multipart/form-data">
              <input type="hidden" name="id" id="id">
              <div class="form-group">
                <label for="name" class="col-sm-2 control-label">Title</label>
                <div class="col-sm-12">
                  <input type="text" class="form-control" id="title" name="title" placeholder="Enter title" maxlength="50" required="">
                </div>
              </div>  

              <div class="form-group">
                <label class="col-sm-2 control-label">Detail</label>
                <div class="col-sm-12">
                  <input type="text" class="form-control" id="detail" name="detail" placeholder="Enter Detail" required="">
                </div>
              </div>

              <div class="col-sm-offset-2 col-sm-10">
                <button type="submit" class="btn btn-primary" id="btn-save">Save changes
                </button>
              </div>
            </form>
          </div>
          <div class="modal-footer">
            
          </div>
        </div>
      </div>
    </div>
<!-- end bootstrap model -->

</body>


</html>

To create popup modal and some functions using jQuery AJAX with Bootstrap in blogs.blade.php file to perform ajax crud operation without page refresh; something like this:

  <!-- boostrap blog model -->
    <div class="modal fade" id="blog-modal" aria-hidden="true">
      <div class="modal-dialog modal-lg">
        <div class="modal-content">
          <div class="modal-header">
            <h4 class="modal-title" id="BlogModal"></h4>
          </div>
          <div class="modal-body">
            <form action="javascript:void(0)" id="blogForm" name="blogForm" class="form-horizontal" method="POST" enctype="multipart/form-data">
              <input type="hidden" name="id" id="id">
              <div class="form-group">
                <label for="name" class="col-sm-2 control-label">Title</label>
                <div class="col-sm-12">
                  <input type="text" class="form-control" id="title" name="title" placeholder="Enter title" maxlength="50" required="">
                </div>
              </div>  

              <div class="form-group">
                <label class="col-sm-2 control-label">Detail</label>
                <div class="col-sm-12">
                  <input type="text" class="form-control" id="detail" name="detail" placeholder="Enter Detail" required="">
                </div>
              </div>

              <div class="col-sm-offset-2 col-sm-10">
                <button type="submit" class="btn btn-primary" id="btn-save">Save changes
                </button>
              </div>
            </form>
          </div>
          <div class="modal-footer">
            
          </div>
        </div>
      </div>
    </div>
<!-- end bootstrap model -->

</body>
<script type="text/javascript">
     
 $(document).ready( function () {

  $.ajaxSetup({
    headers: {
    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
  });
    $('#blogs').DataTable({
           processing: true,
           serverSide: true,
           ajax: "{{ url('blog-list') }}",
           columns: [
                    { data: 'id', name: 'id' },
                    { data: 'title', name: 'title' },
                    { data: 'detail', name: 'detail' },
                    { data: 'created_at', name: 'created_at' },
                    {data: 'action', name: 'action', orderable: false},
                 ],
                 order: [[0, 'desc']]
       });

  });
  
  function add(){

       $('#blogForm').trigger("reset");
       $('#BlogModal').html("Add Blog");
       $('#blog-modal').modal('show');
       $('#id').val('');

  }   
  function editFunc(id){
    
    $.ajax({
        type:"POST",
        url: "{{ url('edit-blog') }}",
        data: { id: id },
        dataType: 'json',
        success: function(res){
          $('#BlogModal').html("Edit Blog");
          $('#blog-modal').modal('show');
          $('#id').val(res.id);
          $('#title').val(res.title);
          $('#detail').val(res.detail);
       }
    });
  }  

  function deleteFunc(id){
        if (confirm("Delete Record?") == true) {
        var id = id;
         
          // ajax
          $.ajax({
              type:"POST",
              url: "{{ url('delete-blog') }}",
              data: { id: id },
              dataType: 'json',
              success: function(res){

                var oTable = $('#blogs').dataTable();
                oTable.fnDraw(false);
             }
          });
       }
  }

  $('#blogForm').submit(function(e) {

     e.preventDefault();
  
     var formData = new FormData(this);
  
     $.ajax({
        type:'POST',
        url: "{{ url('store-blog')}}",
        data: formData,
        cache:false,
        contentType: false,
        processData: false,
        success: (data) => {
          $("#blog-modal").modal('hide');
          var oTable = $('#blogs').dataTable();
          oTable.fnDraw(false);
          $("#btn-save").html('Submit');
          $("#btn-save"). attr("disabled", false);
        },
        error: function(data){
           console.log(data);
         }
       });
   });

</script>

To create edit and delete blog posts button on list in blog-action.blade.php; something like this:

<a href="javascript:void(0)" data-toggle="tooltip" onClick="editFunc({{ $id }})" data-original-title="Edit" class="edit btn btn-success edit">
	Edit
</a>
<a href="javascript:void(0);" id="delete-compnay" onClick="deleteFunc({{ $id }})" data-toggle="tooltip" data-original-title="Delete" class="delete btn btn-danger">
	Delete
</a>

Step 8 – Run and Test Application

Run php artisan serve command on cmd to start application server:

php artisan serve

Open your browser and type http://127.0.0.1:8000/blog-list URL into it to test ajax crud application:

http://127.0.0.1:8000/blog-list

Conclusion

We hope with the help of this example tutorial guide you have learned how to create Laravel 11 Ajax CRUD with Popup Modal using jQuery AJAX, DataTable js and Bootstrap without refreshing page.

Here are some new guides related to Laravel 11; You must check it out:

AuthorAdmin

Greetings, I'm Devendra Dode, a full-stack developer, entrepreneur, and the proud owner of Tutsmake.com. My passion lies in crafting informative tutorials and offering valuable tips to assist fellow developers on their coding journey. Within my content, I cover a spectrum of technologies, including PHP, Python, JavaScript, jQuery, Laravel, Livewire, CodeIgniter, Node.js, Express.js, Vue.js, Angular.js, React.js, MySQL, MongoDB, REST APIs, Windows, XAMPP, Linux, Ubuntu, Amazon AWS, Composer, SEO, WordPress, SSL, and Bootstrap. Whether you're starting out or looking for advanced examples, I provide step-by-step guides and practical demonstrations to make your learning experience seamless. Let's explore the diverse realms of coding together.

Leave a Reply

Your email address will not be published. Required fields are marked *