Laravel 10 Ajax CRUD with Image Upload Tutorial Example

Laravel 10 Ajax CRUD with Image Upload Tutorial Example

In this tutorial, we will learn how to create a CRUD (Create, Read, Update, Delete) application in Laravel 10 with Ajax and Image Upload functionality. The application will allow users to perform CRUD operations without page reloading and also upload images for the records.

Prerequisites:

Before we start, make sure you have the following prerequisites installed on your system:

  • PHP version 7.4 or above
  • Composer
  • Laravel 10
  • A database (MySQL, PostgreSQL, SQLite, or SQL Server)

Step 1: Install Laravel 10

First, we need to create a new Laravel project. Open a terminal and run the following command:

composer create-project --prefer-dist laravel/laravel ajax-crud

This command will create a new Laravel project named “ajax-crud” in the current directory.

Step 2: Set up Database

Next, we need to set up our database. Open the “.env” file and update the database configuration according to your database credentials:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_database_username
DB_PASSWORD=your_database_password

Step 3: Create Migration and Model

Now, we will create a migration and model for our records. Run the following command in the terminal:

php artisan make:model Record -m

This command will create a model named “Record” and a migration file for the records table. Open the migration file and update it with the following code:

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

class CreateRecordsTable extends Migration
{
    public function up()
    {
        Schema::create('records', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email');
            $table->string('phone');
            $table->string('image')->nullable();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('records');
    }
}

This migration will create a table named “records” with columns for name, email, phone, image, and timestamps.

Step 4: Run Migration

Now, we need to run the migration to create the “records” table in the database. Run the following command in the terminal:

php artisan migrate

Step 5: Create Routes and Controller

Next, we will create routes and a controller for our application. Run the following command in the terminal:

php artisan make:controller RecordController --resource

This command will create a controller named “RecordController” with resource methods for CRUD operations. Open the “RecordController.php” file and update it with the following code:

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Record;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Storage;

class RecordController extends Controller
{
    public function index()
    {
        $records = Record::all();
        return view('records.index', compact('records'));
    }

    public function create()
    {
        return view('records.create');
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email|unique:records,email',
            'phone' => 'required|unique:records,phone',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
        ]);

        if ($validator->fails()) {
            return response()->
    json(['errors' => $validator->errors()]);
    }

    $record = new Record;
    $record->name = $request->name;
    $record->email = $request->email;
    $record->phone = $request->phone;

    if ($request->hasFile('image')) {
        $image = $request->file('image');
        $filename = time() . '.' . $image->getClientOriginalExtension();
        Storage::putFileAs('public/images', $image, $filename);
        $record->image = $filename;
    }

    $record->save();

    return response()->json(['success' => 'Record added successfully.']);
}

public function show($id)
{
    $record = Record::findOrFail($id);
    return view('records.show', compact('record'));
}

public function edit($id)
{
    $record = Record::findOrFail($id);
    return view('records.edit', compact('record'));
}

public function update(Request $request, $id)
{
    $validator = Validator::make($request->all(), [
        'name' => 'required',
        'email' => 'required|email|unique:records,email,'.$id,
        'phone' => 'required|unique:records,phone,'.$id,
        'image' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
    ]);

    if ($validator->fails()) {
        return response()->json(['errors' => $validator->errors()]);
    }

    $record = Record::findOrFail($id);
    $record->name = $request->name;
    $record->email = $request->email;
    $record->phone = $request->phone;

    if ($request->hasFile('image')) {
        $image = $request->file('image');
        $filename = time() . '.' . $image->getClientOriginalExtension();
        Storage::putFileAs('public/images', $image, $filename);
        Storage::delete('public/images/'.$record->image);
        $record->image = $filename;
    }

    $record->save();

    return response()->json(['success' => 'Record updated successfully.']);
}

public function destroy($id)
{
    $record = Record::findOrFail($id);
    Storage::delete('public/images/'.$record->image);
    $record->delete();
    return response()->json(['success' => 'Record deleted successfully.']);
}
}

In the above code, we have defined methods for each CRUD operation. We have also added validation rules for form input and uploaded image.

Step 6: Create Views

Next, we will create views for our application. Run the following commands in the terminal:

mkdir resources/views/records
touch resources/views/records/index.blade.php
touch resources/views/records/create.blade.php
touch resources/views/records/edit.blade.php
touch resources/views/records/show.blade.php


Open the "index.blade.php" file and update it with the following code:

