Laravel 10 Ajax CRUD with Image Upload Tutorial

Laravel 10 Ajax CRUD with Image Upload Tutorial

It is very easy to implement Ajax crud example with image upload functionality in the Laravel 10 web application. For this you will need Ajax, jQuery, Bootstrap and dataTable. Using all these JavaScript libraries, you can easily create Ajax CRUD example with Image Upload Functionality in Laravel 10 Web Application.

In this tutorial, you will learn how to create an Ajax crud example with image file upload and preview in Laravel 10 apps without refreshing or reloading the whole web page.

Laravel 10 Ajax CRUD with Image Upload Tutorial

By using the following steps, you can create ajax crud example with image upload in laravel 10 without page refresh; is as follows:

  • Step 1 – Setup New Laravel 10 App
  • Step 2 – Setup Database with Laravel App
  • Step 3 – Create Migration And Model
  • Step 4 – Install and Configure Yajra DataTables
  • Step 5 – Define Routes
  • Step 6 – Create Controller
  • Step 7 – Create Blade View
  • Step 8 – Run Development Server

Step 1 – Setup New Laravel 10 App

First of all, open your terminal to download or install Laravel 10 new setup. Run the following commands in it to install the new Laravel 10 app on your system:

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

Step 2 – Setup Database with Laravel App

Once you have installed laravel web app on your server. Now, you need to set the database credentials in your application.

Let’s open your project .env file and set the database credentials here.

 DB_CONNECTION=mysql 
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=here your database name here
DB_USERNAME=here database username here
DB_PASSWORD=here database password here

Step 3 – Create Migration And Model

In this step, Execute the following command on terminal to create product table migration and create Product Modal using bellow command:

php artisan nake:modal Product -m

Navigate database/migrations/ and open create_products_table.php file. Then update the following code into this file:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('product_code')->nullable();
            $table->string('image')->nullable();
            $table->text('description');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}



Now run the following command:

php artisan migrate

This command will create tables in your database.

Next, Navigate to App directory and open Product.php file and then update the following code to into Product.php file as follow:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory;

    protected $fillable = [
    	                   'title',
    	                   'product_code',
    	                   'description',
    	                   'image'
    	               ];
    	               
}

Step 4 – Install and Configure Yajra DataTables

In this step, Execute the following command to terminal to install Yajra Datatables Packages in your laravel application. Use the below command and install yajra packages in your Laravel 10 app:

composer require yajra/laravel-datatables-oracle

After successfully Install Yajra Datatables Packages in your laravel application. Next step, open config/app.php file and add service provider and aliases.

 
config/app.php


'providers' => [


Yajra\Datatables\DatatablesServiceProvider::class,
],


'aliases' => [


'Datatables' => Yajra\Datatables\Facades\Datatables::class,
]

After set providers and aliases then publish vendor run by following command.

php artisan vendor:publish

Step 5 – Define Routes

In this step, Add routes in the web.php file as below.

Navigate to routes/web.php file and update the following routes:

use App\Http\Controllers\ProductController;

Route::get('product-list', [ProductController::class, 'index']);
Route::get('product-list/{id}/edit', [ProductController::class, 'edit']);
Route::post('product-list/store', [ProductController::class, 'store']);
Route::get('product-list/delete/{id}', [ProductController::class, 'destroy']);

Step 6 – Create Controller

In this step, create a new controller name ProductController. So use the below command and create a new controller that name is ProductController.

php artisan make:controller ProductController

Next navigate to app/Http/Controllers and open ProductController.php file. Then update the following methods for add products, edit product and delete the product into this controller file:

In Product Controller, you need to create some methods as follow:

  • Index()
  • Store()
  • Edit()
  • Destroy()

Index() method

Using the index() method, you will show the product list. So update the below code in your product controller index() method:

    public function index()
    {
        if(request()->ajax()) {
            return datatables()->of(Product::select('*'))
            ->addColumn('action', 'product-button')
            ->addColumn('image', 'image')
            ->rawColumns(['action','image'])
            ->addIndexColumn()
            ->make(true);
        }
        return view('list');
    } 

Store() Method

Using the Store() method, you will save and update the product into a database table. So update the below code in your product controller Store() method:

    public function store(Request $request)
    {  
        request()->validate([
            'image' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048',
       ]);

        $productId = $request->product_id;

        $details = ['title' => $request->title, 'product_code' => $request->product_code, 'description' => $request->description];

        if ($files = $request->file('image')) {
           
           //delete old file
           \File::delete('public/product/'.$request->hidden_image);
        
           //insert new file
           $destinationPath = 'public/product/'; // upload path
           $profileImage = date('YmdHis') . "." . $files->getClientOriginalExtension();
           $files->move($destinationPath, $profileImage);
           $details['image'] = "$profileImage";
        }
        
        $product   =   Product::updateOrCreate(['id' => $productId], $details);  
              
        return Response::json($product);
    } 

Edit() Method

Using the Edit() method, you will edit the product details, So update the below code with your edit method:

public function edit($id)
{   
    $where = array('id' => $id);
    $product  = Product::where($where)->first();
 
    return Response::json($product);
}

Delete() Method

Using the delete method, you can delete a product from the product list and also database table. So update the below code with your delete() method:

    public function destroy($id) 
    {
        $data = Product::where('id',$id)->first(['image']);
        \File::delete('public/product/'.$data->image);
        $product = Product::where('id',$id)->delete();
     
        return Response::json($product);
    }

Now, update all methods into your ProductController.php file as follow:

<?php
  
namespace App\Http\Controllers;
  
use App\Product;
use Illuminate\Http\Request;
use Redirect,Response,DB;
use File;
use PDF;
  
class ProductController extends Controller
{
    public function index()
    {
        if(request()->ajax()) {
            return datatables()->of(Product::select('*'))
            ->addColumn('action', 'product-button')
            ->addColumn('image', 'image')
            ->rawColumns(['action','image'])
            ->addIndexColumn()
            ->make(true);
        }
        return view('list');
    } 

    public function store(Request $request)
    {  
        request()->validate([
            'image' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048',
       ]);

        $productId = $request->product_id;

        $details = ['title' => $request->title, 'product_code' => $request->product_code, 'description' => $request->description];

        if ($files = $request->file('image')) {
           
           //delete old file
           \File::delete('public/product/'.$request->hidden_image);
        
           //insert new file
           $destinationPath = 'public/product/'; // upload path
           $profileImage = date('YmdHis') . "." . $files->getClientOriginalExtension();
           $files->move($destinationPath, $profileImage);
           $details['image'] = "$profileImage";
        }
        
        $product   =   Product::updateOrCreate(['id' => $productId], $details);  
              
        return Response::json($product);
    } 

    public function edit($id)
    {   
        $where = array('id' => $id);
        $product  = Product::where($where)->first();
     
        return Response::json($product);
    }
    public function destroy($id) 
    {
        $data = Product::where('id',$id)->first(['image']);
        \File::delete('public/product/'.$data->image);
        $product = Product::where('id',$id)->delete();
     
        return Response::json($product);
    }
}

Step 7 – Create Blade View

In this step, create 3 blade views files. The first file is an action button that contains two buttons and the button name is edit and delete. The second file contains the product list. and the third file name image.blade.php file, it contains image.

Now, Navigate to resources/views and create action.blade.php file. This file contains a two-button name edit and delete. So you can update the below code in your action button file.

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

Next, create a list.blade.php file inside resources/views/ folder and update the below code in your product list file.

<!DOCTYPE html>
 
<html lang="en">
<head>
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel Ajax Crud Example with Image Upload Tutorial - Tuts Make</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
<link  href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.js"></script>  
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">

  <a href="javascript:void(0)" class="btn btn-info ml-3" id="create-new-product">Add New</a>
  <br><br></br><br>
  
  <table class="table table-bordered table-striped" id="laravel_datatable">
    <thead>
      <tr>
        <th>ID</th>
        <th>S. No</th>
        <th>Image</th>
        <th>Title</th>
        <th>Product Code</th>
        <th>Description</th>
        <th>Created at</th>
        <th>Action</th>
      </tr>
    </thead>
  </table>
</div>

<div class="modal fade" id="ajax-product-modal" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h4 class="modal-title" id="productCrudModal"></h4>
      </div>
      <div class="modal-body">
        <form id="productForm" name="productForm" class="form-horizontal" enctype="multipart/form-data">
          <input type="hidden" name="product_id" id="product_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 Tilte" value="" maxlength="50" required="">
            </div>
          </div>
          <div class="form-group">
            <label for="name" class="col-sm-2 control-label">Product Code</label>
            <div class="col-sm-12">
              <input type="text" class="form-control" id="product_code" name="product_code" placeholder="Enter Tilte" value="" maxlength="50" required="">
            </div>
          </div>
          
          <div class="form-group">
            <label class="col-sm-2 control-label">Description</label>
            <div class="col-sm-12">
              <input type="text" class="form-control" id="description" name="description" placeholder="Enter Description" value="" required="">
            </div>
          </div>
          
          <div class="form-group">
            <label class="col-sm-2 control-label">Image</label>
            <div class="col-sm-12">
              <input id="image" type="file" name="image" accept="image/*" onchange="readURL(this);">
              <input type="hidden" name="hidden_image" id="hidden_image">
            </div>
          </div>

          <img id="modal-preview" src="https://via.placeholder.com/150" alt="Preview" class="form-group hidden" width="100" height="100">

          <div class="col-sm-offset-2 col-sm-10">
            <button type="submit" class="btn btn-primary" id="btn-save" value="create">Save changes
            </button>
          </div>

        </form>
      </div>
      <div class="modal-footer">
        
      </div>
    </div>
  </div>
</div> 

</body>

</html>

Next, you will create a script code for performing create, store, update and delete products from the database table products using jQuery ajax request in laravel. So update this code in your list.blade.php file:

<script>
  
 var SITEURL = '{{URL::to('')}}';

 $(document).ready( function () {
   $.ajaxSetup({
      headers: {
          'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
      }
  });
   
  $('#laravel_datatable').DataTable({
         processing: true,
         serverSide: true,
         ajax: {
          url: SITEURL + "product-list",
          type: 'GET',
         },
         columns: [
                  {data: 'id', name: 'id', 'visible': false},
                  {data: 'DT_RowIndex', name: 'DT_RowIndex', orderable: false,searchable: false},
                  {data: 'image', name: 'image', orderable: false},
                  { data: 'title', name: 'title' },
                  { data: 'product_code', name: 'product_code' },
                  { data: 'description', name: 'description' },
                  { data: 'created_at', name: 'created_at' },
                  {data: 'action', name: 'action', orderable: false},
               ],
        order: [[0, 'desc']]
      });

    /*  When user click add user button */
    $('#create-new-product').click(function () {
        $('#btn-save').val("create-product");
        $('#product_id').val('');
        $('#productForm').trigger("reset");
        $('#productCrudModal').html("Add New Product");
        $('#ajax-product-modal').modal('show');
        $('#modal-preview').attr('src', 'https://via.placeholder.com/150');
    });
 
   /* When click edit user */
    $('body').on('click', '.edit-product', function () {
      var product_id = $(this).data('id');
      $.get('product-list/' + product_id +'/edit', function (data) {
         $('#title-error').hide();
         $('#product_code-error').hide();
         $('#description-error').hide();
         $('#productCrudModal').html("Edit Product");
          $('#btn-save').val("edit-product");
          $('#ajax-product-modal').modal('show');
          $('#product_id').val(data.id);
          $('#title').val(data.title);
          $('#product_code').val(data.product_code);
          $('#description').val(data.description);

          $('#modal-preview').attr('alt', 'No image available');
          if(data.image){
            $('#modal-preview').attr('src', SITEURL +'public/product/'+data.image);
            $('#hidden_image').attr('src', SITEURL +'public/product/'+data.image);
          }
          
      })
   });
    $('body').on('click', '#delete-product', function () {
 
        var product_id = $(this).data("id");
       
        if(confirm("Are You sure want to delete !")){
          $.ajax({
              type: "get",
              url: SITEURL + "product-list/delete/"+product_id,
              success: function (data) {
              var oTable = $('#laravel_datatable').dataTable(); 
              oTable.fnDraw(false);
              },
              error: function (data) {
                  console.log('Error:', data);
              }
          });
        }
    });  

   });

 
  $('body').on('submit', '#productForm', function (e) {

      e.preventDefault();

      var actionType = $('#btn-save').val();
      $('#btn-save').html('Sending..');

      var formData = new FormData(this);

      $.ajax({
          type:'POST',
          url: SITEURL + "product-list/store",
          data: formData,
          cache:false,
          contentType: false,
          processData: false,
          success: (data) => {
              
              $('#productForm').trigger("reset");
              $('#ajax-product-modal').modal('hide');
              $('#btn-save').html('Save Changes');
              var oTable = $('#laravel_datatable').dataTable();
              oTable.fnDraw(false);
          },
          error: function(data){
              console.log('Error:', data);
              $('#btn-save').html('Save Changes');
          }
      });
  });

function readURL(input, id) {
  id = id || '#modal-preview';
  if (input.files && input.files[0]) {
      var reader = new FileReader();

      reader.onload = function (e) {
          $(id).attr('src', e.target.result);
      };

      reader.readAsDataURL(input.files[0]);
      $('#modal-preview').removeClass('hidden');
      $('#start').hide();
  }
}
</script>

Next, navigate to resources/views and create image.blade.php file. Then update the following code into your image.blade.php file:

@if($image)

 <img id="preview" src="{{ ('public/product/'.$image) }}" alt="Preview" class="form-group hidden" width="100" height="100">

@else
 <img id="preview" src="https://via.placeholder.com/150" alt="Preview" class="form-group hidden" width="100" height="100">

@endif

Step 8 – Run Development Server

Now, execute the following command on the terminal to start development server. So open your terminal and run PHP artisan serve command:

 php artisan serve

 If you want to run the project diffrent port so use this below command 

 php artisan serve --port=8080  

Now you are ready to run our this example, so open your browser and hit the below URL:.

http://localhost:8000/product-list

Conclusion

Laravel 10 ajax crud example with image upload and preview tutorial, you have learned how to create ajax crud example app with image upload preview using jQuery, yajra datatables and bootstrap modal without a refresh or reload the whole web page.

Recommended Laravel Posts

If you have any questions or thoughts to share, use the comment form below to reach us.

AuthorAdmin

My name is Devendra Dode. I am a full-stack developer, entrepreneur, and owner of Tutsmake.com. I like writing tutorials and tips that can help other developers. I share tutorials of 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 from a starting stage. As well as demo example.

Leave a Reply

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