laravel crud with Yajra Datatable ajax

The provided code is a Laravel CRUD (Create, Read, Update, Delete) application using DataTables and AJAX. It allows you to perform CRUD operations on a "Service" model. Here's an overview of the code:

1. php artisan make:model Service -mrc
-m, --migration Create a new migration file for the model.
-c, --controller Create a new controller for the model.
-r, --resource Indicates if the generated controller should be a resource controller

2. The migration file (2022_07_26_002457_create_services_table.php) creates a table named "services" with an "id" column, a "name" column, and the default "timestamps" columns.

database\migrations\2022_07_26_002457_create_services_table.php


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

3. The Service model (Service.php) defines the attributes that are mass assignable and uses the HasFactory trait.

app\Models\Service.php


<?php
namespace App\Models;
use App\Helper\StorageSetup;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Service extends Model
{
   use HasFactory;
   /**
    * The attributes that are mass assignable.
    *
    * @var string[]
    */
   protected $fillable = [
       'name',
   ];
}

3. The route file sets up a resourceful route for the "services" endpoint under the "admin" prefix.

Route::group(['prefix' => 'admin', 'as' => 'admin.'], function () {
   Route::resource('services', 'Admin\ServiceController');
});

5. The ServiceController handles the logic for CRUD operations. Notable methods include:

app\Http\Controllers\Admin\ServiceController.php


<?php
namespace App\Http\Controllers\Admin;
use App\Models\Service;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\View;
use DataTables;
class ServiceController extends Controller
{
   public function __construct()
   {
       // Sharing is caring
       View::share('view_data', [
           'view_path' => 'admin.services.',
           'route_prefix' => 'admin.services.',
           'crud_name_1' => 'Service',
           'crud_name_2' => 'Services',
       ]);
   }
   /**
    * Display a listing of the resource.
    *
    * @return \Illuminate\Http\Response
    */
   public function index(Request $request)
   {
       if (!$request->ajax()){
           return view('admin.services.index');
       }
       $data = Service::select('*');
       return Datatables::of($data)
       ->addIndexColumn()
       ->addColumn('action', function($row){
           $btn_data = ['edit'=>true, 'show'=>true, 'delete'=> true, 'route_prefix'=>'admin.services'];
           return view('admin.include.datatable.datatables_btn',compact('row', 'btn_data'))->render();
       })
       ->rawColumns(['action'])
       ->make(true);
   }
   /**
    * Show the form for creating a new resource.
    *
    * @return \Illuminate\Http\Response
    */
   public function create()
   {
       return view('admin.services.create');
   }
   /**
    * Store a newly created resource in storage.
    *
    * @param  \Illuminate\Http\Request  $request
    * @return \Illuminate\Http\Response
    */
   public function store(Request $request)
   {
       $this->validate($request, [
           'name' => 'required|string|max:255',
       ]);
       $service = Service::create($request->only('name'));
       return redirect()->back()->with('success','Record Saved Successfully');
   }
   /**
    * Display the specified resource.
    *
    * @param  int  $id
    * @return \Illuminate\Http\Response
    */
   public function show($id)
   {
       $data = Service::findOrFail($id);
       return view('admin.services.show',compact('data'));
   }

   /**
    * Show the form for editing the specified resource.
    *
    * @param  int  $id
    * @return \Illuminate\Http\Response
    */
   public function edit($id)
   {
       $data = Service::findOrFail($id);
       return view('admin.services.edit',compact('data'));
   }

   /**
    * Update the specified resource in storage.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  int  $id
    * @return \Illuminate\Http\Response
    */
   public function update(Request $request, $id)
   {
       $this->validate($request, [
           'name' => 'required|string|max:255',
       ]);
       $service = Service::findOrFail($id);
       $service->update($request->only(['name']));
       return redirect()->route('admin.services.index')->with('success','Record Updated Successfully');
   }

   /**
    * Remove the specified resource from storage.
    *
    * @param  int  $id
    * @return \Illuminate\Http\Response
    */
   public function destroy($id)
   {
       $data = Service::findOrFail($id)->delete();
       if ($data) {
           return redirect()->route("admin.services.index")->with('success', 'Record removed Successfully');
       }
       return back()->with('error', 'Something Went Wrong');
   }
}

6. The datatables_btn.blade.php partial is used to render action buttons (edit, show, delete) for each row in the DataTable.

resources\views\admin\include\datatable\datatables_btn.blade.php


