activeadmin-dropzone 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ class DropzoneController < ApplicationController
2
+
3
+ def upload
4
+ dropzone_class = params[:dropzone_class].constantize
5
+ dropzone_object = dropzone_class.new
6
+ dropzone_object.send "#{ dropzone_class.dropzone_field(:type) }=", params[:dropzonable_class] if dropzone_class.dropzone_field?(:type)
7
+ dropzone_object.send "#{ dropzone_class.dropzone_field(:data) }=", params[:file]
8
+
9
+ if dropzone_object.save
10
+ render json: dropzone_object.to_json
11
+ else
12
+ head :error and return
13
+ end
14
+ end
15
+
16
+ end
@@ -0,0 +1,18 @@
1
+ module ActiveAdmin::ViewsHelper
2
+
3
+ def render_mock_dropzone_files(dropzone_objects)
4
+ dropzone_objects.map do |dropzone_object|
5
+ {
6
+ id: dropzone_object.id,
7
+ name: dropzone_object.send(dropzone_object.class.dropzone_field(:title)),
8
+ size: dropzone_object.send(dropzone_object.class.dropzone_field(:file_size)),
9
+ url: dropzone_object.send(dropzone_object.class.dropzone_field(:url))
10
+ }
11
+ end.map do |hash|
12
+ hash.map{ |(k, v)| "#{ k }: '#{ v }'" }.join(',')
13
+ end.map do |string|
14
+ "{#{ string }}"
15
+ end.join(', ').html_safe
16
+ end
17
+
18
+ end
@@ -0,0 +1,8 @@
1
+ class DropzoneInput
2
+ include Formtastic::Inputs::Base
3
+
4
+ def to_html
5
+ template.render 'dropzone', object: object, options: options, method: method
6
+ end
7
+
8
+ end
@@ -0,0 +1,91 @@
1
+ <div id="dropzone_<%= method %>_<%= cycle(*(1..999).to_a, name: method) %>" class="dropzone">
2
+ <span class="notice"><%=t 'dropzone.drag_or_click' %></span>
3
+ <%= hidden_field_tag "#{ object.class.model_name.singular }[#{ method }_attributes][-1]", "" %>
4
+ <% object.send(method).each_with_index do |dropzone_object, index| %>
5
+ <%= hidden_field_tag "#{ object.class.model_name.singular }[#{ method }_attributes][#{ dropzone_object.id }][#{ object.class.send("dropzone_#{ method }_field", :title) }]", dropzone_object.send(object.class.send("dropzone_#{ method }_field", :title)) %>
6
+ <% end %>
7
+ </div>
8
+
9
+ <% unless options[:hint].blank? %>
10
+ <p class="inline-hints dropzone-hint"><%= options[:hint] %></p>
11
+ <% end %>
12
+
13
+ <script>
14
+ (function() {
15
+ Dropzone.autoDiscover = false;
16
+
17
+ var mockFiles = [<%= render_mock_dropzone_files(object.send(method)) %>];
18
+ var dropzone_id = "#dropzone_<%= method %>_<%= current_cycle(method) %>";
19
+ var dropzone = new Dropzone(dropzone_id, {
20
+ url: '<%= upload_dropzone_path(dropzonable_class: object.class, dropzone_class: object.class.send("dropzone_#{ method }_class")) %>',
21
+ addRemoveLinks: true,
22
+ dictCancelUpload: '<%=t "dropzone.cancel" %>',
23
+ dictRemoveFile: '<%=t "dropzone.remove" %>',
24
+ maxFiles: <%= defined?(max_files) ? '1' : 'null' %>,
25
+ sending: function(file, xhr, formData) {
26
+ xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').prop('content'));
27
+ },
28
+ success: function(file, data) {
29
+ $(dropzone_id).append('<input type="hidden" name="<%= object.class.model_name.singular %>[<%= method %>_attributes][' + data.id + '][<%= object.class.send("dropzone_#{ method }_field", :title) %>]" value="" />');
30
+ $(file.previewElement).attr('data-id', data.id);
31
+ $(file.previewElement).attr('data-url', data.url);
32
+ return file.previewElement.classList.add("dz-success");
33
+ },
34
+ removedfile: function(file) {
35
+ $(dropzone_id + ' input[name="<%= object.class.model_name.singular %>[images_attributes][' + file.id + '][<%= object.class.send("dropzone_#{ method }_field", :title) %>]"]').remove();
36
+ $(dropzone_id + ' input[name="<%= object.class.model_name.singular %>[images_attributes][' + file.id + '][<%= object.class.send("dropzone_#{ method }_field", :position) %>]"]').remove();
37
+ $(file.previewElement).remove();
38
+ $(dropzone_id).sortable('refresh');
39
+ }
40
+ });
41
+
42
+ $(dropzone_id).sortable({
43
+ items: '.dz-preview',
44
+ placeholder: 'sortable-placeholder'
45
+ });
46
+
47
+ var func = function(file) {
48
+ if (file.id)
49
+ $(file.previewElement).attr('data-id', file.id);
50
+
51
+ $(file.previewElement).find('.dz-filename, img').on('click', function() {
52
+ var id = $(this).parents('.dz-preview:first').attr('data-id');
53
+ var input = $(dropzone_id + ' input[name="<%= object.class.model_name.singular %>[<%= method %>_attributes][' + id + '][<%= object.class.send("dropzone_#{ method }_field", :title) %>]"]');
54
+ var title = prompt("<%=t 'dropzone.title' %>: ", $(file.previewElement).find('.dz-filename span').text());
55
+ $(file.previewElement).find('.dz-filename span').text(title);
56
+ input.val(title);
57
+ });
58
+ };
59
+
60
+ var generate_dropzone_position_elements = function() {
61
+ var position = 0;
62
+ $(dropzone_id + ' .dz-preview').each(function() {
63
+ var id = $(this).attr('data-id');
64
+ $(dropzone_id).append('<input type="hidden" name="<%= object.class.model_name.singular %>[<%= method %>_attributes][' + id + '][<%= object.class.send("dropzone_#{ method }_field", :position) %>]" value="' + (position++) + '" />');
65
+ });
66
+ };
67
+
68
+ dropzone.on('addedfile', func);
69
+
70
+ for (var i = 0; i < mockFiles.length; i++) {
71
+ var mockFile = mockFiles[i];
72
+ dropzone.options.addedfile.call(dropzone, mockFile);
73
+ func(mockFile);
74
+ if (mockFile.url)
75
+ dropzone.options.thumbnail.call(dropzone, mockFile, mockFile.url);
76
+ $(mockFile.previewElement).attr('data-url', mockFile.url);
77
+ }
78
+
79
+ $('form').submit(function(e) {
80
+ if (dropzone.getQueuedFiles().length > 0 || dropzone.getUploadingFiles().length > 0) {
81
+ if (confirm("<%=t 'dropzone.are_you_sure' %>") == true) {
82
+ generate_dropzone_position_elements();
83
+ } else {
84
+ e.preventDefault();
85
+ }
86
+ } else {
87
+ generate_dropzone_position_elements();
88
+ }
89
+ });
90
+ })();
91
+ </script>
@@ -0,0 +1,7 @@
1
+ en:
2
+ dropzone:
3
+ drag_or_click: 'Drag files here or click to upload'
4
+ cancel: 'Cancel'
5
+ remove: 'Remove'
6
+ title: 'Title'
7
+ are_you_sure: 'Several images have not been uploaded to the server yet. Are you sure to submit form without these images?'
@@ -0,0 +1,7 @@
1
+ ru:
2
+ dropzone:
3
+ drag_or_click: 'Перетащите сюда файлы или нажмите для загрузки'
4
+ cancel: 'Отменить'
5
+ remove: 'Удалить'
6
+ title: 'Название'
7
+ are_you_sure: 'Некоторые файлы еще не загрузились на сервер. Вы действительно хотите сохранить без них?'
data/config/routes.rb ADDED
@@ -0,0 +1,8 @@
1
+ # temporary fix double route error
2
+ unless defined?(Rails.application.routes.url_helpers.upload_dropzone_path)
3
+ Rails.application.routes.draw do
4
+
5
+ post '/dropzone/upload' => 'dropzone#upload', as: :upload_dropzone
6
+
7
+ end
8
+ end
data/lib/.DS_Store ADDED
Binary file
@@ -0,0 +1,2 @@
1
+ require "activeadmin-dropzone/engine"
2
+ require "activeadmin-dropzone/active_record/dropzone"
@@ -0,0 +1,82 @@
1
+ module Activeadmin
2
+ module Dropzone
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def dropzone(association_name)
7
+ class_eval %Q(
8
+ def self.dropzone_#{ association_name }_class
9
+ self.reflect_on_association(:#{ association_name }).class_name.constantize
10
+ end
11
+
12
+ def #{ association_name }_attributes=(attributes)
13
+ original_collection = self.#{ association_name }.to_a
14
+
15
+ ActiveRecord::Base.transaction do
16
+ self.#{ association_name } = self.class.dropzone_#{ association_name }_class.find(attributes.select{ |id, hash| !id.blank? and id != '-1' }.map{ |id, hash| id.to_i })
17
+
18
+ self.#{ association_name }.each do |dropzone_object|
19
+ attribute = attributes[dropzone_object.id.to_s]
20
+ changes = {}
21
+
22
+ title_field = self.class.dropzone_#{ association_name }_class.dropzone_field(:title)
23
+ if dropzone_object.respond_to?(title_field) and dropzone_object.send(title_field) != attribute['title']
24
+ changes[title_field] = attribute['title']
25
+ end
26
+
27
+ position_field = self.class.dropzone_#{ association_name }_class.dropzone_field(:position)
28
+ if dropzone_object.respond_to?(position_field) and dropzone_object.send(position_field) != attribute['position'].to_i
29
+ changes[position_field] = attribute['position']
30
+ end
31
+
32
+ unless changes.empty?
33
+ dropzone_object.update_attributes changes
34
+ end
35
+ end
36
+
37
+ self.update_attribute :#{ association_name }_count, self.#{ association_name }.size if self.respond_to?(:#{ association_name }_count)
38
+
39
+ (original_collection - self.#{ association_name }).each do |object|
40
+ object.destroy
41
+ end
42
+ end
43
+ end
44
+
45
+ def self.dropzone_#{ association_name }_field(key)
46
+ dropzone_#{ association_name }_class.dropzone_field(key)
47
+ end
48
+
49
+ def self.dropzone_#{ association_name }_field?(key)
50
+ dropzone_#{ association_name }_class.dropzone_field?(key)
51
+ end
52
+ )
53
+ end
54
+
55
+ def dropzone_item(options = {})
56
+ options = {
57
+ title: :title,
58
+ position: :position,
59
+ data: :data,
60
+ file_size: :data_file_size,
61
+ url: :data_url
62
+ }.deep_merge(options)
63
+
64
+ class_eval %Q(
65
+ def self.dropzone_field(key)
66
+ #{ options }[key.to_sym]
67
+ end
68
+
69
+ def self.dropzone_field?(key)
70
+ #{ options }.keys.include? key.to_sym
71
+ end
72
+
73
+ def #{ options[:data] }_url
74
+ #{ options[:data] }.url
75
+ end
76
+ )
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ ActiveRecord::Base.send :include, Activeadmin::Dropzone
@@ -0,0 +1,6 @@
1
+ module Activeadmin
2
+ module Dropzone
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'activeadmin-dropzone'
16
+
17
+ class Test::Unit::TestCase
18
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestActiveadminDropzone < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activeadmin-dropzone
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Maxim Gladkov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-02-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jeweler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: simplecov-rcov
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email: contact@maximgladkov.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files:
46
+ - LICENSE.txt
47
+ - README.md
48
+ files:
49
+ - .DS_Store
50
+ - .document
51
+ - Gemfile
52
+ - Gemfile.lock
53
+ - LICENSE.txt
54
+ - README.md
55
+ - Rakefile
56
+ - VERSION
57
+ - activeadmin-dropzone.gemspec
58
+ - app/.DS_Store
59
+ - app/assets/.DS_Store
60
+ - app/assets/images/.DS_Store
61
+ - app/assets/javascripts/activeadmin-dropzone.js
62
+ - app/assets/javascripts/dropzone.js
63
+ - app/assets/stylesheets/activeadmin-dropzone.css.scss
64
+ - app/assets/stylesheets/dropzone.css
65
+ - app/controllers/dropzone_controller.rb
66
+ - app/helpers/active_admin/views_helper.rb
67
+ - app/inputs/dropzone_input.rb
68
+ - app/views/application/_dropzone.html.erb
69
+ - config/locales/en.yml
70
+ - config/locales/ru.yml
71
+ - config/routes.rb
72
+ - lib/.DS_Store
73
+ - lib/activeadmin-dropzone.rb
74
+ - lib/activeadmin-dropzone/active_record/dropzone.rb
75
+ - lib/activeadmin-dropzone/engine.rb
76
+ - test/helper.rb
77
+ - test/test_activeadmin-dropzone.rb
78
+ homepage: http://maximgladkov.com/blog/activeadmin-dropzone-gem
79
+ licenses:
80
+ - MIT
81
+ metadata: {}
82
+ post_install_message:
83
+ rdoc_options: []
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ required_rubygems_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 2.0.3
99
+ signing_key:
100
+ specification_version: 4
101
+ summary: Easy to use integration of drag&drop files upload via dropzone.js for ActiveAdmin
102
+ test_files: []