Multiple Images Uploading using dropzone.js with laravel 5x

Tiếp tục SERIES: Tìm hiểu laravel & Xây dựng website bán hàng cùng Laravel 5x.

Phần 1: Blade template, Xây dựng giao diện người dùng Phần 2: User Authentication, Xây dựng trang login Phần 3: Back-end : Category management Phần 4: Back-end : Product management, Upload multiple images
Phần N: Show sp, tạo giỏ hàng, quản lý đơn hàng, Mail....

Chức năng Product management, các bạn làm tương tự như chức năng Back-end : Category management mình đã làm trước đó.

Upload multiple là một trong những tính năng được sử dụng khá nhiều trong ứng dụng website. Phần này mình sẽ hướng dẫn xây dựng chức năng upload ảnh cho sản phẩm.

Trong bài viết này, mình sẽ sử dụng Dropzone.js. Nó là một thư viện đơn giản để tạo chức năng upload tập tin theo dạng "Kéo và thả". Khác với thư viện javascript khác, Dropzone hỗ trợ nhiều tùy biến khác nhau.

Preview : Chức năng upload nhiều hình ảnh cho sản phẩm.

Ok. Bây giờ chúng ta sẽ bắt đầu.

Step 1: Add Route

Route::resource('product', 'AdminProductController');
Route::post('uploadImg', '[email protected]'); 

Step 2: Add Controller Method

php artisan make:controller Admin\AdminProductController

Nội dung file

app/Http/Controllers/Admin/AdminProductController.php

class AdminProductController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $this->data['title'] = 'List products';
        $productsInfo = DB::table('products')
            ->orderBy('id', 'desc')
            ->paginate(10);
        $this->data['listProduct'] = $productsInfo;
        return view('admin.product.index', $this->data);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $this->data['title'] = 'Add new product';
        $listCate = DB::table('categories')->orderBy('id', 'desc')->get();
        $this->data['listCate'] = $listCate;
        return view('admin.product.create', $this->data);
    }

php artisan make:controller Admin\AdminUploadController

Controller này để xử lý upload, delete images = ajax

Nội dung:

app/Http/Controllers/Admin/AdminUploadController.php

    <?php

namespace App\Http\Controllers\Admin;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\ProductImage;
use App\Product;
class AdminUploadController extends Controller
{
    //
    function postImages(Request $request)
    {
        if ($request->ajax()) {
            if ($request->hasFile('file')) {
                $imageFiles = $request->file('file');
                // set destination path
                $folderDir = 'uploads/products';
                $destinationPath = base_path() . '/' . $folderDir;
                // this form uploads multiple files
                foreach ($request->file('file') as $fileKey => $fileObject ) {
                    // make sure each file is valid
                    if ($fileObject->isValid()) {
                        // make destination file name
                        $destinationFileName = time() . $fileObject->getClientOriginalName();
                        // move the file from tmp to the destination path
                        $fileObject->move($destinationPath, $destinationFileName);
                        // save the the destination filename
                        $prodcuctImage = new ProductImage;
			            $ProdcuctImage->image_path = $folderDir . $destinationFileName;
			            $prodcuctImage->title = $originalNameWithoutExt;
			            $prodcuctImage->alt = $originalNameWithoutExt;
			            $prodcuctImage->save();
                    }
                }
            }
        }
    }

Step 3: Add Blade File

Nội dung File create.blade.php

@extends('admin.master')
@section('content')
    <section class="content-header">
        <h1>
            Edit Product
        </h1>
        <ol class="breadcrumb">
            <li><a href="#"><i class="fa fa-dashboard"></i> Home</a></li>
            <li><a href="#">Product</a></li>
            <li class="active">Edit</li>
        </ol>
    </section>
    <section class="content ">
        @if(count($errors) >0)
            <ul>
                @foreach($errors->all() as $error)
                    <li class="text-danger">{{ $error }}</li>
                @endforeach
            </ul>
        @endif
        <!-- enctype="multipart/form-data" class="dropzone dz-clickable" -->
        <form action="{{ url('admincp/product') }}" method="POST" enctype="multipart/form-data">
            {{ csrf_field() }}
            <div class="col-md-6">
                <div class="box">
                    <div class="box-header with-border">
                        <h3 class="box-title">Info</h3>
                    </div>
                    <div class="box-body ">
                        <div class="form-group col-md-12">
                            <label>Name</label>
                            <input type="text" name="txtName" class="form-control" value="{{ old('txtName')}}">
                        </div>
                        <div class="form-group col-md-12">
                            <label>Desc</label>
                            <textarea name="txtDesc" class="form-control">{{ old('txtDesc') }}</textarea>
                        </div>
                        <div class="form-group col-md-12">
                            <label>Content</label>
                            <textarea name="txtContent" class="form-control">{{ old('txtContent') }}</textarea>
                        </div>
                        <div class="form-group col-md-12">
                            <label>Price</label>
                            <input name="txtPrice" class="form-control"
                                   value="@if(empty(old('txtPrice'))) 0 @else{{old('txtPrice')}}@endif">
                        </div>
                        <div class="form-group col-md-12">
                            <label>Category</label>
                            <select class="form-control" name="cate_id">
                                <option value="0">---</option>
                                @foreach($listCate as $cate)
                                    <option value="{{ $cate->id }}"
                                        @if ($cate->id == old('cate_id'))
                                        selected="selected"
                                        @endif
                                        >{{ $cate->name }}</option>
                                @endforeach
                            </select>
                        </div>
                    </div>
                </div>
            </div>
            <div class="col-md-6">
                <div class="box">
                    <div class="box-header with-border">
                        <h3 class="box-title">SEO Infomation</h3>
                    </div>
                    <div class="box-body">
                        <div class="form-group col-md-12">
                            SEO Title <input type="text" name="meta_title" class="form-control"  value="{{ old('meta_title') }}">
                            Meta Keywords <input type="text" name="meta_key" class="form-control"  value="{{ old('meta_key') }}">
                            Meta Description <input type="text" name="meta_desc" class="form-control"  value="{{ old('meta_desc') }}">
                        </div>
                    </div>
                </div>
            </div>
            <div class="col-md-12">
                <div class="dropzone" id="my-dropzone" name="myDropzone">

