Laravel 10/9 ajax DataTable CRUD with image upload; Through this tutorial, i am going to show you how to make ajax crud with image upload using datatable js and bootstrap modal in Laravel 10/9 apps.
Laravel 10/9 Ajax Crud with Image Upload using DataTable Js Example
Follow the following steps to make ajax crud with image upload using dataTable js and bootstrap modal in Laravel 10/9 apps:
- Step 1 – Installing Laravel 10/9 App
- Step 2 – Configuring .evn file for Database
- Step 3 – Installing Laravel Yajra DataTables
- Step 4 – Create Model and Migration
- Step 5 – Run Migration
- Step 6 – Create Routes
- Step 7 – Creating Datatables Controller
- Step 8 – Create Action Button(delete and edit) Blade View
- Step 9 – Show Image in Datatable
- Step 10- Create DataTable Blade View
- Step 11 – Start Development Server
Step 1 – Installing Laravel 10/9 App
In step 1, open your terminal and navigate to your local web server directory using the following command:
//for windows user cd xampp/htdocs //for ubuntu user cd var/www/html
Then install laravel latest application using the following command:
composer create-project --prefer-dist laravel/laravel LaravelAjaxCRUDImageUpload
Step 2 – Configuring .evn file for Database
In step 2, open your downloaded laravel app into any text editor. Then find .env file and configure database detail like following:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=db name DB_USERNAME=db user name DB_PASSWORD=db password
Step 3 – Installing Laravel Yajra DataTables
In step 3, Navigate to your downloaded laravel directory. And then install Yajra Datatables Packages in your laravel. Open terminal and run the following command:
cd / LaravelAjaxCRUDImageUpload composer require yajra/laravel-datatables-oracle
config/app.php 'providers' => [ Yajra\Datatables\DatatablesServiceProvider::class, ], 'aliases' => [ 'Datatables' => Yajra\Datatables\Facades\Datatables::class, ]
Then publish laravel datatables vendor package by using the following command:
php artisan vendor:publish
Step 4 – Create Model and Migration
In step 4, create book model and migration file by using the following command:
php artisan make:model Book -m
The above command will create two files into your laravel ajax crud with image upload and datatable, ajax modal app, which is located inside the following locations:
Now, open Book.php model file inside LaravelAjaxCRUDImageUpload/app/Models directory. And open it then add the fillable property code into Book.php file, like following:
- /app/Models/Book.php
- /database/migrations/create_books_table.php
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Book extends Model { use HasFactory; protected $fillable = [ 'title', 'code', 'author', 'image' ]; }
Then, find create_books_table.php file inside /database/migrations/ directory. Then open this file and add the following code into function up() on this file:
public function up() { Schema::create('books', function (Blueprint $table) { $table->id(); $table->string('title'); $table->string('code'); $table->string('author'); $table->string('image'); $table->timestamps(); }); }
Step 5 – Run Migration
Now, open again your terminal and type the following command on cmd to create tables into your selected database:
php artisan migrate
Step 6 – Create Routes
In step 6, open your web.php file, which is located inside routes directory. Then add the following routes into web.php file:
use App\Http\Controllers\AjaxCRUDImageController; Route::get('ajax-crud-image-upload', [AjaxCRUDImageController::class, 'index']); Route::post('add-update-book', [AjaxCRUDImageController::class, 'store']); Route::post('edit-book', [AjaxCRUDImageController::class, 'edit']); Route::post('delete-book', [AjaxCRUDImageController::class, 'destroy']);
Step 7 – Creating Datatables Controller
In step 7, create ajax crud datatable controller by using the following command:
php artisan make:controller AjaxCRUDImageController
The above command will create AjaxCRUDImageController.php file, which is located inside /app/Http/Controllers/ directory. So add the following code into it:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Book; use Datatables; class AjaxCRUDImageController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { if(request()->ajax()) { return datatables()->of(Book::select('*')) ->addColumn('action', 'book-action') ->addColumn('image', 'show-image') ->rawColumns(['action','image']) ->addIndexColumn() ->make(true); } return view('book-list'); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { $bookId = $request->id; if($bookId){ $book = Book::find($bookId); if($request->hasFile('image')){ $path = $request->file('image')->store('public/images'); $book->image = $path; } }else{ $path = $request->file('image')->store('public/images'); $book = new Book; $book->image = $path; } $book->title = $request->title; $book->code = $request->code; $book->author = $request->author; $book->save(); return Response()->json($book); } /** * Show the form for editing the specified resource. * * @param \App\book $book * @return \Illuminate\Http\Response */ public function edit(Request $request) { $where = array('id' => $request->id); $book = Book::where($where)->first(); return Response()->json($book); } /** * Remove the specified resource from storage. * * @param \App\book $book * @return \Illuminate\Http\Response */ public function destroy(Request $request) { $book = Book::where('id',$request->id)->delete(); return Response()->json($book); } }
Step 8 – Create Action Button(delete and edit) Blade View
In step 8, create action button name book-action.blade.php file. And add the following code into it:
<a href="javascript:void(0)" data-toggle="tooltip" data-id="{{ $id }}" data-original-title="Edit" class="edit btn btn-success edit"> Edit </a> <a href="javascript:void(0);" id="delete-book" data-toggle="tooltip" data-original-title="Delete" data-id="{{ $id }}" class="delete btn btn-danger"> Delete </a>
Step 9 – Show Image in Datatable
In step 9, create image display blade view named image.blade.php. Using this file, you can show image in datatable list. So add the following code into image.blade.php:
@if($image) <img src="{{ Storage::url($image) }}" height="75" width="75" alt="" /> @else <img src="https://www.riobeauty.co.uk/images/product_image_not_found.gif" alt="" height="75" width="75"> @endif
Step 10 – Create DataTable Blade View
In step 10, create new blade view file that named book-list.blade.php inside resources/views directory for display list using yajra datatables in laravel.
So, add the following code into book-list.blade.php file:
<!DOCTYPE html> <html> <head> <title>Laravel 10/9 DataTable Ajax Books CRUD Example</title> <meta name="csrf-token" content="{{ csrf_token() }}"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.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 mt-4"> <div class="col-md-12 mt-1 mb-2"><button type="button" id="addNewBook" class="btn btn-success">Add</button></div> <div class="card"> <div class="card-header text-center font-weight-bold"> <h2>Laravel 10/9 Ajax Book CRUD with DataTable Example Tutorial</h2> </div> <div class="card-body"> <table class="table table-bordered" id="datatable-ajax-crud"> <thead> <tr> <th>Id</th> <th>Image</th> <th>Book Title</th> <th>Code</th> <th>Author</th> <th>Created at</th> <th>Action</th> </tr> </thead> </table> </div> </div> <!-- boostrap add and edit book model --> <div class="modal fade" id="ajax-book-model" aria-hidden="true"> <div class="modal-dialog modal-lg"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title" id="ajaxBookModel"></h4> </div> <div class="modal-body"> <form action="javascript:void(0)" id="addEditBookForm" name="addEditBookForm" 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">Book Name</label> <div class="col-sm-12"> <input type="text" class="form-control" id="title" name="title" placeholder="Enter Book Name" maxlength="50" required=""> </div> </div> <div class="form-group"> <label for="name" class="col-sm-2 control-label">Book Code</label> <div class="col-sm-12"> <input type="text" class="form-control" id="code" name="code" placeholder="Enter Book Code" maxlength="50" required=""> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">Book Author</label> <div class="col-sm-12"> <input type="text" class="form-control" id="author" name="author" placeholder="Enter author Name" required=""> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">Book Image</label> <div class="col-sm-6 pull-left"> <input type="file" class="form-control" id="image" name="image" required=""> </div> <div class="col-sm-6 pull-right"> <img id="preview-image" src="https://www.riobeauty.co.uk/images/product_image_not_found.gif" alt="preview image" style="max-height: 250px;"> </div> </div> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-primary" id="btn-save" value="addNewBook">Save changes </button> </div> </form> </div> <div class="modal-footer"> </div> </div> </div> </div> <!-- end bootstrap model --> <script type="text/javascript"> $(document).ready( function () { $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); $('#image').change(function(){ let reader = new FileReader(); reader.onload = (e) => { $('#preview-image').attr('src', e.target.result); } reader.readAsDataURL(this.files[0]); }); $('#datatable-ajax-crud').DataTable({ processing: true, serverSide: true, ajax: "{{ url('ajax-datatable-crud') }}", columns: [ {data: 'id', name: 'id', 'visible': false}, { data: 'image', name: 'image' , orderable: false}, { data: 'title', name: 'title' }, { data: 'code', name: 'code' }, { data: 'author', name: 'author' }, { data: 'created_at', name: 'created_at' }, {data: 'action', name: 'action', orderable: false}, ], order: [[0, 'desc']] }); $('#addNewBook').click(function () { $('#addEditBookForm').trigger("reset"); $('#ajaxBookModel').html("Add Book"); $('#ajax-book-model').modal('show'); $("#image").attr("required", "true"); $('#id').val(''); $('#preview-image').attr('src', 'https://www.riobeauty.co.uk/images/product_image_not_found.gif'); }); $('body').on('click', '.edit', function () { var id = $(this).data('id'); // ajax $.ajax({ type:"POST", url: "{{ url('edit-book') }}", data: { id: id }, dataType: 'json', success: function(res){ $('#ajaxBookModel').html("Edit Book"); $('#ajax-book-model').modal('show'); $('#id').val(res.id); $('#title').val(res.title); $('#code').val(res.code); $('#author').val(res.author); $('#image').removeAttr('required'); } }); }); $('body').on('click', '.delete', function () { if (confirm("Delete Record?") == true) { var id = $(this).data('id'); // ajax $.ajax({ type:"POST", url: "{{ url('delete-book') }}", data: { id: id }, dataType: 'json', success: function(res){ var oTable = $('#datatable-ajax-crud').dataTable(); oTable.fnDraw(false); } }); } }); $('#addEditBookForm').submit(function(e) { e.preventDefault(); var formData = new FormData(this); $.ajax({ type:'POST', url: "{{ url('add-update-book')}}", data: formData, cache:false, contentType: false, processData: false, success: (data) => { $("#ajax-book-model").modal('hide'); var oTable = $('#datatable-ajax-crud').dataTable(); oTable.fnDraw(false); $("#btn-save").html('Submit'); $("#btn-save"). attr("disabled", false); }, error: function(data){ console.log(data); } }); }); }); </script> </div> </body> </html>
Demonstration of above book-list.blade.php file code,
The following jQuery and ajax code into book-list.blade.php to get data from database table and display with html table with pagination:
$('#datatable-ajax-crud').DataTable({ processing: true, serverSide: true, ajax: "{{ url('ajax-datatable-crud') }}", columns: [ {data: 'id', name: 'id', 'visible': false}, { data: 'image', name: 'image' , orderable: false}, { data: 'title', name: 'title' }, { data: 'code', name: 'code' }, { data: 'author', name: 'author' }, { data: 'created_at', name: 'created_at' }, {data: 'action', name: 'action', orderable: false}, ], order: [[0, 'desc']] });
And the following code add, edit, delete data using ajax with datatable on book-list.blade.php file:
$('#addNewBook').click(function () { $('#addEditBookForm').trigger("reset"); $('#ajaxBookModel').html("Add Book"); $('#ajax-book-model').modal('show'); $("#image").attr("required", "true"); $('#id').val(''); $('#preview-image').attr('src', 'https://www.riobeauty.co.uk/images/product_image_not_found.gif'); }); $('body').on('click', '.edit', function () { var id = $(this).data('id'); // ajax $.ajax({ type:"POST", url: "{{ url('edit-book') }}", data: { id: id }, dataType: 'json', success: function(res){ $('#ajaxBookModel').html("Edit Book"); $('#ajax-book-model').modal('show'); $('#id').val(res.id); $('#title').val(res.title); $('#code').val(res.code); $('#author').val(res.author); $('#image').removeAttr('required'); } }); }); $('body').on('click', '.delete', function () { if (confirm("Delete Record?") == true) { var id = $(this).data('id'); // ajax $.ajax({ type:"POST", url: "{{ url('delete-book') }}", data: { id: id }, dataType: 'json', success: function(res){ var oTable = $('#datatable-ajax-crud').dataTable(); oTable.fnDraw(false); } }); } }); $('#addEditBookForm').submit(function(e) { e.preventDefault(); var formData = new FormData(this); $.ajax({ type:'POST', url: "{{ url('add-update-book')}}", data: formData, cache:false, contentType: false, processData: false, success: (data) => { $("#ajax-book-model").modal('hide'); var oTable = $('#datatable-ajax-crud').dataTable(); oTable.fnDraw(false); $("#btn-save").html('Submit'); $("#btn-save"). attr("disabled", false); }, error: function(data){ console.log(data); } }); });
And the ollowing code will display add book and edit book model:
<!-- boostrap add and edit book model --> <div class="modal fade" id="ajax-book-model" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <h4 class="modal-title" id="ajaxBookModel"></h4> </div> <div class="modal-body"> <form action="javascript:void(0)" id="addEditBookForm" name="addEditBookForm" class="form-horizontal" method="POST"> <input type="hidden" name="id" id="id"> <div class="form-group"> <label for="name" class="col-sm-2 control-label">Book Name</label> <div class="col-sm-12"> <input type="text" class="form-control" id="title" name="title" placeholder="Enter Book Name" maxlength="50" required=""> </div> </div> <div class="form-group"> <label for="name" class="col-sm-2 control-label">Book Code</label> <div class="col-sm-12"> <input type="text" class="form-control" id="code" name="code" placeholder="Enter Book Code" maxlength="50" required=""> </div> </div> <div class="form-group"> <label class="col-sm-2 control-label">Book Author</label> <div class="col-sm-12"> <input type="text" class="form-control" id="author" name="author" placeholder="Enter author Name" required=""> </div> </div> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-primary" id="btn-save" value="addNewBook">Save changes </button> </div> </form> </div> <div class="modal-footer"> </div> </div> </div> </div> <!-- end bootstrap model -->
And the following jquery code will show image preview before upload:
$('#image').change(function(){ let reader = new FileReader(); reader.onload = (e) => { $('#preview-image').attr('src', e.target.result); } reader.readAsDataURL(this.files[0]); });
Don’t worry i have already added the jquery datatables libraries and ajax code on book-list.blade.php.
Step 11 – Start Development Server
In step 10, open cmd and run the following command:
php artisan serve
Then open browser and fire the following url into your browser:
http://127.0.0.1:8000/ajax-crud-image-upload