```html
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <div class="card">
                <div class="card-header">Records</div>

                <div class="card-body">
                    <div class="mb-3">
                        <a href="{{ route('records.create') }}" class="btn btn-primary">Add New Record</a>
                    </div>

                    <table class="table">
                        <thead>
                            <tr>
                                <th>Name</th>
                                <th>Email</th>
                                <
                            <th>Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach($records as $record)
                            <tr>
                                <td>{{ $record->name }}</td>
                                <td>{{ $record->email }}</td>
                                <td>
                                    <a href="{{ route('records.show', $record->id) }}" class="btn btn-sm btn-info">View</a>
                                    <a href="{{ route('records.edit', $record->id) }}" class="btn btn-sm btn-primary">Edit</a>
                                    <button type="button" class="btn btn-sm btn-danger" onclick="deleteRecord({{ $record->id }})">Delete</button>
                                </td>
                            </tr>
                        @endforeach
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>
</div>
<form action="" method="POST" id="deleteForm">
    @csrf
    @method('DELETE')
</form>
@endsection

@section('scripts')

<script>
    function deleteRecord(id) {
        if (confirm("Are you sure you want to delete this record?")) {
            var url = "{{ route('records.destroy', ':id') }}";
            url = url.replace(':id', id);
            var form = document.getElementById('deleteForm');
            form.action = url;
            form.submit();
        }
    }
</script>
@endsection

Here, we have created a table to display records with options to view, edit and delete each record. We have also added a form to handle record deletion.

Open the “create.blade.php” file and update it with the following code:

```html
@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <div class="card">
                <div class="card-header">Add New Record</div>

                <div class="card-body">
                    <form action="{{ route('records.store') }}" method="POST" enctype="multipart/form-data" id="createForm">
                        @csrf

                        <div class="form-group">
                            <label for="name">Name</label>
                            <input type="text" class="form-control" id="name" name="name" value="{{ old('name') }}" required>
                        </div>

                        <div class="form-group">
                            <label for="email">Email</label>
                            <input type="email" class="form-control" id="email" name="email" value="{{ old('email') }}" required>
                        </div>

                        <div class="form-group">
                            <label for="phone">Phone</label>
                            <input type="text" class="form-control" id="phone" name="phone" value="{{ old('phone') }}" required>
                        </div>

                        <div class="form-group">
                            <label for="image">Image</label>
                            <input type="file" class="form-control" id="image" name="image">
                        </div>

                        <button type="submit" class="btn btn-primary">Submit</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

@endsection

@section('scripts')
<script>
    $(document).ready(function() {
        $('#createForm').submit(function(e) {
            e.preventDefault();

            var formData = new FormData(this);

            $.ajax({
                type: 'POST',
                url: $(this).attr('action'),
                data: formData,
                dataType: 'json',
                contentType: false,
                processData: false,
                success: function(response) {
                    window.location.href


            },
            error: function(response) {
                var errors = response.responseJSON.errors;
                var errorMsg = '';

                $.each(errors, function(key, value) {
                    errorMsg += value[0] + '<br>';
                });

                Swal.fire({
                    icon: 'error',
                    title: 'Oops...',
                    html: errorMsg
                });
            }
        });
    });
});
</script>
@endsection
```

Here, we have added a form to add a new record with fields for name, email, phone, and image. We have also added JavaScript code to handle form submission via Ajax and display any validation errors using the SweetAlert library.

Next, open the “edit.blade.php” file and update it with the following code:

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <div class="card">
                <div class="card-header">Edit Record</div>

                <div class="card-body">
                    <form action="{{ route('records.update', $record->id) }}" method="POST" enctype="multipart/form-data" id="editForm">
                        @csrf
                        @method('PUT')

                        <div class="form-group">
                            <label for="name">Name</label>
                            <input type="text" class="form-control" id="name" name="name" value="{{ $record->name }}" required>
                        </div>

                        <div class="form-group">
                            <label for="email">Email</label>
                            <input type="email" class="form-control" id="email" name="email" value="{{ $record->email }}" required>
                        </div>

                        <div class="form-group">
                            <label for="phone">Phone</label>
                            <input type="text" class="form-control" id="phone" name="phone" value="{{ $record->phone }}" required>
                        </div>

                        <div class="form-group">
                            <label for="image">Image</label>
                            <input type="file" class="form-control" id="image" name="image">
                            <br>
                            @if($record->image)
                                <img src="{{ asset('storage/' . $record->image) }}" width="100">
                            @endif
                        </div>

                        <button type="submit" class="btn btn-primary">Submit</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

@endsection

@section('scripts')
<script>
    $(document).ready(function() {
        $('#editForm').submit(function(e) {
            e.preventDefault();

            var formData = new FormData(this);

            $.ajax({
                type: 'POST',
                url: $(this).attr('action'),
                data: formData,
                dataType: 'json',
                contentType: false,
                processData: false,
                success: function(response) {
                    window.location.href = "{{ route('records.index') }}";
                },
                error: function(response) {
                    var errors = response.responseJSON.errors;
                    var errorMsg = '';

                    $.each(errors, function(key, value) {
                        errorMsg += value[0] + '<br>';
                    });

                    Swal.fire({
                        icon: 'error',
                        title: 'Oops...',
                        html: errorMsg
                    });
                }
            });
        });
    });
</script>
@endsection

Here, we have added a form to edit an existing record with pre-filled fields for name, email, phone, and image. We have also added JavaScript code to handle form submission via Ajax and display any validation errors using the SweetAlert library.

Finally, open the “RecordsController.php” file and update it with the following code:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Record;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;

class RecordsController extends Controller
{
    public function index()
    {
        $records = Record::all();

        return view('records.index', compact('records'));
    }

    public function create()
    {
        return view('records.create');
    }

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email|unique:records',
            'phone' => 'required',
            'image' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048',
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }

        $record = new Record;
        $record->name = $request->name;
        $record->email = $request->email;
        $record->phone = $request->phone;

        if ($request->hasFile('image')) {
            $image = $request->file('image');
            $path = $image->store('public/images');
            $record->image = str_replace('public/', '', $path);
        }

        $record->save();

        return response()->json(['success' => 'Record added successfully']);
    }

    public function edit($id)
    {
        $record = Record::find($id);

        return view('records.edit', compact('record'));
    }

    public function update(Request $request, $id)
    {
        $validator = Validator::make($request->all(), [
            'name' => 'required',
            'email' => 'required|email|unique:records,email,'.$id,
            'phone' => 'required',
            'image' => 'image|mimes:jpeg,png,jpg,gif,svg|max:2048',
        ]);

        if ($validator->fails()) {
            return response()->json(['errors' => $validator->errors()], 422);
        }

        $record = Record::find($id);
        $record->name = $request->name;
        $record->email = $request->email;
        $record->phone = $request->phone;

        if ($request->hasFile('image')) {
            if ($record->image) {
                Storage::delete('public/'.$record->image);
            }

            $image = $request->file('image');
            $path = $image->store('public/images');
            $record->image = str_replace('public/', '', $path);
        }

        $record->save();

        return response()->json(['success' => 'Record updated successfully']);
    }

    public function destroy($id)
    {
        $record = Record::find($id);

        if ($record->image) {
            Storage::delete('public/'.$record->image);
        }

        $record->delete();

        return response()->json(['success' => 'Record deleted successfully']);
    }
}

Here, we have added code to handle CRUD operations using Laravel’s Eloquent ORM. We have also added validation rules for form fields and used the Storage facade to handle image uploads and deletions.

That’s it! You now have a fully functional Ajax CRUD system with image upload using Laravel 10. You can test your application by running it in the browser and performing CRUD operations on records.

Conclusion

Conclusion In this tutorial, we have learned how to build a Laravel 10 Ajax CRUD system with image upload. We have used jQuery and the Bootstrap framework to create the user interface and handle AJAX requests.

We have also covered the basics of Laravel’s Eloquent ORM, validation, and file uploads using the Storage facade. By the end of this tutorial, you should have a solid understanding of how to create dynamic, responsive web applications using Laravel.

If you want to learn more about Laravel and web development in general, there are many resources available online. Some good places to start include the official Laravel documentation, Laracasts, and Stack Overflow.

Remember to always keep security in mind when building web applications. Make sure to sanitize user input, validate form fields, and use secure password storage methods. Laravel provides many tools to help you build secure web applications, so be sure to take advantage of them.

This Article Ideas has been taken from the following websites; which are following:

https://dcodemania.com/post/crud-application-image-upload-laravel-8-ajax-sweetalert-datatable

Laravel 10 Ajax CRUD with Image Upload Example

https://www.itsolutionstuff.com/post/laravel-10-ajax-image-upload-exampleexample.html

https://websolutionstuff.com/post/crud-with-image-upload-in-laravel-10-example

https://techsolutionstuff.com/post/how-to-create-ajax-crud-operation-in-laravel-10

Comments

Leave a Reply

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