12/08/2018, 12:35

Upload nhiều files với DropzoneJS và Carrierwave

1. DropzoneJS là gì## DropzoneJS là một thư viện javascript cho phép upload nhiều file thông qua AJAX. Ngoài ra, thư viện này còn hỗ trợ tính năng kéo thả file và tính năng xem trước file ảnh đã upload. 2. Cài đặt## Bạn thêm gem sau vào Gemfile: gem "dropzonejs-rails" gem "carrierwave" ...

1. DropzoneJS là gì##

DropzoneJS là một thư viện javascript cho phép upload nhiều file thông qua AJAX. Ngoài ra, thư viện này còn hỗ trợ tính năng kéo thả file và tính năng xem trước file ảnh đã upload.

2. Cài đặt##

Bạn thêm gem sau vào Gemfile:

gem "dropzonejs-rails"
gem "carrierwave"

Sau đó chạy lệnh:

bundle install

Trong file app/assets/javascripts/application.js, bạn thêm dòng sau:

//= require dropzone

Tiếp theo, trong file app/assets/javascripts/application.css, bạn bổ sung thêm dòng sau:

*= require dropzone/dropzone

Tạo Avartar Uploader:

rails g uploader avatar

Generate model Avatar:

rails g model avatar name:string

File app/models/avatar.rb:

class Avatar < ActiveRecord::Base
  mount_uploader :name, AvatarUploader
end

Tiếp theo, ta tạo controller app/controllers/avatars_controller.rb:

class AvatarsController < ApplicationController
  def index
    @avatars = Avatar.all
    @avatar = Avatar.new
  end
  def create
    @avatar = Avatar.new avatar_params
    if @avatar.save
      render json: { message: "success", fileID: @avatar.id }, status: 200
    else
      render json: { error: @avatar.errors.full_messages.join(',')}, status: 400
    end
  end
  private
  def avatar_params
    params.require(:avatar).permit(:name)
  end
end

Sau đó ta bổ sung nội dung vào file routes.rb các dòng sau:

resources :avatars, only: [:index, :create]
root to: "avatars#index"

Cuối cùng, ta sẽ tạo view. Đầu tiên, ta sẽ tạo index view trong file app/views/avatars/index.html.erb như sau:

<h1>My Images</h1>
<%= form_for(Avatar.new,
html: { multipart: true, class: "dropzone"}, remote: true) do |f|  %>
  <div class="fallback">
    <%= f.file_field :name %><br>
    <%= f.submit "Upload my Avatar" %>
  </div>
<% end %>
<div class="index">
  <%= render "index" %>
</div>

Bây giờ, ta sẽ tạo file app/views/avatars/_index.html.erb để hiển thi một avatar có nội dung như sau:

<% @avatars.each do |avatar| %>
  <div class="img-thumbnail">
    <%= image_tag avatar.name.url(:thumb), alt: avatar.name.url(:thumb) %>
  </div>
<% end %>

Cuối cùng, chúng ta cần sử dụng javascript để xử lý AJAX hiển thị ảnh sau khi upload. Trong file app/views/avatars/index.js.erb thêm đoạn code sau:

$(".index").html("<%= escape_javascript(render('index')) %>")

Tới đây, ta đã hoàn thành xong việc upload nhiều file dùng dropzone và carrierwave.

3. Mở rộng##

DropzoneJS còn cung cấp một số tùy chỉnh cho người dùng. Để tùy chỉnh được, ta khai báo trong file application.js như sau:

$(document).ready(function(){
  // grap our upload form by its id
  $(".dropzone").dropzone({
    // kích thước tối đa của 1 file có thể upload
    maxFilesize: 1,
    // Hiển thị link xóa trên mỗi ảnh
    addRemoveLinks: true
  });
});

Ngoài ra, trong thư viện này còn có danh sách một số sự kiện javascript như là:

addedfile : Sự kiện xảy ra khi file đã được thêm vào dropzone

success : Sự kiện xảy ra khi 1 file đã được upload thành công

Để xem thêm danh sách các sự kiện thì có thể truy cập vào đường link sau: http://www.dropzonejs.com/#events

Với việc sử dụng thư viện dropzonejs, ta đã có thêm một tùy chọn nữa trong việc upload file của rails.

Cám ơn các bạn đã đọc bài viết của mình và mong rằng chúng ta sẽ có những trao đổi hữu ích thông qua bài viết này.

Tham Khảo##

http://www.dropzonejs.com/

https://richonrails.com/articles/multiple-file-uploads-with-dropzone

0