                </div>
            </div>
            <div class="col-md-12">
                <button type="submit" class="btn btn-success pull-right">
                    <i class="fa fa-save"></i>
                    <span>Save and back</span>
                </button>
            </div>
        </form>

    </section>
@endsection

Step 4: Setup dropzonejs.

Trước tiên bạn cần download lib dropzonejs, Chi tiết về dropzonejs bạn có thể lên trang dropzonejs.com để tìm hiểu. Khi đã download về, coppy các thư mục (js, css, images) vào project

Thêm đoạn code sau vào create.blade.php.

@section('page-js-script')
    <link rel="stylesheet" href="{{ asset('admin/dist/css/dropzone.css') }}">
    <script src="{{ asset('admin/dist/js/dropzone.js') }}"></script>
    <script type="text/javascript">
       Dropzone.options.myDropzone= {
           url: '{{ url('admincp/uploadImg') }}',
           headers: {
               'X-CSRF-TOKEN': '{!! csrf_token() !!}'
           },
           autoProcessQueue: true,
           uploadMultiple: true,
           parallelUploads: 5,
           maxFiles: 10,
           maxFilesize: 5,
           acceptedFiles: ".jpeg,.jpg,.png,.gif",
           dictFileTooBig: 'Image is bigger than 5MB',
           addRemoveLinks: true,
           removedfile: function(file) {
           var name = file.name;    
           name =name.replace(/\s+/g, '-').toLowerCase();    /*only spaces*/
            $.ajax({
                type: 'POST',
                url: '{{ url('admincp/deleteImg') }}',
                headers: {
                     'X-CSRF-TOKEN': '{!! csrf_token() !!}'
                 },
                data: "id="+name,
                dataType: 'html',
                success: function(data) {
                    $("#msg").html(data);
                }
            });
          var _ref;
          if (file.previewElement) {
            if ((_ref = file.previewElement) != null) {
              _ref.parentNode.removeChild(file.previewElement);
            }
          }
          return this._updateMaxFilesReachedClass();
        },
        previewsContainer: null,
        hiddenInputContainer: "body",
       }
    </script>
    <style>
        .dropzone {
            border: 2px dashed #0087F7;
            border-radius: 5px;
            background: white;
        }
    </style>
@endsection

Demo: