Laravel ajax image upload system

Laravel ajax image upload system

Image upload system is one of the most important parts of application or website development and Ajax image upload system enhances your application UX. In this post, I'll show you step by step process on how to Ajax image upload with validation by Laravel framework. Following this post, you can do the exact same things from Laravel version 5 to the current version.

Goal

The goal is to upload image for user profile. Suppose we have application or website where we need to update or add an image for user profile. Here we do it Ajax request with jQuery. So that the Image will upload without any page refresh.

Contents

  • Route Define
  • Make Blade View & Js Code
  • Make Controller & Logic
  • Conclusion

 

Route Define

First, define 2 routes in your routes file. One for returning a view with a file input field and the last one is for submitting post request to our controller to upload the image.

Route::get('user/profile', 'UserController@getProfile')->name('profile');
Route::post('user/profile', 'UserController@postProfileUpdate')->name('updateProfile');

 

Make Blade View & Js Code

Make a blade view inside resource directory with the name profile.blade.php

@extends('app')
@section('content')
    <div class="container">
        <div class="row">
            <div class="col-md-6">
                <h3><i class="fa fa-image"></i> Ajax Image Upload</h3>
                <br>

                <h4>User Profile</h4>
                <hr>
                <div style="display: flex;">
                    <div>
                        <img class="imgPreview img img-circle" 
                         width="80" src="https://via.placeholder.com/80">
                    </div>
                    <div style="margin-left: 15px; flex-grow: 1">
                        <p>Choose a file</p>
                        <input id="photo" type="file">
                        <input type="hidden" name="id" value="{{$user->id}}">
                        <br>
                        <div class="progress">
                            <div class="progress-bar" 
                                 role="progressbar" aria-valuemin="0"
                                 aria-valuemax="100">

                            </div>
                        </div>
                    </div>
                </div>


                <table class="table table-condensed table-bordered">
                    <tr>
                        <td width="100">Name</td>
                        <td>{{$user->name}}</td>
                    </tr>
                    <tr>
                        <td>E-Mail</td>
                        <td>{{$user->email}}</td>
                    </tr>
                    <tr>
                        <td>Phone</td>
                        <td>{{$user->phone}}</td>
                    </tr>
                    <tr>
                        <td>Address</td>
                        <td>{{$user->address}}</td>
                    </tr>
                </table>
            </div>
        </div>
    </div>

    <script>
        $(function () {
            $.ajaxSetup({
                headers: {'X-CSRF-Token': '{{csrf_token()}}'}
            });

            var id = $('input[name="id"]').val();


            $('#photo').change(function () {
                var photo = $(this)[0].files[0];
                var formData = new FormData();
                formData.append('id', id);
                formData.append('photo', photo);

                $.ajax({
                    xhr: function () {
                        var xhr = new window.XMLHttpRequest();
                        xhr.upload.addEventListener("progress", function (evt) {
                            if (evt.lengthComputable) {
                                var percentComplete = evt.loaded / evt.total;
                                percentComplete = parseInt(percentComplete * 100);
                                console.log(percentComplete);
                                $('.progress-bar').css('width', percentComplete + '%');
                                if (percentComplete === 100) {
                                    console.log('completed 100%')

                                    var imageUrl = window.URL.createObjectURL(photo)
                                    $('.imgPreview').attr('src', imageUrl);
                                    setTimeout(function () {
                                        $('.progress-bar').css('width', '0%');
                                    }, 2000)
                                }
                            }
                        }, false);
                        return xhr;
                    },
                    url: '{{route('updateProfile')}}',
                    type: 'POST',
                    data: formData,
                    processData: false,
                    contentType: false,
                    success: function (res) {
                        if(!res.success){alert(res.error)}
                    }
                })
            })
        })
    </script>
@endsection

 

Make Controller & Logic

Now make a controller with the artisan command php artisan make:controller UserController

<?php
namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class UserController extends Controller
{
    public function getProfile()
    {
        $user = User::find(1);
        return view('profile', compact('user'));
    }

    public function postProfileUpdate(Request $request)
    {
    	$validator = Validator::make($request->all(), [
                		'photo' => 'required|image|mimes:png,jpg,jpeg|max:200',
            		]);

        if ($validator->fails()) {
            return response()
                ->json([
                    'success' => false,
                    'error' =>  $validation->errors()->first()
                ]);
        }

        $user = User::find($request->input('id'));

        if ($request->hasFile('photo')) {
            $photo = $request->file('photo');

            $fileName = $user->id . "." . $photo->getClientOriginalExtension();
            $request->file('photo')->move(public_path('user-photos'), $fileName);
            $user->update(['photo' => $fileName]);
        }

        return ['success'=>true,'message'=>'Successfully updated'];
    }
}

Here, with the getProfile method we just return user profile data to our profile view. In the postProfileUpdate we validated user-selected photo with Laravel validator facade. According to our validation user can only able to upload an image file with png, jpg, jpeg extensions image maximum 200KB.

 

Conclusion

Hope this step by step post will help you to learn ajax upload image upload in Laravel framework. If you find this is helpful for you then share it with others.


Share on

Related Post


DB Seeder - A database seeder application

Laravel Barcode generation tutorial

Laravel Validation Cheat Sheet

PEST - Make Laravel test easier

Laravel Google reCaptcha without package

Speed Up Laravel website - Step by Step