@if ($btn_data['edit'])
   <a class="btn-sm btn-icon btn btn-primary" href="{{ route($btn_data['route_prefix'].'.edit',$row->id) }}">
       Edit
   </a>
@endif
@if ($btn_data['show'])
   <a class="btn-sm btn-icon btn btn-info" href="{{ route($btn_data['route_prefix'].'.show',$row->id) }}">
       Show
   </a>
@endif
@if ($btn_data['delete'])
   <a class="btn-sm btn-icon btn btn-danger" href="#;" onclick="$(this).find('form').submit();">
       Delete
       <form onSubmit="return confirm('Are you sure want to delete this ?');return false;" action="{{ route($btn_data['route_prefix'].'.destroy', $row->id) }}" method="POST" name="delete_item" style="display:none">
           @csrf
           {{method_field('DELETE')}}
       </form>
   </a>
@endif
6. The create.blade.php view displays a form to create a new service record.
resources\views\admin\services\_form.blade.php
<div class="row">
   <div class="col-md-10 m-auto">
       <div class="mb-3 row">
           <label class="form-label col-md-4">Name</label>
           <div class="col-md-8">
               {!! Form::text('name', null, ['placeholder' => 'Name', 'class' => 'form-control']) !!}
               @if ($errors->has('name'))
                   <label class="text-danger">{{ $errors->first('name') }}</label>
               @endif
           </div>
       </div>
       <div class="mb-3 row">
           <div class="col-md-4"></div>
           <div class="col-md-8">
               <button type="submit" class="btn-sm btn btn-primary">
                   <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-device-floppy" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                       <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
                       <path d="M6 4h10l4 4v10a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2" />
                       <circle cx="12" cy="14" r="2" />
                       <polyline points="14 4 14 8 8 8 8 4" />
                   </svg>
                   Save
               </button>
           </div>
       </div>
   </div>
</div>

7. The edit.blade.php view displays a form to edit an existing service record.
resources\views\admin\services\create.blade.php

@extends('admin.layouts.admin')
@section('content')
<div class="container-xl">
   <!-- Page title -->
   <div class="page-header d-print-none">
       <div class="row align-items-center">
           <div class="col">
               <!-- Page pre-title -->
               <h2 class="page-title">
                   Add New {{$view_data['crud_name_1']}}
               </h2>
           </div>
           <div class="col-auto ms-auto d-print-none">
               <div class="btn-list">
                   <a href="{{ route($view_data['route_prefix'].'index') }}" class="btn-sm btn btn-primary">
                       <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-arrow-left" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                           <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
                           <line x1="5" y1="12" x2="19" y2="12" />
                           <line x1="5" y1="12" x2="11" y2="18" />
                           <line x1="5" y1="12" x2="11" y2="6" />
                       </svg>
                       Back
                   </a>
               </div>
           </div>
       </div>
   </div>
</div>
<div class="page-body">
   <div class="container-xl">
       <div class="row row-deck row-cards">
           <div class="col-12">
               <div class="card" style="padding: 18px;">
                   {!! Form::open(['route' => [$view_data['route_prefix'].'store'],'method' => 'post', 'enctype' => 'multipart/form-data',]) !!}
                   @include($view_data['view_path'].'_form')
                   {!! Form::close() !!}
               </div>
           </div>
       </div>
   </div>
</div>
@endsection

8. The index.blade.php view displays a table using DataTables to list all service records. It includes a "Add New Service" button and uses the data-table class for DataTables initialization.

resources\views\admin\services\edit.blade.php


@extends('admin.layouts.admin')
@section('content')
<div class="container-xl">
   <!-- Page title -->
   <div class="page-header d-print-none">
       <div class="row align-items-center">
           <div class="col">
               <!-- Page pre-title -->
               <h2 class="page-title">
                   {{$view_data['crud_name_2']}} edit
               </h2>
           </div>
           <div class="col-auto ms-auto d-print-none">
               <div class="btn-list">
                   <a href="{{ route($view_data['route_prefix'].'index') }}" class="btn-sm btn btn-primary">
                       <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-arrow-left" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
                           <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
                           <line x1="5" y1="12" x2="19" y2="12" />
                           <line x1="5" y1="12" x2="11" y2="18" />
                           <line x1="5" y1="12" x2="11" y2="6" />
                       </svg>
                       Back
                   </a>
               </div>
           </div>
       </div>
   </div>
