avatars_for_rails 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -8,3 +8,4 @@ spec/dummy/public/images/tmp/
8
8
  spec/dummy/public/system/
9
9
  *.DS_Store
10
10
  .project
11
+ *.gem
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- avatars_for_rails (0.0.1)
4
+ avatars_for_rails (0.0.6)
5
5
  foreigner (~> 0.9.1)
6
6
  paperclip (~> 2.3.4)
7
7
  rmagick (~> 2.13.1)
@@ -55,7 +55,7 @@ GEM
55
55
  factory_girl (1.3.3)
56
56
  ffi (1.0.7)
57
57
  rake (>= 0.8.7)
58
- foreigner (0.9.1)
58
+ foreigner (0.9.2)
59
59
  forgery (0.3.7)
60
60
  nokogiri (~> 1.4)
61
61
  i18n (0.5.0)
@@ -68,7 +68,7 @@ GEM
68
68
  treetop (~> 1.4.8)
69
69
  mime-types (1.16)
70
70
  nokogiri (1.4.4)
71
- paperclip (2.3.10)
71
+ paperclip (2.3.11)
72
72
  activerecord (>= 2.3.0)
73
73
  activesupport (>= 2.3.2)
74
74
  polyglot (0.3.1)
@@ -132,7 +132,7 @@ DEPENDENCIES
132
132
  capybara (~> 0.3.9)
133
133
  factory_girl (~> 1.3.2)
134
134
  forgery (~> 0.3.6)
135
- rails (~> 3.0.5)
135
+ rails (>= 3.0.5)
136
136
  rspec-rails (~> 2.5.0)
137
137
  ruby-debug (~> 0.10.3)
138
138
  sqlite3-ruby
data/README.rdoc CHANGED
@@ -40,13 +40,15 @@ In your application layout you have to add this on the <head> label:
40
40
  </script>
41
41
  </head>
42
42
 
43
- In config/initializers/avatars_for_rails.rb you have to change:
43
+ In config/initializers/avatars_for_rails.rb you have to define:
44
44
 
45
- def current_avatarable_object
46
- return Actor.find(:all).first
45
+ AvatarsForRails.setup do |config|
46
+ config.avatarable_model = :actor
47
+ config.current_avatarable_object = :current_actor
47
48
  end
48
-
49
- to return the actor you wants to be the owner of the new avatars, etc For example, you can return the current logged in actor.
49
+
50
+ * actor is the name of the object owner of the avatars
51
+ * current_actor will return the actor you wants to be the owner of the new avatars, etc For example, you can return the current logged in actor. This method can be defined on the application_controller of your app.
50
52
 
51
53
  Finally, add to your actor model the relation with avatars_for_rails:
52
54
 
@@ -56,6 +58,8 @@ Now, if you go to /avatars you will see:
56
58
  * A list of all the avatars for the current actor. You can change the default and delete avatars in this list.
57
59
  * Forms for creating a new avatar with two options. A typical file filed or a drag and drop file field
58
60
 
61
+ Of course, you can overwrite the index.html.erb so you can personalize the index.
62
+
59
63
  For rendering the avatars list:
60
64
  <%= render :partial => 'list' %>
61
65
 
@@ -79,9 +83,17 @@ or
79
83
  <%= stylesheet_link_tag "jquery.fileupload-ui", :media => "screen, projection" %><br/>
80
84
  <%end%>
81
85
 
86
+ If you want to get an actor's active avatar you can do:
87
+ actor.avatars.active.first
88
+
82
89
  For rendering an image_tag for an acctor's avatar:
83
90
  <%= image_tag(avatar.logo.url(:style) ) %>
84
91
 
92
+ If you wan't to display an actor's active avatar:
93
+ <%= image_tag(actor.avatars.active.first, :id => "current_avatar_img") %>
94
+
95
+ The id of the image it's important. If it's set like this, when you change the default avatar from the list, it will change the avatar shown on the image with jquery.
96
+
85
97
  The avaible styles for now are:
86
98
 
87
99
  :representation => 20x20 px
@@ -14,7 +14,7 @@ class AvatarsController < ApplicationController
14
14
  def new
15
15
  @avatars = Avatar.all
16
16
  @avatar = Avatar.create(params[:avatar])
17
-
17
+
18
18
  if params[:drag_name].blank?
19
19
  respond_to do |format|
20
20
  format.html # new.html.erb
@@ -32,7 +32,7 @@ class AvatarsController < ApplicationController
32
32
  end
33
33
 
34
34
  def update
35
- #debugger
35
+
36
36
  if !current_avatarable_object.avatars.blank?
37
37
 
38
38
  new_logo = Avatar.find(params[:id])
@@ -40,8 +40,7 @@ class AvatarsController < ApplicationController
40
40
  if (new_logo.avatarable == current_avatarable_object)
41
41
  actual_logo = current_avatarable_object.avatars.active.first
42
42
  unless actual_logo.blank?
43
- #actual_logo.active = false
44
- #actual_logo.save
43
+ return if new_logo == actual_logo
45
44
  old_logo_id = actual_logo.id
46
45
  current_avatarable_object.avatars.each do |old_logo|
47
46
  old_logo.active = false
@@ -57,7 +56,7 @@ class AvatarsController < ApplicationController
57
56
  respond_to do |format|
58
57
  format.js { render :layout=>false , :locals=>{:new_id => params[:id],:old_id => old_logo_id}}
59
58
  end
60
-
59
+
61
60
  end
62
61
  end
63
62
 
@@ -66,10 +65,11 @@ class AvatarsController < ApplicationController
66
65
 
67
66
  def create
68
67
  @avatar = current_avatarable_object.avatars.create(params[:avatar])
69
-
68
+ #debugger
70
69
  if @avatar.new_record?
70
+ #debugger
71
71
  if (params[:avatar].blank? || params[:avatar][:drag].nil?)
72
- render :new
72
+ render :new, :layout => false
73
73
  else
74
74
  render :json => {:name => File.basename(@avatar.logo.queued_for_write[:original].path) }
75
75
  end
@@ -101,11 +101,11 @@ class AvatarsController < ApplicationController
101
101
  end
102
102
  end
103
103
  #redirect_to avatars_path
104
-
105
104
  end
106
105
 
107
- #def current_avatarable_object
108
- #return Actor.find(:all).first
109
- #end
106
+ def current_avatarable_object
107
+ __send__ AvatarsForRails.current_avatarable_object
108
+ #return Actor.find(:all).first
109
+ end
110
110
 
111
111
  end
data/app/models/avatar.rb CHANGED
@@ -14,7 +14,6 @@ class Avatar < ActiveRecord::Base
14
14
 
15
15
  after_validation :precrop_done
16
16
 
17
- #belongs_to :actor
18
17
  belongs_to AvatarsForRails.avatarable_model
19
18
 
20
19
  scope :active, where(:active => true)
@@ -1,6 +1,5 @@
1
1
  <br class="clearfloat" />
2
- <div class="space_center"></div>
3
2
 
4
- <% unless @avatar.logo.errors["invalid_type"].blank?%>
5
- <%= @avatar.logo.errors["invalid_type"]%>
3
+ <% @avatar.errors.each do |error| %>
4
+ <%= error[1]%><br/><br/>
6
5
  <% end %>
@@ -8,19 +8,13 @@
8
8
  <div class="avatars" id="all_avatars">
9
9
  <% @avatars.each do |avatar| %>
10
10
  <% unless avatar.id.blank? %>
11
- <%= div_for(avatar) do %>
12
- <div class="boxgrid captionfull">
13
- <%= image_tag(avatar.logo.url(:profile), :class => avatar.active ? 'default' : 'non_default', :size => '94x94', :id => "avatar_img_#{avatar.id}") %>
14
- <% if avatar.active %>
15
- <div class="cover boxcaption">
16
- <%= link_to "Delete avatar", avatar, :confirm => t('avatar.destroy_sure'), :method => :delete, :remote => true %>
17
- </div>
18
- <% else %>
19
- <div class="cover boxcaption">
20
- <%= link_to "Set as default", avatar, :confirm => t('avatar.set_default_sure'), :method => :put, :remote => true %>
21
- <%= link_to "Delete avatar", avatar, :confirm => t('avatar.destroy_sure'), :method => :delete, :remote => true %>
22
- </div>
23
- <% end %>
11
+ <%= div_for(avatar) do %>
12
+ <div class="boxgrid captionfull">
13
+ <%= image_tag(avatar.logo.url(:profile), :class => avatar.active ? 'default' : 'non_default', :size => '94x94', :id => "avatar_img_#{avatar.id}") %>
14
+ <div class="cover boxcaption">
15
+ <%= link_to t('avatar.set_default'), avatar, :confirm => t('avatar.set_default_sure'), :method => :put, :remote => true, :id => "avatar_link_#{avatar.id}", :style => avatar.active ? 'display:none;': 'display:solid;' %>
16
+ <%= link_to t('avatar.destroy'), avatar, :confirm => t('avatar.destroy_sure'), :method => :delete, :remote => true %>
17
+ </div>
24
18
  </div>
25
19
  <% end %>
26
20
  <% end %>
@@ -33,7 +27,4 @@
33
27
  <h2><%=t('avatar.text.new') %></h2>
34
28
  <% else %>
35
29
  <h2><%= t('avatar.new') %></h2>
36
- <% end %>
37
-
38
-
39
-
30
+ <% end %>
@@ -1,15 +1,17 @@
1
1
  <% if !@avatar.logo.errors['precrop'].blank? %>
2
- <h2><%= t('avatar.crop_image') %></h2>
2
+ <!--<h2><%= t('avatar.crop_image') %></h2>
3
3
  <br class="clearfloat" />
4
4
  <div class="space_center"></div>
5
+ -->
5
6
  <%= render :partial => 'precrop' %>
6
7
  <% elsif !@avatar.errors.blank? %>
7
8
  <%= render :partial => 'errors' %>
8
9
  <% else %>
9
- <br class="clearfloat" />
10
+ <!-- <br class="clearfloat" />
10
11
  <div class="space_center"></div>
11
12
  <div class="space_center"></div>
12
13
  <div id="content_logo">
13
14
  <%= render :partial => 'form' %>
15
+ -->
14
16
  <% end %>
15
17
 
@@ -1,6 +1,9 @@
1
1
  $("#avatar_img_<%= old_id %>").removeClass("default");
2
2
  $("#avatar_img_<%= old_id %>").addClass("non_default");
3
+ $("#avatar_link_<%= old_id %>").show();
3
4
 
4
5
  $("#avatar_img_<%= new_id %>").removeClass("non_default");
5
6
  $("#avatar_img_<%= new_id %>").addClass("default");
7
+ $("#avatar_link_<%= new_id %>").hide();
6
8
 
9
+ $("#current_avatar_img").attr('src', $("#avatar_img_<%= new_id %>").attr('src') );
@@ -2,7 +2,7 @@
2
2
  # project in your rails apps through git.
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "avatars_for_rails"
5
- s.version = "0.0.5"
5
+ s.version = "0.0.6"
6
6
  s.authors = ["Jaime Castro Montero"]
7
7
  s.summary = "Avatar manager for rails apps."
8
8
  s.description = "A Rails engine that allows any model to act as avatarable, permitting it to have a complete avatar manager with a few options."
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
20
20
 
21
21
  # Development Gem dependencies
22
22
  #
23
- s.add_development_dependency('rails', '~> 3.0.5')
23
+ s.add_development_dependency('rails', '>= 3.0.5')
24
24
  # Testing database
25
25
  s.add_development_dependency('sqlite3-ruby')
26
26
  # Debugging
@@ -4,7 +4,7 @@ en:
4
4
  avatar:
5
5
  crop_image: "Crop the uploaded image"
6
6
  crop_submit: "Crop image"
7
- destroy: "Delete"
7
+ destroy: "Delete avatar"
8
8
  destroy_sure: "Are you sure you wan't to delete the selected avatar?"
9
9
  error:
10
10
  no_file: "You have to select a file"
@@ -4,25 +4,26 @@ require 'paperclip'
4
4
 
5
5
  module AvatarsForRails
6
6
 
7
- autoload :AvatarsControllerConfig, 'avatars_for_rails/avatars_controller_config'
7
+ #autoload :AvatarsControllerConfig, 'avatars_for_rails/avatars_controller_config'
8
8
 
9
9
  mattr_accessor :avatarable_model
10
+ mattr_accessor :current_avatarable_object
10
11
 
11
12
  class << self
12
13
  def setup
13
14
  yield self
14
15
  end
15
16
  end
16
-
17
+
17
18
  class Engine < Rails::Engine
18
-
19
- config.to_prepare do
19
+ =begin
20
+ config.to_prepare do
20
21
  AvatarsController.class_eval do
21
22
  #include AvatarsForRails::AvatarsControllerConfig
22
23
  include AvatarsControllerConfig
23
- end
24
+ end
24
25
  end
25
-
26
+ =end
26
27
  end
27
-
28
+
28
29
  end
@@ -1,11 +1,4 @@
1
1
  AvatarsForRails.setup do |config|
2
2
  config.avatarable_model = :<%= file_name %>
3
- end
4
-
5
-
6
-
7
- module AvatarsForRails::AvatarsControllerConfig
8
- def current_avatarable_object
9
- return current_<%= file_name %>
10
- end
3
+ config.current_avatarable_object = :current_<%= file_name %>
11
4
  end
@@ -1,51 +1,142 @@
1
1
  /*
2
- * jQuery File Upload User Interface Plugin 3.2.2
2
+ * jQuery File Upload User Interface Plugin 4.4
3
+ * https://github.com/blueimp/jQuery-File-Upload
4
+ *
5
+ * Copyright 2010, Sebastian Tschan
6
+ * https://blueimp.net
3
7
  *
4
- * Copyright 2010, Sebastian Tschan, AQUANTUM
5
8
  * Licensed under the MIT license:
6
9
  * http://creativecommons.org/licenses/MIT/
7
- *
8
- * https://blueimp.net
9
- * http://www.aquantum.de
10
10
  */
11
11
 
12
12
  /*jslint browser: true */
13
- /*global jQuery */
13
+ /*global jQuery, FileReader, URL, webkitURL */
14
14
 
15
15
  (function ($) {
16
+ 'use strict';
16
17
 
17
- var UploadHandler,
18
- methods;
18
+ var undef = 'undefined',
19
+ func = 'function',
20
+ UploadHandler,
21
+ methods,
22
+
23
+ MultiLoader = function (callBack) {
24
+ var loaded = 0,
25
+ list = [];
26
+ this.complete = function () {
27
+ loaded += 1;
28
+ if (loaded === list.length + 1) {
29
+ // list.length * onComplete + 1 * onLoadAll
30
+ callBack(list);
31
+ loaded = 0;
32
+ list = [];
33
+ }
34
+ };
35
+ this.push = function (item) {
36
+ list.push(item);
37
+ };
38
+ this.getList = function () {
39
+ return list;
40
+ };
41
+ };
19
42
 
20
43
  UploadHandler = function (container, options) {
21
44
  var uploadHandler = this,
22
- undef = 'undefined',
23
- func = 'function',
24
45
  dragOverTimeout,
25
- isDropZoneEnlarged;
46
+ isDropZoneEnlarged,
47
+ multiLoader = new MultiLoader(function (list) {
48
+ uploadHandler.hideProgressBarAll(function () {
49
+ uploadHandler.resetProgressBarAll();
50
+ if (typeof uploadHandler.onCompleteAll === func) {
51
+ uploadHandler.onCompleteAll(list);
52
+ }
53
+ });
54
+ }),
55
+ getUploadTable = function (handler) {
56
+ return typeof handler.uploadTable === func ?
57
+ handler.uploadTable(handler) : handler.uploadTable;
58
+ },
59
+ getDownloadTable = function (handler) {
60
+ return typeof handler.downloadTable === func ?
61
+ handler.downloadTable(handler) : handler.downloadTable;
62
+ };
26
63
 
64
+ this.requestHeaders = {'Accept': 'application/json, text/javascript, */*; q=0.01'};
27
65
  this.dropZone = container;
66
+ this.imageTypes = /^image\/(gif|jpeg|png)$/;
67
+ this.previewMaxWidth = this.previewMaxHeight = 80;
68
+ this.previewLoadDelay = 100;
69
+ this.previewAsCanvas = true;
70
+ this.previewSelector = '.file_upload_preview';
28
71
  this.progressSelector = '.file_upload_progress div';
29
- this.cancelSelector = '.file_upload_cancel div';
72
+ this.cancelSelector = '.file_upload_cancel button';
30
73
  this.cssClassSmall = 'file_upload_small';
31
74
  this.cssClassLarge = 'file_upload_large';
32
75
  this.cssClassHighlight = 'file_upload_highlight';
33
76
  this.dropEffect = 'highlight';
34
- this.uploadTable = this.downloadTable = $();
35
-
36
- this.buildUploadRow = this.buildDownloadRow = function () {
37
- return null;
77
+ this.uploadTable = this.downloadTable = null;
78
+ this.buildUploadRow = this.buildDownloadRow = null;
79
+ this.progressAllNode = null;
80
+
81
+ this.loadImage = function (file, callBack, maxWidth, maxHeight, imageTypes, noCanvas) {
82
+ var img,
83
+ scaleImage,
84
+ urlAPI,
85
+ fileReader;
86
+ if (imageTypes && !imageTypes.test(file.type)) {
87
+ return null;
88
+ }
89
+ scaleImage = function (img) {
90
+ var canvas = document.createElement('canvas'),
91
+ scale = Math.min(
92
+ (maxWidth || img.width) / img.width,
93
+ (maxHeight || img.height) / img.height
94
+ );
95
+ if (scale > 1) {
96
+ scale = 1;
97
+ }
98
+ img.width = parseInt(img.width * scale, 10);
99
+ img.height = parseInt(img.height * scale, 10);
100
+ if (noCanvas || typeof canvas.getContext !== func) {
101
+ return img;
102
+ }
103
+ canvas.width = img.width;
104
+ canvas.height = img.height;
105
+ canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
106
+ return canvas;
107
+ };
108
+ img = document.createElement('img');
109
+ urlAPI = typeof URL !== undef ? URL : typeof webkitURL !== undef ? webkitURL : null;
110
+ if (urlAPI && typeof urlAPI.createObjectURL === func) {
111
+ img.onload = function () {
112
+ urlAPI.revokeObjectURL(this.src);
113
+ callBack(scaleImage(img));
114
+ };
115
+ img.src = urlAPI.createObjectURL(file);
116
+ } else if (typeof FileReader !== undef &&
117
+ typeof FileReader.prototype.readAsDataURL === func) {
118
+ img.onload = function () {
119
+ callBack(scaleImage(img));
120
+ };
121
+ fileReader = new FileReader();
122
+ fileReader.onload = function (e) {
123
+ img.src = e.target.result;
124
+ };
125
+ fileReader.readAsDataURL(file);
126
+ } else {
127
+ callBack(null);
128
+ }
38
129
  };
39
130
 
40
131
  this.addNode = function (parentNode, node, callBack) {
41
- if (node) {
132
+ if (parentNode && parentNode.length && node && node.length) {
42
133
  node.css('display', 'none').appendTo(parentNode).fadeIn(function () {
43
134
  if (typeof callBack === func) {
44
135
  try {
45
136
  callBack();
46
137
  } catch (e) {
47
138
  // Fix endless exception loop:
48
- $(this).stop();
139
+ node.stop();
49
140
  throw e;
50
141
  }
51
142
  }
@@ -56,15 +147,15 @@
56
147
  };
57
148
 
58
149
  this.removeNode = function (node, callBack) {
59
- if (node) {
150
+ if (node && node.length) {
60
151
  node.fadeOut(function () {
61
- $(this).remove();
152
+ node.remove();
62
153
  if (typeof callBack === func) {
63
154
  try {
64
155
  callBack();
65
156
  } catch (e) {
66
157
  // Fix endless exception loop:
67
- $(this).stop();
158
+ node.stop();
68
159
  throw e;
69
160
  }
70
161
  }
@@ -73,68 +164,204 @@
73
164
  callBack();
74
165
  }
75
166
  };
167
+
168
+ this.replaceNode = function (oldNode, newNode, callBack) {
169
+ if (oldNode && newNode) {
170
+ oldNode.fadeOut(function () {
171
+ newNode.css('display', 'none');
172
+ oldNode.replaceWith(newNode);
173
+ newNode.fadeIn(function () {
174
+ if (typeof callBack === func) {
175
+ try {
176
+ callBack();
177
+ } catch (e) {
178
+ // Fix endless exception loop:
179
+ oldNode.stop();
180
+ newNode.stop();
181
+ throw e;
182
+ }
183
+ }
184
+ });
185
+ });
186
+ } else if (typeof callBack === func) {
187
+ callBack();
188
+ }
189
+ };
190
+
191
+ this.resetProgressBarAll = function () {
192
+ if (uploadHandler.progressbarAll) {
193
+ uploadHandler.progressbarAll.progressbar(
194
+ 'value',
195
+ 0
196
+ );
197
+ }
198
+ };
199
+
200
+ this.hideProgressBarAll = function (callBack) {
201
+ if (uploadHandler.progressbarAll && !$(getUploadTable(uploadHandler))
202
+ .find(uploadHandler.progressSelector + ':visible:first').length) {
203
+ uploadHandler.progressbarAll.fadeOut(callBack);
204
+ } else if (typeof callBack === func) {
205
+ callBack();
206
+ }
207
+ };
76
208
 
77
209
  this.onAbort = function (event, files, index, xhr, handler) {
78
- uploadHandler.removeNode(handler.uploadRow);
210
+ handler.removeNode(handler.uploadRow, handler.hideProgressBarAll);
79
211
  };
80
212
 
81
213
  this.cancelUpload = function (event, files, index, xhr, handler) {
82
214
  var readyState = xhr.readyState;
83
215
  xhr.abort();
84
216
  // If readyState is below 2, abort() has no effect:
85
- if (isNaN(readyState) || readyState < 2) {
217
+ if (typeof readyState !== 'number' || readyState < 2) {
86
218
  handler.onAbort(event, files, index, xhr, handler);
87
219
  }
88
220
  };
89
221
 
90
222
  this.initProgressBar = function (node, value) {
223
+ if (!node || !node.length) {
224
+ return null;
225
+ }
91
226
  if (typeof node.progressbar === func) {
92
227
  return node.progressbar({
93
228
  value: value
94
229
  });
95
230
  } else {
96
- var progressbar = $('<progress value="' + value + '" max="100"/>').appendTo(node);
97
- progressbar.progressbar = function (key, value) {
98
- progressbar.attr('value', value);
99
- };
100
- return progressbar;
231
+ node.addClass('progressbar')
232
+ .append($('<div/>').css('width', value + '%'))
233
+ .progressbar = function (key, value) {
234
+ return this.each(function () {
235
+ if (key === 'destroy') {
236
+ $(this).removeClass('progressbar').empty();
237
+ } else {
238
+ $(this).children().css('width', value + '%');
239
+ }
240
+ });
241
+ };
242
+ return node;
101
243
  }
102
244
  };
103
245
 
104
- this.initUploadRow = function (event, files, index, xhr, handler, callBack) {
105
- var uploadRow = handler.uploadRow = uploadHandler.buildUploadRow(files, index);
106
- if (uploadRow) {
107
- handler.progressbar = uploadHandler.initProgressBar(
108
- uploadRow.find(uploadHandler.progressSelector),
109
- (xhr.upload ? 0 : 100)
110
- );
111
- uploadRow.find(uploadHandler.cancelSelector).click(function (e) {
112
- uploadHandler.cancelUpload(e, files, index, xhr, handler);
113
- });
246
+ this.destroyProgressBar = function (node) {
247
+ if (!node || !node.length) {
248
+ return null;
114
249
  }
115
- uploadHandler.addNode(uploadHandler.uploadTable, uploadRow, callBack);
250
+ return node.progressbar('destroy');
116
251
  };
117
252
 
118
- this.initUpload = function (event, files, index, xhr, handler, callBack) {
119
- uploadHandler.initUploadRow(event, files, index, xhr, handler, function () {
120
- if (typeof uploadHandler.beforeSend === func) {
121
- uploadHandler.beforeSend(event, files, index, xhr, handler, callBack);
122
- } else {
123
- callBack();
124
- }
125
- });
253
+ this.initUploadProgress = function (xhr, handler) {
254
+ if (!xhr.upload && handler.progressbar) {
255
+ handler.progressbar.progressbar(
256
+ 'value',
257
+ 100 // indeterminate progress displayed by a full animated progress bar
258
+ );
259
+ }
126
260
  };
127
-
261
+
262
+ this.initUploadProgressAll = function () {
263
+ if (uploadHandler.progressbarAll && uploadHandler.progressbarAll.is(':hidden')) {
264
+ uploadHandler.progressbarAll.fadeIn();
265
+ }
266
+ };
267
+
268
+ this.onSend = function (event, files, index, xhr, handler) {
269
+ handler.initUploadProgress(xhr, handler);
270
+ };
271
+
128
272
  this.onProgress = function (event, files, index, xhr, handler) {
129
- if (handler.progressbar) {
273
+ if (handler.progressbar && event.lengthComputable) {
130
274
  handler.progressbar.progressbar(
131
275
  'value',
132
276
  parseInt(event.loaded / event.total * 100, 10)
133
277
  );
134
278
  }
135
279
  };
280
+
281
+ this.onProgressAll = function (event, list) {
282
+ if (uploadHandler.progressbarAll && event.lengthComputable) {
283
+ uploadHandler.progressbarAll.progressbar(
284
+ 'value',
285
+ parseInt(event.loaded / event.total * 100, 10)
286
+ );
287
+ }
288
+ };
289
+
290
+ this.onLoadAll = function (list) {
291
+ multiLoader.complete();
292
+ };
293
+
294
+ this.initProgressBarAll = function () {
295
+ if (!uploadHandler.progressbarAll) {
296
+ uploadHandler.progressbarAll = uploadHandler.initProgressBar(
297
+ (typeof uploadHandler.progressAllNode === func ?
298
+ uploadHandler.progressAllNode(uploadHandler) : uploadHandler.progressAllNode),
299
+ 0
300
+ );
301
+ }
302
+ };
303
+
304
+ this.destroyProgressBarAll = function () {
305
+ uploadHandler.destroyProgressBar(uploadHandler.progressbarAll);
306
+ };
307
+
308
+ this.loadPreviewImage = function (files, index, handler) {
309
+ index = index || 0;
310
+ handler.uploadRow.find(handler.previewSelector).each(function () {
311
+ var previewNode = $(this),
312
+ file = files[index];
313
+ setTimeout(function () {
314
+ handler.loadImage(
315
+ file,
316
+ function (img) {
317
+ handler.addNode(
318
+ previewNode,
319
+ $(img)
320
+ );
321
+ },
322
+ handler.previewMaxWidth,
323
+ handler.previewMaxHeight,
324
+ handler.imageTypes,
325
+ !handler.previewAsCanvas
326
+ );
327
+ }, handler.previewLoadDelay);
328
+ index += 1;
329
+ });
330
+ };
331
+
332
+ this.initUploadRow = function (event, files, index, xhr, handler) {
333
+ var uploadRow = handler.uploadRow = (typeof handler.buildUploadRow === func ?
334
+ handler.buildUploadRow(files, index, handler) : null);
335
+ if (uploadRow) {
336
+ handler.progressbar = handler.initProgressBar(
337
+ uploadRow.find(handler.progressSelector),
338
+ 0
339
+ );
340
+ uploadRow.find(handler.cancelSelector).click(function (e) {
341
+ handler.cancelUpload(e, files, index, xhr, handler);
342
+ e.preventDefault();
343
+ });
344
+ handler.loadPreviewImage(files, index, handler);
345
+ }
346
+ };
136
347
 
137
- this.parseResponse = function (xhr) {
348
+ this.initUpload = function (event, files, index, xhr, handler, callBack) {
349
+ handler.initUploadRow(event, files, index, xhr, handler);
350
+ handler.addNode(
351
+ getUploadTable(handler),
352
+ handler.uploadRow,
353
+ function () {
354
+ if (typeof handler.beforeSend === func) {
355
+ handler.beforeSend(event, files, index, xhr, handler, callBack);
356
+ } else {
357
+ callBack();
358
+ }
359
+ }
360
+ );
361
+ handler.initUploadProgressAll();
362
+ };
363
+
364
+ this.parseResponse = function (xhr, handler) {
138
365
  if (typeof xhr.responseText !== undef) {
139
366
  return $.parseJSON(xhr.responseText);
140
367
  } else {
@@ -143,30 +370,44 @@
143
370
  }
144
371
  };
145
372
 
146
- this.initDownloadRow = function (event, files, index, xhr, handler, callBack) {
373
+ this.initDownloadRow = function (event, files, index, xhr, handler) {
147
374
  var json, downloadRow;
148
375
  try {
149
- json = handler.response = uploadHandler.parseResponse(xhr);
150
- downloadRow = handler.downloadRow = uploadHandler.buildDownloadRow(json);
151
- uploadHandler.addNode(uploadHandler.downloadTable, downloadRow, callBack);
376
+ json = handler.response = handler.parseResponse(xhr, handler);
152
377
  } catch (e) {
153
- if (typeof uploadHandler.onError === func) {
378
+ if (typeof handler.onError === func) {
154
379
  handler.originalEvent = event;
155
- uploadHandler.onError(e, files, index, xhr, handler);
380
+ handler.onError(e, files, index, xhr, handler);
156
381
  } else {
157
382
  throw e;
158
383
  }
159
384
  }
385
+ downloadRow = handler.downloadRow = (typeof handler.buildDownloadRow === func ?
386
+ handler.buildDownloadRow(json, handler) : null);
160
387
  };
161
388
 
162
389
  this.onLoad = function (event, files, index, xhr, handler) {
163
- uploadHandler.removeNode(handler.uploadRow, function () {
164
- uploadHandler.initDownloadRow(event, files, index, xhr, handler, function () {
165
- if (typeof uploadHandler.onComplete === func) {
166
- uploadHandler.onComplete(event, files, index, xhr, handler);
390
+ var uploadTable = getUploadTable(handler),
391
+ downloadTable = getDownloadTable(handler),
392
+ callBack = function () {
393
+ if (typeof handler.onComplete === func) {
394
+ handler.onComplete(event, files, index, xhr, handler);
167
395
  }
396
+ multiLoader.complete();
397
+ };
398
+ multiLoader.push(Array.prototype.slice.call(arguments, 1));
399
+ handler.initDownloadRow(event, files, index, xhr, handler);
400
+ if (uploadTable && (!downloadTable || uploadTable.get(0) === downloadTable.get(0))) {
401
+ handler.replaceNode(handler.uploadRow, handler.downloadRow, callBack);
402
+ } else {
403
+ handler.removeNode(handler.uploadRow, function () {
404
+ handler.addNode(
405
+ downloadTable,
406
+ handler.downloadRow,
407
+ callBack
408
+ );
168
409
  });
169
- });
410
+ }
170
411
  };
171
412
 
172
413
  this.dropZoneEnlarge = function () {
@@ -229,6 +470,20 @@
229
470
  }
230
471
  };
231
472
 
473
+ this.init = function () {
474
+ uploadHandler.initProgressBarAll();
475
+ if (typeof uploadHandler.initExtended === func) {
476
+ uploadHandler.initExtended();
477
+ }
478
+ };
479
+
480
+ this.destroy = function () {
481
+ if (typeof uploadHandler.destroyExtended === func) {
482
+ uploadHandler.destroyExtended();
483
+ }
484
+ uploadHandler.destroyProgressBarAll();
485
+ };
486
+
232
487
  $.extend(this, options);
233
488
  };
234
489
 
@@ -238,11 +493,26 @@
238
493
  $(this).fileUpload(new UploadHandler($(this), options));
239
494
  });
240
495
  },
241
-
496
+
497
+ option: function (option, value, namespace) {
498
+ if (!option || (typeof option === 'string' && typeof value === undef)) {
499
+ return $(this).fileUpload('option', option, value, namespace);
500
+ }
501
+ return this.each(function () {
502
+ $(this).fileUpload('option', option, value, namespace);
503
+ });
504
+ },
505
+
242
506
  destroy : function (namespace) {
243
507
  return this.each(function () {
244
508
  $(this).fileUpload('destroy', namespace);
245
509
  });
510
+ },
511
+
512
+ upload: function (files, namespace) {
513
+ return this.each(function () {
514
+ $(this).fileUpload('upload', files, namespace);
515
+ });
246
516
  }
247
517
  };
248
518
 
@@ -252,7 +522,7 @@
252
522
  } else if (typeof method === 'object' || !method) {
253
523
  return methods.init.apply(this, arguments);
254
524
  } else {
255
- $.error('Method ' + method + ' does not exist on jQuery.fileUploadUI');
525
+ $.error('Method "' + method + '" does not exist on jQuery.fileUploadUI');
256
526
  }
257
527
  };
258
528