Uploading Image using AJAX

Uploading image is one of the basics of web development. But it is one of the most important part in web as well as app.

Here in this article, we will learn about process of image upload using AJAX. This method is applicable from Laravel 5 to current version of laravel.

Below we will program a simple that uses AJAX and Laravel for uploading image. We will use jQuery’s AJAX request to add or update images because it helps in uploading without refreshing the page.

Required Contents

  • Routes
  • Blade and JS
  • Controller and Logic

Routes

First of all we will make two route files, one for returning view in which we input image and another for uploading image.

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

Blade And Js

After writing routes, make profile.blade.php inside resource folder.

@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

Controller And Logic

Finally, we develop controller using 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 getUser()
    {
        $user = User::find(1);
        return view('profile', compact('user'));
    }

    public function postUpdate(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'];
    }
}

There are two methods inside this class which are getUser and postUpdate. getUser mthod returns user’s data to profile view whereas postUpdate validates photo with Laravel validator facade and if it passes then it uploads the image.

Image Requirments

  • image having jpg, png, jpeg as file extension
  • Size having less than 200KB.

We can change the requirements from postUpdate method.

Leave a Comment