Dropzone.js + rails để upload multiple file theo cách bạn muốn

Tram Ho

Khi nói về việc upload file trong một ứng dụng web, cách mà hầu như chúng ta đều nghĩ đến là sử dụng form với một thẻ <input type="file"> :

Cách làm trên tạo ra một trải nghiệm upload file khá tẻ nhạt như thế này:

So với cách làm trên, thư viện Dropzone.js cung cấp cho người dùng một trải nghiệm upload file thân thiện hơn rất nhiều như thế này:

Thư viện này cung cấp một hệ thống settings rất rõ ràng và dễ để config lại từ view template, quá trình upload fiile, validate file, …. Các bạn có thể nghiên cứu cách sử dụng nó tại đây .
Còn ở bài viết lần này, mình sẽ hướng dẫn các bạn sử dụng dropzone.js và carrierwave để tạo một media gallery(lưu trữ file video, audio và image) cơ bản dựa trên framework rails.

Tạo rails app

Mình sẽ tạo một rails app đơn giản với thông tin như sau:

  • Có một bảng Media để lưu lại thông tin các file tải lên.
  • Có một trang để thực hiện tải file lên.
  • Có một trang để hiển thị tất cả các file đã tải lên.

Đầu tiên, các bạn tạo một rails app cơ bản có cài 2 gem sau

Tạo model Media và một FileUploader

Bây giờ mình sẽ bắt đầu tạo trang tải file lên. Tạo đường dẫn cho trang đó trước trong file routes.rb :

Tạo controller với action new tương ứng cho trang tải file lên:

Tạo view cho trang tải file: new.html.erb

Và chúng ta sẽ được 1 cái view như thế này.

Bây giờ chúng ta sẽ xử lý upload file thông qua các hàm của thư viện dropzone trong 1 file javascript, mình đêt tên nó là upload.js.
Đầu tiên, thêm file upload.js vào asset pipelines:

Tạo file app/assets/javascripts/upload.js

Ở file js trên, ta khởi tạo một đối tượng Dropzone với các thuộc tính:

  • dictDefaultMessage: Là message hiển thị trong các element có class là .dropzone. Ở đây mình để trống để custom lại view.
  • uploadMultiple: true . Cho phép bạn lựa chọn upload nhiều file.
  • url: là đường dẫn để thực hiện POST request sau khi file tải lên.
    Hiện tại khi click vào div#mydropzone sẽ có cửa sổ upload file hiện lên như thế này:

    Nhưng mình muốn chỉ khi click vào button chọn nút này để tải file lênthì mới có cửa sổ chọn file hiện lên, nên mình sẽ custom thêm 1 thuộc tính clickable :

Giờ thì có vẻ nó đã hoạt động theo đúng ý mình :

Bây giờ, mặc định khi bạn chọn file trong cửa sổ vừa hiện lên hoặc kéo/thả file vào div#dropzone như thế này thì một request POST /medias sẽ được thực hiện:

Và dữ liệu mà nó truyền lên server trong params sẽ như thế này:

Bây giờ mình sẽ xử lý phía server để có thể lưu dữ liệu này vào trong db

Như vậy là dữ liệu, sau khi được upload sẽ được lưu trực tiếp vào database. Giờ mình muốn xử lý , để ngay sau khi upload tất cả các file thành công thì redirect đến trang hiển thị list tất cả các ảnh .
Đầu tiên, ta xử lý sự kiện successmultiple cho biến dropzone như sau:

Với việc xử lý như trên, sau khi tất cả các file được upload thành công, trình duyệt sẽ tự động redirect sang trang hiển thị list /medias.
Ta tạo cho trang hiển thị list:

Và cùng xem phần xử lý:

Validate ở client_size với dropzone.js

Ở đây, mình chỉ muốn upload các file với định dạng ".jpg, .png, .mp4, .mp3" và file có size nhỏ hơn 10Mb thì có thể thêm 2 thuộc tính vào biến dropzone là acceptedFilesmaxFilesize

Và error message sẽ được hiển thị như sau:

Ngoài ra, còn rất nhiều thuộc tính và sự kiện khác mà bạn có thể custom tại đây .
Bài viết của mình tạm dừng ở đây.


Tài liệu tham khảo: https://www.dropzonejs.com/

Chia sẻ bài viết ngay

Nguồn bài viết : Viblo