</div>
<div class="page-body">
   <div class="container-xl">
       <div class="row row-deck row-cards">
           <div class="col-12">
               <div class="card" style="padding: 18px;">
                   {!! Form::model($data,['route' => [$view_data['route_prefix'].'update', $data->id],'method' => 'patch', 'enctype' => 'multipart/form-data',]) !!}
                   @include($view_data['view_path'].'_form')
                   {!! Form::close() !!}
               </div>
           </div>
       </div>
   </div>
</div>
@endsection

9. The header and footer sections in the views include relevant CSS and JavaScript dependencies for DataTables.
resources\views\admin\services\index.blade.php

@extends('admin.layouts.admin')
@section('header')
   <link href="https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css" rel="stylesheet">
@endsection
@section('content')
   <div class="container-xl">
       <!-- Page title -->
       <div class="page-header d-print-none">
           <div class="row align-items-center">
               <div class="col">
                   <!-- Page pre-title -->
                   <h2 class="page-title">
                       {{ $view_data['crud_name_2'] }} List
                   </h2>
               </div>
               <div class="col-auto ms-auto d-print-none">
                   <div class="btn-list">
                       <a href="{{ route($view_data['route_prefix'] . 'create') }}" class="btn-sm btn btn-primary">
                           <svg xmlns="http://www.w3.org/2000/svg" class="icon" width="24" height="24"
                               viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none"
                               stroke-linecap="round" stroke-linejoin="round">
                               <path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
                               <line x1="12" y1="5" x2="12" y2="19"></line>
                               <line x1="5" y1="12" x2="19" y2="12"></line>
                           </svg>
                           Add New {{ $view_data['crud_name_1'] }}
                       </a>
                   </div>
               </div>
           </div>
       </div>
   </div>
   <div class="page-body">
       <div class="container-xl">
           <div class="row row-deck row-cards">
               <div class="col-12">
                   <div class="card" style="padding: 18px;">
                       <table class="table data-table">
                           <thead>
                               <tr>
                                   <th>#id</th>
                                   <th>Name</th>
                                   <th>Created On</th>
                                   <th style="width: 156px;">Action</th>
                               </tr>
                           </thead>
                       </table>
                   </div>
               </div>
           </div>
       </div>
   </div>
@endsection
@section('footer')
   <script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
   <script src="https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js"></script>
   <script type="text/javascript">
       $(function() {
           var table = $('.data-table').DataTable({
               order: [
                   [0, "DESC"]
               ],
               processing: true,
               serverSide: true,
               ajax: "{{ route($view_data['route_prefix'] . 'index') }}",
               columns: [
                   {data: 'id',name: 'id'},
                   {data: 'name',name: 'name'},
                   {data: 'created_at',name: 'created_at'},
                   {data: 'action',name: 'action',orderable: false,searchable: false},
               ]
           });
       });
   </script>
@endsection

resources\views\admin\services\show.blade.php


@extends('admin.layouts.admin')
@section('content')
<div class="container-xl">
   <!-- Page title -->
   <div class="page-header d-print-none">
       <div class="row align-items-center">
           <div class="col">
               <h2 class="page-title">
                   {{ $view_data['crud_name_1'] }} Show
               </h2>
           </div>
           <div class="col-auto ms-auto d-print-none">
               <div class="btn-list">
                   <a href="{{ route($view_data['route_prefix'] . 'index') }}" class="btn-sm btn btn-primary">
                       <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-arrow-left"
                           width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor"
                           fill="none" stroke-linecap="round" stroke-linejoin="round">
                           <path stroke="none" d="M0 0h24v24H0z" fill="none" />
                           <line x1="5" y1="12" x2="19" y2="12" />
                           <line x1="5" y1="12" x2="11" y2="18" />
                           <line x1="5" y1="12" x2="11" y2="6" />
                       </svg>
                       Back
                   </a>
               </div>
           </div>
       </div>
   </div>
</div>
<div class="page-body">
   <div class="container-xl">
       <div class="row row-deck row-cards">
           <div class="col-12">
               <div class="card" style="padding: 18px;">
                   <div align="center" class="whitebox mtop15">
                       <table cellspacing="0" cellpadding="7" border="0" align="center">
                           <tr>
                               <td align="left"><strong class="upper">Name:</strong></td>
                               <td align="left">
                                   {{ $data->name }}
                               </td>
                           </tr>
                       </table>
                   </div>
               </div>
           </div>
       </div>
   </div>
</div>
@endsection

Overall, this code provides a basic implementation of a Laravel CRUD application with DataTables and AJAX for improved data handling and interactivity.

Leave A Comment