qiniu_form 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,267 @@
1
+ //= require 'jquery.ui.sortable'
2
+ //= require 'jquery.iframe-transport'
3
+ //= require 'jquery.file-upload'
4
+
5
+ /*
6
+ upload file tag 结构
7
+
8
+ div class="ui-upload uploaded" data-type="#{type}" data-value="#{src}"
9
+ div class="ui-type-#{type} ui-upload-type"
10
+ div.ui-upload-tag.ui-wrap
11
+ span.glyphicon.glyphicon-#{type}
12
+
13
+ div.ui-upload-progress.ui-wrap
14
+
15
+ div.ui-upload-preview.ui-wrap
16
+
17
+ div.ui-upload-file.ui-wrap
18
+ input type="hidden" value="#{value}" name="#{name}"
19
+ input.file data-form-data="#{form_data}" data-name="#{name}" title="" data-url="#{url}" name="file" id="qiniu-#{uuid}" type="file"
20
+
21
+ div.ui-upload-close
22
+ span.glyphicon.glyphicon-remove
23
+ */
24
+ (function() {
25
+ 'use strict';
26
+
27
+ // 设置文件的预览
28
+ function set_tag_preview($root, data) {
29
+ var $preview,
30
+ val = data.value,
31
+ type = data.type;
32
+
33
+ if (!val || !type) return ;
34
+
35
+ $preview = $root.find('.ui-upload-preview');
36
+
37
+ switch (type) {
38
+ case 'image':
39
+ case 'avatar':
40
+ $preview.html('<img src="' + val + '"/>');
41
+ break;
42
+ case 'audio':
43
+ $preview.html('<audio controls src="' + val + '"></audio>');
44
+ break;
45
+ case 'video':
46
+ $preview.html('<video controls src="' + val + '"></video>');
47
+ break;
48
+ case 'file':
49
+ $preview.html('<a href="' + val + '">' + (data.filename || val) + '</a>');
50
+ break;
51
+ }
52
+ }
53
+
54
+ function set_tag_value($root, key) {
55
+ $root.removeClass('uploading').addClass('uploaded');
56
+ $root.find('input[type=hidden]').val(key);
57
+ }
58
+
59
+ function del_tag_value($root) {
60
+ $root
61
+ .removeClass('uploading').removeClass('uploaded')
62
+ .find('input[type=hidden]').val('');
63
+ }
64
+
65
+
66
+ // 头像选择组件
67
+ $(function() {
68
+ var $upload_root,
69
+ $container = $('.avatars_choose_container');
70
+
71
+ if (!$container.length) {
72
+ return false;
73
+ }
74
+
75
+ $(document).on('click', '.avatar-file .btn', function() {
76
+ var $btn = $(this),
77
+ center = {},
78
+ offset, size;
79
+
80
+ $upload_root = $btn.closest('.avatar-file').find('.ui-upload');
81
+
82
+ offset = $btn.offset();
83
+ size = {width: $btn.outerWidth(), height: $btn.outerHeight()};
84
+
85
+ center.x = size.width / 2 + offset.left;
86
+ center.y = size.height + offset.top;
87
+
88
+ $container.removeClass('hide');
89
+ $container.css({
90
+ top: center.y + 15,
91
+ left: center.x - $container.outerWidth() / 2
92
+ });
93
+
94
+ });
95
+
96
+ $container.on('click', 'img', function() {
97
+ var $img = $(this),
98
+ key;
99
+ key = $img.data('key');
100
+ if (key && $upload_root) {
101
+ set_tag_value($upload_root, key);
102
+ set_tag_preview($upload_root, {value: $img.attr('src'), type: 'avatar'});
103
+ $container.addClass('hide');
104
+ }
105
+ });
106
+ $container.on('click', '.close', function() {
107
+ $upload_root = null;
108
+ $container.addClass('hide');
109
+ return false;
110
+ });
111
+ $container.on('click', '.upload', function() {
112
+ if ($upload_root) {
113
+ $upload_root.find('.file').trigger('click');
114
+ return false;
115
+ }
116
+ });
117
+ });
118
+
119
+
120
+ function init_async_file_upload($elem) {
121
+ var $root = $elem.closest('.ui-upload'),
122
+ params = $root.data(),
123
+ $progress_bar = $root.find('.ui-upload-progress');
124
+
125
+ set_tag_preview($root, params);
126
+
127
+ $elem.fileupload({
128
+ dataType: 'json',
129
+ type: 'POST',
130
+ dropZone: $root,
131
+ pasteZone: $root,
132
+ add: function (e, data) {
133
+ var file = data.files[0];
134
+
135
+ if (file && file.name) {
136
+ params.filename = file.name;
137
+ }
138
+
139
+ if (file && params.type !== 'file' ) {
140
+ // 支持的文件类型,放在 types 字段中,暂时还没实现,有点乱了
141
+ var allow_types = params.types && params.types.split(',') || params.type.split(','),
142
+ type = file.type,
143
+ allowed = false;
144
+
145
+ // 有些有 file, 但 file.type = "" , 可能是客户端识别不了文件的 type
146
+ if (type !== '') {
147
+ if (params.type === 'image' || params.type === 'audio' || params.type === 'video') {
148
+ for (var allow_type, i = 0; i < allow_types.length; ++i) {
149
+ allow_type = $.trim(allow_types[i]);
150
+ if (allow_type.indexOf('/') > 0 && allow_type === type ||
151
+ allow_type.indexOf('/') < 0 && type.split('/').shift() === allow_type) {
152
+
153
+ allowed = true;
154
+ }
155
+ }
156
+ } else {
157
+ allowed = true;
158
+ }
159
+ }
160
+
161
+ if (!allowed) {
162
+ window.alerts.warning('upload_file_type_not_allowed');
163
+ return false;
164
+ }
165
+ }
166
+
167
+ $progress_bar.css('width', '1%').text('1%').parent();
168
+ $root.addClass('uploading');
169
+
170
+ data.submit()
171
+ .fail(function () {
172
+ $root.removeClass('uploading');
173
+ window.alerts.warning('Failure. Bad connection. please try again.');
174
+ });
175
+ },
176
+ progress: function(e, data) {
177
+ var percent = parseInt(data.loaded / data.total * 100, 10) + '%';
178
+ if (percent === '100%') percent = '99%';
179
+ $progress_bar.css('width', percent).text(percent);
180
+ },
181
+ done: function (e, data) {
182
+ data = data.result;
183
+ var $file_input = $root.find('input[type=file]');
184
+ var download_host = $file_input.attr('data-download-host');
185
+ var is_url_val = $file_input.attr('data-url-value');
186
+ var url = download_host + '/' + data.key;
187
+
188
+ if (is_url_val) {
189
+ params.value = url;
190
+ } else {
191
+ params.value = data.key;
192
+ }
193
+
194
+ $root.trigger('uploaded', [data]);
195
+ set_tag_value($root, params.value);
196
+
197
+ set_tag_preview($root, params);
198
+ }
199
+ });
200
+ }
201
+
202
+ $.fn.qiniu_fileupload = function () {
203
+ this.each(function () {
204
+ init_async_file_upload($(this));
205
+ });
206
+ };
207
+
208
+ /*
209
+ 七牛上传组件,它的 tag 是在后端生成的
210
+ 所以在页面加载的时候我就把一部分 tag 放在一个隐藏的 div 内
211
+ 然后在需要加载这些 tag 的地方放一个标签
212
+ */
213
+ var $container = $('.qiniu-file-tags');
214
+ $container.on('fill', function(e, placeholder_elem) {
215
+ var $children = $container.children(),
216
+ $placeholder_elem = $(placeholder_elem),
217
+ $append, data;
218
+ if (!$children.length) {
219
+ window.alerts.danger('qi_niu_file_tag_not_enough');
220
+ return ;
221
+ }
222
+
223
+ data = $placeholder_elem.data();
224
+ $append = $children.last();
225
+
226
+ $placeholder_elem.append($append);
227
+
228
+ if (data.value && data.src) {
229
+ set_tag_value($append, data.value);
230
+ set_tag_preview($append, {value: data.src, type: $append.attr('data-type')});
231
+
232
+ } else {
233
+ del_tag_value($append);
234
+ }
235
+
236
+ // 删除所有事件
237
+ // 默认通过 jQuery 移除某个 DOM 时,jQuery 会删除这个 DOM 里所有元素的所有事件
238
+ $append.off().find('input.file').qiniu_fileupload(); // 添加上传文件事件
239
+ });
240
+
241
+
242
+ $container.on('recycle', function(e, upload_elem) {
243
+ $container.append(upload_elem);
244
+ });
245
+
246
+
247
+ // 初始化
248
+ $(function() {
249
+ // 文件删除事件监控
250
+ $(document).delegate('.ui-upload-close', 'click', function() {
251
+ var $root = $(this).closest('.ui-upload');
252
+ del_tag_value($root);
253
+ });
254
+
255
+ // 初始化上传文件组件
256
+ $('.ui-upload .file').off().qiniu_fileupload();
257
+
258
+ // 部署上传文件表单
259
+ $('.qiniu-file-place').each(function() {
260
+ var $placeholder = $(this);
261
+ if (!$placeholder.find('.ui-upload').length) {
262
+ $container.trigger('fill', [this]);
263
+ }
264
+ });
265
+ });
266
+
267
+ })();
@@ -0,0 +1,284 @@
1
+ $module-content-bg: #EDEDED;
2
+ $image-file-upload-width: 150px;
3
+ $image-file-upload-height: 100px;
4
+ $avatar-file-upload-width: 100px;
5
+ $avatar-file-upload-height: 100px;
6
+ $audio-file-upload-width: 150px;
7
+ $audio-file-upload-height: 40px;
8
+ $file-upload-width: 150px;
9
+ $file-upload-height: 40px;
10
+ $video-file-upload-width: 150px;
11
+ $video-file-upload-height: 100px;
12
+
13
+
14
+ .avatars_choose_container {
15
+ position: absolute;
16
+ padding: 60px 49px 50px;
17
+ width: 400px;
18
+ border: 1px solid #B3B3B3;
19
+ border-radius: 8px;
20
+ background-color: $module-content-bg;
21
+ z-index: 1000;
22
+ box-shadow: 0 5px 10px rgba(0,0,0,.2);
23
+
24
+ .arrow, .arrow:after {
25
+ position: absolute;
26
+ display: block;
27
+ width: 0;
28
+ height: 0;
29
+ border-color: transparent;
30
+ border-style: solid;
31
+ border-width: 10px;
32
+ }
33
+
34
+ .arrow {
35
+ position: absolute;
36
+ top: -11px;
37
+ left: 50%;
38
+ margin-left: -11px;
39
+ border-width: 11px;
40
+ border-top-width: 0;
41
+ border-bottom-color: #B3B3B3;
42
+
43
+ &:after {
44
+ top: 1px;
45
+ margin-left: -10px;
46
+ content: " ";
47
+ border-top-width: 0;
48
+ border-bottom-color: $module-content-bg;
49
+ }
50
+ }
51
+
52
+ .close {
53
+ position: absolute;
54
+ right: 20px;
55
+ top: 10px;
56
+ font-size: 24px;
57
+ font-weight: normal;
58
+ }
59
+ .nav-tabs {
60
+ li {
61
+ width: 33.3333%;
62
+ }
63
+ a {
64
+ border-radius: 0;
65
+ color: #999999;
66
+ width: 100%;
67
+ padding: 8px 0;
68
+ text-align: center;
69
+ }
70
+ }
71
+ .tab-pane {
72
+ margin-top: 4px;
73
+ font-size: 0;
74
+ }
75
+ .square {
76
+ display: inline-block;
77
+ width: 50px;
78
+ height: 50px;
79
+ background-color: #EDEDED;
80
+ border: 1px solid $module-content-bg;
81
+
82
+ img {
83
+ width: 100%;
84
+ height: 100%;
85
+ vertical-align: baseline;
86
+ cursor: pointer;
87
+
88
+ &:hover {
89
+ border: 1px solid #EDEDED;
90
+ }
91
+ }
92
+ }
93
+
94
+ }
95
+
96
+ .ui-upload {
97
+ width: 100%;
98
+ overflow: visible;
99
+
100
+ .ui-upload-type {
101
+ display: block;
102
+ position: relative;
103
+ background: #fefefe;
104
+ border: 1px dashed #d3d3d3;
105
+ box-shadow: inset 0 1px 1px white;
106
+
107
+ &:hover {
108
+ background: #eee;
109
+ border-style: solid;
110
+ }
111
+ }
112
+
113
+
114
+ .ui-wrap {
115
+ position: absolute;
116
+ top: 0;
117
+ left: 0;
118
+ bottom: 0;
119
+ right: 0;
120
+ }
121
+
122
+ .ui-upload-tag {
123
+ z-index: 3;
124
+ color: #ccc;
125
+ .glyphicon {
126
+ font-size: 22px;
127
+ display: block;
128
+ width: 22px;
129
+ height: 22px;
130
+ position: absolute;
131
+ top: 0;
132
+ left: 0;
133
+ right: 0;
134
+ bottom: 0;
135
+ z-index: 10;
136
+ margin: auto;
137
+ }
138
+ }
139
+
140
+ .ui-upload-progress {
141
+ z-index: 2;
142
+ display: none;
143
+
144
+ background: #428bca;
145
+ text-align: center;
146
+ color: #ffffff;
147
+ font-weight: bold;
148
+ width: 0%;
149
+
150
+ -webkit-transition: width 0.8s ease;
151
+ transition: width 0.8s ease;
152
+ }
153
+
154
+ .ui-upload-preview {
155
+ z-index: 4;
156
+ display: none;
157
+ }
158
+
159
+ .ui-upload-file {
160
+ z-index: 5;
161
+ overflow: hidden;
162
+ .file {
163
+ opacity: 0;
164
+ -webkit-appearance: 0;
165
+ cursor: pointer;
166
+
167
+ position: absolute;
168
+ top: 0;
169
+ left: 0;
170
+ right: 0;
171
+ bottom: 0;
172
+ filter:alpha(opacity=0);
173
+ opacity: 0;
174
+ }
175
+ }
176
+
177
+
178
+ .ui-upload-close {
179
+ position: absolute;
180
+ z-index: 10;
181
+ display: none;
182
+ right: -10px;
183
+ top: -10px;
184
+ width: 24px;
185
+ height: 24px;
186
+ border-radius: 30px;
187
+ box-shadow: 1px 1px 2px rgba(0,0,0,.5), -1px -1px 2px rgba(0,0,0,.5);
188
+ background: black;
189
+ border: 2px solid white;
190
+ text-align: center;
191
+ cursor: pointer;
192
+
193
+ span {
194
+ font-size: 12px;
195
+ color: white;
196
+ }
197
+ }
198
+
199
+
200
+ // 上传中
201
+ &.uploading {
202
+ .ui-upload-file {
203
+ display: none;
204
+ }
205
+
206
+ .ui-upload-progress {
207
+ display: block;
208
+ }
209
+ }
210
+
211
+ // 上传完成
212
+ &.uploaded {
213
+ .ui-upload-file, .ui-upload-tag {
214
+ display: none;
215
+ }
216
+
217
+ .ui-upload-preview {
218
+ display: block;
219
+ }
220
+
221
+ .ui-upload-type, .ui-upload-type:hover {
222
+ border: none;
223
+ background: transparent;
224
+ }
225
+
226
+ .ui-upload-type:hover {
227
+ .ui-upload-close {
228
+ display: block;
229
+ }
230
+ }
231
+
232
+ .ui-type-file, .ui-type-file:hover {
233
+ background: #eee;
234
+ border: 1px solid #d3d3d3;
235
+ }
236
+
237
+ }
238
+
239
+
240
+ // 指定对应容器的大小
241
+ // type = image
242
+ .ui-type-image, .ui-type-image img {
243
+ width: $image-file-upload-width;
244
+ height: $image-file-upload-height;
245
+ }
246
+
247
+ // type = avatar
248
+ .ui-type-avatar, .ui-type-avatar img {
249
+ width: $avatar-file-upload-width;
250
+ height: $avatar-file-upload-height;
251
+ border-radius: $avatar-file-upload-width;
252
+ }
253
+
254
+ // type = audio
255
+ .ui-type-audio, .ui-type-audio audio {
256
+ width: $audio-file-upload-width;
257
+ height: $audio-file-upload-height;
258
+ }
259
+
260
+
261
+ // type = file
262
+ .ui-type-file {
263
+ width: $file-upload-width;
264
+ height: $file-upload-height;
265
+ }
266
+ .ui-type-file .ui-upload-preview {
267
+ overflow: hidden;
268
+ a {
269
+ display: block;
270
+ overflow: hidden;
271
+ text-overflow: ellipsis;
272
+ white-space: nowrap;
273
+ text-indent: 20px;
274
+ line-height: $file-upload-height;
275
+ }
276
+ }
277
+
278
+
279
+ // type = video
280
+ .ui-type-video, .ui-type-video video {
281
+ width: $video-file-upload-width;
282
+ height: $video-file-upload-height;
283
+ }
284
+ }
@@ -0,0 +1,32 @@
1
+ - src = value
2
+
3
+ /image/audio/video/file
4
+ / please don't change the default type
5
+ / if need change, please see connett_tools/action_view/helpers/tags/qiniu_upload_field.rb
6
+ - type ||= 'image'
7
+
8
+ div class="ui-upload #{value.blank? ? '' : 'uploaded'} file-#{name}" data-type="#{type}" data-value="#{src}"
9
+ div class="ui-type-#{type} ui-upload-type"
10
+ div.ui-upload-tag.ui-wrap
11
+ - case type
12
+ - when 'image'
13
+ span.glyphicon.glyphicon-picture
14
+ - when 'avatar'
15
+ span.glyphicon.glyphicon-user
16
+ - when 'audio'
17
+ span.glyphicon.glyphicon-music
18
+ - when 'video'
19
+ span.glyphicon.glyphicon-facetime-video
20
+ - when 'file'
21
+ span.glyphicon.glyphicon-file
22
+
23
+ div.ui-upload-progress.ui-wrap
24
+
25
+ div.ui-upload-preview.ui-wrap
26
+
27
+ div.ui-upload-file.ui-wrap
28
+ input type="hidden" value="#{value}" name="#{name}"
29
+ input.file data-form-data="#{form_data}" data-name="#{name}" title="" data-url="#{url}" name="file" id="qiniu-#{uuid}" type="file" data-download-host=download_host data-url-value=url_value
30
+
31
+ div.ui-upload-close
32
+ span.glyphicon.glyphicon-remove
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: qiniu_form
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - jiangzhi.xie
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
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
+ - !ruby/object:Gem::Dependency
42
+ name: rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '4.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: uuid
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Qiniu upload from
70
+ email:
71
+ - xiejiangzhi@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - lib/qiniu_form.rb
82
+ - lib/qiniu_form/rails.rb
83
+ - lib/qiniu_form/rails/engine.rb
84
+ - lib/qiniu_form/version.rb
85
+ - lib/qiniu_form/view_helpers/form_helper.rb
86
+ - lib/qiniu_form/view_helpers/tags/qiniu_upload_field.rb
87
+ - qiniu_form.gemspec
88
+ - vendor/assets/javascripts/jquery.file-upload.js
89
+ - vendor/assets/javascripts/jquery.iframe-transport.js
90
+ - vendor/assets/javascripts/jquery.ui.sortable.js
91
+ - vendor/assets/javascripts/qiniu_form.js
92
+ - vendor/assets/stylesheets/qiniu_from.scss
93
+ - vendor/views/_qiniu_upload_field.slim
94
+ homepage: ''
95
+ licenses:
96
+ - MIT
97
+ metadata: {}
98
+ post_install_message:
99
+ rdoc_options: []
100
+ require_paths:
101
+ - lib
102
+ required_ruby_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ requirements: []
113
+ rubyforge_project:
114
+ rubygems_version: 2.2.2
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Qiniu upload from
118
+ test_files: []