Laravel Ajax Multiple Image Upload and Preview

This is post talk about ajax multiple image upload and preview with Dropzone.js in Laravel 4, and store file info in database.

Dropzone.js comes with nice CSS and Javascript that make it a breeze to work with HTML 5 file upload API. It provides you with a file input container that users can drag and drop files unto or just click the container to select multiple files from the file system.

From the plugin docs: Dropzone.js works in:

  • Chrome 7+
  • Firefox 4+
  • IE 10+
  • Opera 12+
  • Safari 5+

For all the other browsers, dropzone provides an oldschool file input fallback.

Ajax Image Upload Features

  • Ajax image upload without page refrshing using laravel
  • Instant uploaded image preview
  • Image validation and showing error messages

Note: For validation you need to enable php_fileinfo otherwise it returns exception.

Now start the implementation

At first we need to set route for display and post form data.

File: routes.php

Route::group(array('prefix' => 'articles'), function () {
    $resource   = 'articles';
    $controller = '[email protected]';
    // ...
    Route::post('{id}', array('as' => $resource.'.postUpload', 'uses' => $controller.'postUpload' ));
    // ...
});

Routes are fine. Then we need to process the form data. We can create a postUpload Controller, but at here I create postUpload function in my ArticleResource Controller.

File: ArticleResource.php

// ...
public function postUpload($id){

    $input = Input::all();
    $rules = array(
        'file' => 'image|max:3000',
    );

    $validation = Validator::make($input, $rules);

    if ($validation->fails())
    {
        return Response::make($validation->errors->first(), 400);
    }

    $file               = Input::file('file');
    $destinationPath    = 'uploads';

    // Get real extension according to mime type
    $ext                = $file->guessClientExtension();  

    // Client file name, including the extension of the client
    $fullname           = $file->getClientOriginalName(); 

    // Hash processed file name, including the real extension
    $hashname           = date('H.i.s').'-'.md5($fullname).'.'.$ext; 
    $upload_success     = Input::file('file')->move($destinationPath, $hashname);
    $models             = new Picture;
    $models->filename   = $hashname;
    $models->article_id = $id;
    $models->user_id    = Auth::user()->id;
    $models->save();

    if( $upload_success ) {
       return Response::json('success', 200);
    } else {
       return Response::json('error', 400);
    }
}
// ...

Create uploads folder in your application public directory (public/uploads/) then you must give 777 folder permission.

Picture Models

File: Picture.php

<?php

/**
 * Article Pictures
 */
class Picture extends BaseModel
{
    /**
     * Database table name (without prefix)
     * @var string
     */
    protected $table = 'article_pictures';

    /**
     * Soft delete
     * @var boolean
     */
    protected $softDelete = true;

    /**
     * Object-relational model: Vesting article
     * @return object Article
     */
    public function article()
    {
        return $this->belongsTo('Article', 'article_id');
    }

}

View blade file: article/edit.blade.php

// ...
{{ script('dropzone') }} // Require Dropzone.js
// ...
<form action="{{ route($resource.'.postUpload', $data->id) }}" class="dropzone" id="upload">
    <input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>
// ...

Note: I've define dropzone.js in app/config/extend.php

File: extend.php

<?php

/*
|--------------------------------------------------------------------------
| Extend File Configuration
|--------------------------------------------------------------------------
|
*/

return array(
    /**
     * Static resource files alias configuration
     */
    'webAssets' => array(
        // ...
        'jsAliases'  => array(  // Script alias configuration
            // ...
            'dropzone' => 'assets/dropzone-3.10.2/lib/dropzone.js',
            // ...
        ),
    ),
);

Note: If you get the error Dropzone already attached. when creating the Dropzone, try to turn off autoDiscover globally like this:

Dropzone.autoDiscover = false;

... or turn off autoDiscover of specific elements like this:

Dropzone.options.myAwesomeDropzone = false;

Laravel Ajax Multiple Image Upload and Preview

I hope you like this tutorial. Share this tutorials on your favorite media to show your appreciation. Thanks!

Laravel Ajax Multiple Image Upload and Preview
4 votes, 4.00 avg. rating (82% score)