jbasdf-uploader 0.1.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +323 -0
  3. data/Rakefile +67 -0
  4. data/TODO +3 -0
  5. data/VERSION +1 -0
  6. data/app/controllers/uploader/uploads_controller.rb +126 -0
  7. data/app/helpers/uploader_helper.rb +17 -0
  8. data/app/views/uploads/_swf_javascript.html.erb +63 -0
  9. data/app/views/uploads/_swf_upload.html.erb +32 -0
  10. data/config/uploader_routes.rb +3 -0
  11. data/db/migrate/20090517040220_create_uploads.rb +38 -0
  12. data/lib/active_record/acts/uploader_upload.rb +234 -0
  13. data/lib/daemons/amazonaws.rb +36 -0
  14. data/lib/uploader.rb +24 -0
  15. data/lib/uploader/exceptions.rb +5 -0
  16. data/lib/uploader/initialize_routes.rb +8 -0
  17. data/lib/uploader/middleware/flash_session_cookie_middleware.rb +18 -0
  18. data/lib/uploader/mime_type_groups.rb +18 -0
  19. data/lib/uploader/tasks.rb +42 -0
  20. data/locales/ar.yml +17 -0
  21. data/locales/bg.yml +17 -0
  22. data/locales/ca.yml +17 -0
  23. data/locales/cs.yml +17 -0
  24. data/locales/da.yml +17 -0
  25. data/locales/de.yml +17 -0
  26. data/locales/el.yml +17 -0
  27. data/locales/en.yml +16 -0
  28. data/locales/es.yml +17 -0
  29. data/locales/fr.yml +17 -0
  30. data/locales/it.yml +17 -0
  31. data/locales/iw.yml +17 -0
  32. data/locales/ja.yml +17 -0
  33. data/locales/ko.yml +17 -0
  34. data/locales/lt.yml +17 -0
  35. data/locales/lv.yml +17 -0
  36. data/locales/nl.yml +17 -0
  37. data/locales/no.yml +18 -0
  38. data/locales/pl.yml +17 -0
  39. data/locales/pt.yml +17 -0
  40. data/locales/ro.yml +17 -0
  41. data/locales/ru.yml +17 -0
  42. data/locales/sk.yml +17 -0
  43. data/locales/sl.yml +17 -0
  44. data/locales/sr.yml +17 -0
  45. data/locales/sv.yml +17 -0
  46. data/locales/tl.yml +17 -0
  47. data/locales/uk.yml +17 -0
  48. data/locales/vi.yml +17 -0
  49. data/locales/zh-CN.yml +17 -0
  50. data/locales/zh-TW.yml +17 -0
  51. data/locales/zh.yml +17 -0
  52. data/public/images/SWFUploadButton.png +0 -0
  53. data/public/images/file_icons/excel.gif +0 -0
  54. data/public/images/file_icons/file.gif +0 -0
  55. data/public/images/file_icons/file.png +0 -0
  56. data/public/images/file_icons/file_aac.gif +0 -0
  57. data/public/images/file_icons/file_ai.gif +0 -0
  58. data/public/images/file_icons/file_avi.gif +0 -0
  59. data/public/images/file_icons/file_bin.gif +0 -0
  60. data/public/images/file_icons/file_bmp.gif +0 -0
  61. data/public/images/file_icons/file_cue.gif +0 -0
  62. data/public/images/file_icons/file_divx.gif +0 -0
  63. data/public/images/file_icons/file_doc.gif +0 -0
  64. data/public/images/file_icons/file_eps.gif +0 -0
  65. data/public/images/file_icons/file_flac.gif +0 -0
  66. data/public/images/file_icons/file_flv.gif +0 -0
  67. data/public/images/file_icons/file_gif.gif +0 -0
  68. data/public/images/file_icons/file_html.gif +0 -0
  69. data/public/images/file_icons/file_ical.gif +0 -0
  70. data/public/images/file_icons/file_indd.gif +0 -0
  71. data/public/images/file_icons/file_inx.gif +0 -0
  72. data/public/images/file_icons/file_iso.gif +0 -0
  73. data/public/images/file_icons/file_jpg.gif +0 -0
  74. data/public/images/file_icons/file_mov.gif +0 -0
  75. data/public/images/file_icons/file_mp3.gif +0 -0
  76. data/public/images/file_icons/file_mpg.gif +0 -0
  77. data/public/images/file_icons/file_pdf.gif +0 -0
  78. data/public/images/file_icons/file_php.gif +0 -0
  79. data/public/images/file_icons/file_png.gif +0 -0
  80. data/public/images/file_icons/file_pps.gif +0 -0
  81. data/public/images/file_icons/file_ppt.gif +0 -0
  82. data/public/images/file_icons/file_psd.gif +0 -0
  83. data/public/images/file_icons/file_qxd.gif +0 -0
  84. data/public/images/file_icons/file_qxp.gif +0 -0
  85. data/public/images/file_icons/file_raw.gif +0 -0
  86. data/public/images/file_icons/file_rtf.gif +0 -0
  87. data/public/images/file_icons/file_svg.gif +0 -0
  88. data/public/images/file_icons/file_tif.gif +0 -0
  89. data/public/images/file_icons/file_txt.gif +0 -0
  90. data/public/images/file_icons/file_vcf.gif +0 -0
  91. data/public/images/file_icons/file_wav.gif +0 -0
  92. data/public/images/file_icons/file_wma.gif +0 -0
  93. data/public/images/file_icons/file_xls.gif +0 -0
  94. data/public/images/file_icons/file_xml.gif +0 -0
  95. data/public/images/file_icons/mp3.gif +0 -0
  96. data/public/images/file_icons/pdf.gif +0 -0
  97. data/public/images/file_icons/pdf.png +0 -0
  98. data/public/images/file_icons/text.gif +0 -0
  99. data/public/images/file_icons/text.png +0 -0
  100. data/public/images/file_icons/word.gif +0 -0
  101. data/public/javascripts/swfupload/fileprogress.js +151 -0
  102. data/public/javascripts/swfupload/handlers.js +206 -0
  103. data/public/javascripts/swfupload/swfupload.cookies.js +53 -0
  104. data/public/javascripts/swfupload/swfupload.js +945 -0
  105. data/public/javascripts/swfupload/swfupload.queue.js +77 -0
  106. data/public/javascripts/swfupload/swfupload.swfobject.js +110 -0
  107. data/public/stylesheets/swfupload.css +26 -0
  108. data/public/swf/swfupload.swf +0 -0
  109. data/rails/init.rb +10 -0
  110. data/rdoc/classes/ActionController.html +107 -0
  111. data/rdoc/classes/ActionController/Routing.html +107 -0
  112. data/rdoc/classes/ActionController/Routing/RouteSet.html +148 -0
  113. data/rdoc/classes/ActiveRecord.html +105 -0
  114. data/rdoc/classes/ActiveRecord/Acts/UploaderUpload/ClassMethods.html +186 -0
  115. data/rdoc/classes/ActiveRecord/Acts/UploaderUpload/InstanceMethods.html +750 -0
  116. data/rdoc/classes/ActiveRecord/Acts/UploaderUpload/SingletonMethods.html +111 -0
  117. data/rdoc/classes/Uploader.html +126 -0
  118. data/rdoc/classes/Uploader/Exceptions.html +111 -0
  119. data/rdoc/classes/Uploader/Exceptions/MissingTemplateError.html +111 -0
  120. data/rdoc/classes/Uploader/FlashSessionCookieMiddleware.html +177 -0
  121. data/rdoc/classes/Uploader/MimeTypeGroups.html +143 -0
  122. data/rdoc/classes/Uploader/Tasks.html +146 -0
  123. data/rdoc/created.rid +1 -0
  124. data/rdoc/files/README_rdoc.html +501 -0
  125. data/rdoc/files/lib/active_record/acts/uploader_upload_rb.html +101 -0
  126. data/rdoc/files/lib/uploader/exceptions_rb.html +101 -0
  127. data/rdoc/files/lib/uploader/initialize_routes_rb.html +101 -0
  128. data/rdoc/files/lib/uploader/middleware/flash_session_cookie_middleware_rb.html +108 -0
  129. data/rdoc/files/lib/uploader/mime_type_groups_rb.html +101 -0
  130. data/rdoc/files/lib/uploader/tasks_rb.html +110 -0
  131. data/rdoc/files/lib/uploader_rb.html +112 -0
  132. data/rdoc/fr_class_index.html +39 -0
  133. data/rdoc/fr_file_index.html +35 -0
  134. data/rdoc/fr_method_index.html +54 -0
  135. data/rdoc/index.html +24 -0
  136. data/rdoc/rdoc-style.css +208 -0
  137. data/tasks/rails.rake +2 -0
  138. data/test/test_helper.rb +3 -0
  139. data/test/unit/upload_test.rb +5 -0
  140. data/uninstall.rb +0 -0
  141. data/uploader.gemspec +182 -0
  142. metadata +204 -0
data/rdoc/created.rid ADDED
@@ -0,0 +1 @@
1
+ Sat, 30 May 2009 16:52:50 -0600
@@ -0,0 +1,501 @@
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!DOCTYPE html
3
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
+
6
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7
+ <head>
8
+ <title>File: README.rdoc</title>
9
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10
+ <meta http-equiv="Content-Script-Type" content="text/javascript" />
11
+ <link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
12
+ <script type="text/javascript">
13
+ // <![CDATA[
14
+
15
+ function popupCode( url ) {
16
+ window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17
+ }
18
+
19
+ function toggleCode( id ) {
20
+ if ( document.getElementById )
21
+ elem = document.getElementById( id );
22
+ else if ( document.all )
23
+ elem = eval( "document.all." + id );
24
+ else
25
+ return false;
26
+
27
+ elemStyle = elem.style;
28
+
29
+ if ( elemStyle.display != "block" ) {
30
+ elemStyle.display = "block"
31
+ } else {
32
+ elemStyle.display = "none"
33
+ }
34
+
35
+ return true;
36
+ }
37
+
38
+ // Make codeblocks hidden by default
39
+ document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40
+
41
+ // ]]>
42
+ </script>
43
+
44
+ </head>
45
+ <body>
46
+
47
+
48
+
49
+ <div id="fileHeader">
50
+ <h1>README.rdoc</h1>
51
+ <table class="header-table">
52
+ <tr class="top-aligned-row">
53
+ <td><strong>Path:</strong></td>
54
+ <td>README.rdoc
55
+ </td>
56
+ </tr>
57
+ <tr class="top-aligned-row">
58
+ <td><strong>Last Update:</strong></td>
59
+ <td>Thu May 28 19:40:14 -0600 2009</td>
60
+ </tr>
61
+ </table>
62
+ </div>
63
+ <!-- banner header -->
64
+
65
+ <div id="bodyContent">
66
+
67
+
68
+
69
+ <div id="contextContent">
70
+
71
+ <div id="description">
72
+ <h1><a href="../classes/Uploader.html">Uploader</a></h1>
73
+ <p>
74
+ <a href="../classes/Uploader.html">Uploader</a> makes it easy to integrate
75
+ multiple file uploads into your application using SWFUpload
76
+ </p>
77
+ <h2>Installation</h2>
78
+ <h3>Install Dependancies:</h3>
79
+ <p>
80
+ sudo gem install mime-types
81
+ </p>
82
+ <h3>Install the gem:</h3>
83
+ <p>
84
+ sudo gem install uploader
85
+ </p>
86
+ <h3>Add the gem to environment.rb</h3>
87
+ <p>
88
+ config.gem &#8216;uploader&#8216;
89
+ </p>
90
+ <h3>Install jQuery</h3>
91
+ <p>
92
+ uploader uses jQuery. You&#8216;ll need to include it in your application.
93
+ Download it here: <a href="http://jquery.com">jquery.com</a>/
94
+ </p>
95
+ <p>
96
+ Then include it in your layout:
97
+ </p>
98
+ <pre>
99
+ &lt;%= javascript_include_tag 'jquery/jquery.js' %&gt;
100
+ </pre>
101
+ <p>
102
+ Another option is to use jRails <a
103
+ href="http://ennerchi.com/projects/jrails">ennerchi.com/projects/jrails</a>
104
+ </p>
105
+ <h3>Create a model for uploads.</h3>
106
+ <p>
107
+ We recommend creating a model called upload.rb. acts_as_uploader accepts
108
+ all valid options for paperclip via :has_attached_file =&gt; {}
109
+ </p>
110
+ <pre>
111
+ class Upload &lt; ActiveRecord::Base
112
+
113
+ acts_as_uploader :enable_s3 =&gt; false,
114
+ :has_attached_file =&gt; {
115
+ :url =&gt; &quot;/system/:attachment/:id_partition/:style/:basename.:extension&quot;,
116
+ :path =&gt; &quot;:rails_root/public/system/:attachment/:id_partition/:style/:basename.:extension&quot;,
117
+ :styles =&gt; { :icon =&gt; &quot;30x30!&quot;,
118
+ :thumb =&gt; &quot;100&gt;&quot;,
119
+ :small =&gt; &quot;150&gt;&quot;,
120
+ :medium =&gt; &quot;300&gt;&quot;,
121
+ :large =&gt; &quot;660&gt;&quot; },
122
+ :default_url =&gt; &quot;/images/profile_default.jpg&quot;,
123
+ :storage =&gt; :s3,
124
+ :s3_credentials =&gt; AMAZON_S3_CREDENTIALS,
125
+ :bucket =&gt; &quot;assets.example.com&quot;,
126
+ :s3_host_alias =&gt; &quot;assets.example.com&quot;,
127
+ :convert_options =&gt; {
128
+ :all =&gt; '-quality 80'
129
+ }
130
+ },
131
+ :s3_path =&gt; ':id_partition/:style/:basename.:extension'
132
+
133
+ # only allow images:
134
+ # validates_attachment_content_type :file, :content_type =&gt; ['image/jpeg', 'image/pjpeg', 'image/jpg']
135
+
136
+ # The following method is implemented in 'acts_as_uploader'. This is the method destroy will check to see if
137
+ # the user has permission to delete the object. Add additional logic as needed or if the existing logic
138
+ # looks fine then feel free to delete this comment and the can_edit? method.
139
+ def can_edit?(check_user)
140
+ return false if user.blank?
141
+ check_user == self.user
142
+ end
143
+
144
+ end
145
+ </pre>
146
+ <h3>Add multiple file uploads to one of your models</h3>
147
+ <p>
148
+ Your uploads will need a parent object to attach to. For example, a user
149
+ might have many files:
150
+ </p>
151
+ <pre>
152
+ class User &lt; ActiveRecord::Base
153
+ has_many :uploads, :as =&gt; :uploadable, :order =&gt; 'created_at desc', :dependent =&gt; :destroy
154
+
155
+ def can_upload?(check_user)
156
+ self == check_user
157
+ end
158
+ end
159
+ </pre>
160
+ <p>
161
+ or a photo album might have many photos
162
+ </p>
163
+ <pre>
164
+ class PhotoAlbum &lt; ActiveRecord::Base
165
+ has_many :photos, :as =&gt; :uploadable, :order =&gt; 'created_at desc', :dependent =&gt; :destroy
166
+
167
+ def can_upload?(check_user)
168
+ self.editors.include?(check_user)
169
+ end
170
+ end
171
+ </pre>
172
+ <p>
173
+ Note that in both examples there is an implementation of
174
+ &#8216;can_upload?&#8217;. This method must be included in any parent
175
+ object and will control who has permission to upload files.
176
+ </p>
177
+ <h3>The application controller</h3>
178
+ <p>
179
+ Be sure you have turned on protect from forgery. This is required for
180
+ uploader to get the appropriate tokens from your Rails application. It is
181
+ also a good idea and is the default in new Rails applications.
182
+ </p>
183
+ <pre>
184
+ protect_from_forgery # See ActionController::RequestForgeryProtection for details
185
+ </pre>
186
+ <h3>The uploads controller</h3>
187
+ <p>
188
+ You can modify the upload controller behavior by inheriting from the
189
+ uploader controller. For example, you might want to require that users be
190
+ logged in to upload a file. There are a number of methods in the uploads
191
+ controller that contain default functionality that you may consider
192
+ overriding.
193
+ </p>
194
+ <p>
195
+ Be sure to modify your routes file. Add the following line to ensure that
196
+ your application uses the new uploads controller instead of directly using
197
+ the one inside the gem:
198
+ </p>
199
+ <pre>
200
+ map.resources :uploads, :collection =&gt; { :swfupload =&gt; :post }
201
+
202
+ class UploadsController &lt; Uploader::UploadsController
203
+
204
+ prepend_before_filter :login_required
205
+
206
+ protected
207
+
208
+ # The default 'get_upload_text' method throws an exception. You must override this method in your controller. It
209
+ # is used by the swf upload call to generate the html to be returned to the client.
210
+ # Here's an example:
211
+ def get_upload_text(upload)
212
+ render_to_string( :partial =&gt; 'uploads/upload_row', :object =&gt; upload, :locals =&gt; { :parent =&gt; @parent } )
213
+ end
214
+
215
+ # The existing method will handle most cases but you might choose a different message or a different redirect:
216
+ def permission_denied
217
+ message = t(&quot;uploader.permission_denied&quot;)
218
+ respond_to do |format|
219
+ format.html do
220
+ flash[:notice] = message
221
+ redirect_to get_redirect
222
+ end
223
+ format.js { render :text =&gt; message }
224
+ format.json { render :json =&gt; { :success =&gt; false, :message =&gt; message } }
225
+ end
226
+ end
227
+
228
+ # Simply attempts to redirect to the parent object. You might want to build something more sophisticated that
229
+ # redirect to different areas of you site depending on the type of object that was uploaded or on based on the parent.
230
+ # source can be :destroy_success, :create_success, :create_failure, :permission_denied
231
+ def get_redirect
232
+ @parent
233
+ end
234
+
235
+ # The default action is to call 'can_upload?' on the parent object. Be sure to implement 'can_upload?(check_user) on
236
+ # your parent objects
237
+ def has_permission_to_upload(user, upload_parent)
238
+ upload_parent.can_upload?(user)
239
+ end
240
+
241
+ # By default the controller will use a model named 'Upload' to do a destroy. If you want to use a different model
242
+ # you'll need to override 'set_upload_for_destroy in your controller to find the object using a different object.
243
+ # For example:
244
+ def set_upload_for_destroy
245
+ @upload = Photo.find(params[:id])
246
+ end
247
+
248
+ end
249
+ </pre>
250
+ <h3>Configure your views.</h3>
251
+ <p>
252
+ You&#8216;ll need something like this in your layout so that uploader can
253
+ add in the required css and javascript files.
254
+ </p>
255
+ <p>
256
+ &lt;%= yield :head -%&gt;
257
+ </p>
258
+ <p>
259
+ Then to add an upload form: &lt;%= upload_form(parent_object) %&gt;
260
+ parent_object should be the object which owns the uploads. ie a user,
261
+ photo_album, etc.
262
+ </p>
263
+ <h3>Rake Tasks</h3>
264
+ <p>
265
+ Add the rake tasks for uploader to your project. You will need to add the
266
+ following to your applications&#8216;s Rakefile
267
+ </p>
268
+ <pre>
269
+ require 'uploader'
270
+ require 'uploader/tasks'
271
+ </pre>
272
+ <p>
273
+ Then run:
274
+ </p>
275
+ <pre>
276
+ rake uploader:sync
277
+ </pre>
278
+ <p>
279
+ Last run:
280
+ </p>
281
+ <pre>
282
+ rake db:migrate
283
+ </pre>
284
+ <p>
285
+ This will create an uploads table for you. If you selected a different name
286
+ for your model you will need to modify the migration accordingly.
287
+ </p>
288
+ <h2>WARNING</h2>
289
+ <p>
290
+ The migration will drop any existing &#8216;uploads&#8217; table you have
291
+ in place
292
+ </p>
293
+ <p>
294
+ That will copy all the required javascript and asset files into your
295
+ project
296
+ </p>
297
+ <h2>Amazon s3</h2>
298
+ <p>
299
+ If you&#8216;d like to store your uploads on Amazon&#8216;s S3 service
300
+ there are a few extra steps involved. See the example file above to view
301
+ the options in context.
302
+ </p>
303
+ <h3>Turn on s3</h3>
304
+ <p>
305
+ Set the enable_s3 option to true in acts_as_uploader
306
+ </p>
307
+ <pre>
308
+ :enable_s3 =&gt; true
309
+ </pre>
310
+ <p>
311
+ Pass your s3 credentials into acts_as_uploader
312
+ </p>
313
+ <pre>
314
+ :has_attached_file =&gt; { :s3_credentials =&gt; File.join(RAILS_ROOT, 'config', 's3.yml') }
315
+ </pre>
316
+ <h3>Setup your credentials</h3>
317
+ <p>
318
+ Create a file named s3.yml in your configuration directory and add the
319
+ following lines:
320
+ </p>
321
+ <pre>
322
+ access_key_id: PUT YOUR KEY HERE
323
+ secret_access_key: PUT YOUR SECRET ACCESS KEY HERE
324
+ </pre>
325
+ <h3>Turn on the Daemon process</h3>
326
+ <p>
327
+ There are a number of timing issues that you will run into if you attempt
328
+ to upload files directly to s3. To overcome that problem uploader includes
329
+ a daemon process which will send the files to Amazon asynchronously. Note
330
+ that the uploader will leave your local copy in place.
331
+ </p>
332
+ <p>
333
+ Add the daemons gem and plugin:
334
+ </p>
335
+ <pre>
336
+ sudo gem install daemons
337
+ </pre>
338
+ <p>
339
+ Then inside your Rails project:
340
+ </p>
341
+ <pre>
342
+ script/plugin install git://github.com/dougal/daemon_generator.git
343
+ script/generate daemon amazonaws
344
+
345
+ RAILS_ENV=development lib/daemons/mailer_ctl start
346
+ </pre>
347
+ <p>
348
+ Learn more about the custom daemon gem with Ryan Bates screencast:
349
+ </p>
350
+ <pre>
351
+ http://railscasts.com/episodes/129-custom-daemon
352
+ </pre>
353
+ <h2>Use Rake to send files to s3</h2>
354
+ <p>
355
+ uploader includes a task capable of sending files to s3 but it makes an
356
+ assumption that the model you are interacting with is named
357
+ &#8216;Upload&#8217;.
358
+ </p>
359
+ <pre>
360
+ rake uploader:upload_to_s3
361
+ </pre>
362
+ <p>
363
+ If you want to use a different model or several models just add a rake task
364
+ to your project:
365
+ </p>
366
+ <pre>
367
+ desc 'Send all uploads to S3. (Will only send uploads from a model named Upload)'
368
+ task :upload_to_s3 do
369
+
370
+ uploads = Upload.pending_s3_migration
371
+ uploads.each do |upload|
372
+ upload.remote = upload.local
373
+ upload.save!
374
+ end
375
+
376
+ photos = Photo.pending_s3_migration
377
+ photos.each do |photo|
378
+ photo.remote = photo.local
379
+ photo.save!
380
+ end
381
+
382
+ end
383
+ </pre>
384
+ <h2>Setup Domains</h2>
385
+ <p>
386
+ If you use Amazon&#8216;s S3 service you can setup a cname to clean up your
387
+ urls. Configure your s3 bucket as above:
388
+ </p>
389
+ <pre>
390
+ :bucket =&gt; &quot;assets.example.com&quot;
391
+ :s3_host_alias =&gt; &quot;assets.example.com&quot;
392
+ </pre>
393
+ <p>
394
+ Your assets will be available at assets.example.com.s3.amazon.com. You can
395
+ then create a CNAME in your DNS entries to point
396
+ &quot;assets.example.com&quot; to
397
+ &quot;assets.example.com.s3.amazon.com&quot;. Your assets will then appear
398
+ to be be served from assets.example.com even though they are loaded from
399
+ Amazon.
400
+ </p>
401
+ <h2>Other Stuff</h2>
402
+ <p>
403
+ If you&#8216;d like to add an ajax delete to your uploads page this code
404
+ might come in handy.
405
+ </p>
406
+ <p>
407
+ Say you have chosen to display your upload in a table. Your code might look
408
+ like the following. Note that there are a number of assumptions made in
409
+ this code. Modify it to suite your needs.
410
+ </p>
411
+ <pre>
412
+ &lt;tr id=&quot;&lt;%= upload_row.dom_id %&gt;&quot; class=&quot;delete-container &lt;%= cycle('odd', 'even') %&gt;&quot; &lt;%=style-%&gt; &gt;
413
+ &lt;td&gt;&lt;div class=&quot;file-icon&quot;&gt;&lt;%= image_tag upload_row.icon -%&gt;&lt;/div&gt;&lt;/td&gt;
414
+ &lt;td&gt;&lt;a href=&quot;&lt;%=upload_row.file.url%&gt;&quot;&gt;&lt;%= truncate(sanitize(upload_row.file_name), 100) %&gt;&lt;/a&gt;&lt;/td&gt;
415
+ &lt;td&gt;&lt;%= upload_row.created_at.to_s(:long) -%&gt;&lt;/td&gt;
416
+ &lt;td&gt;
417
+ &lt;% if parent.can_edit?(current_user) -%&gt;
418
+ &lt;% form_for(:upload, :url =&gt; upload_path(upload_row.id), :html =&gt; { :class =&gt; &quot;delete-form&quot;, :method =&gt; :delete} ) do |f| -%&gt;
419
+ &lt;%= image_submit_tag '/images/icons/delete.png', {:id =&gt; 'submit-comment', :title =&gt; t('general.delete_file'), :class =&gt; 'submit-delete', :width =&gt; '12', :height =&gt; '12', :alt =&gt; t('general.delete_file') } %&gt;
420
+ &lt;% end -%&gt;
421
+ &lt;% if !style.empty? -%&gt;
422
+ &lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
423
+ jQuery(&quot;#&lt;%= upload_row.dom_id %&gt;&quot;).fadeIn(&quot;slow&quot;);
424
+ &lt;/script&gt;
425
+ &lt;% end -%&gt;
426
+ &lt;% end -%&gt;
427
+ &lt;/td&gt;
428
+ &lt;/tr&gt;
429
+ </pre>
430
+ <p>
431
+ I put the following in my main upload view
432
+ </p>
433
+ <pre>
434
+ &lt;% content_for :javascript do -%&gt;
435
+
436
+ setup_submit_delete();
437
+
438
+ function upload_completed_callback(data){
439
+ jQuery('#upload-list').prepend(data);
440
+ setup_submit_delete();
441
+ }
442
+ &lt;% end -%&gt;
443
+ </pre>
444
+ <p>
445
+ The following jQuery code will do an ajax delete for you
446
+ </p>
447
+ <pre>
448
+ function setup_submit_delete(){
449
+ jQuery(&quot;.submit-delete&quot;).click(function() {
450
+ // if(!confirm(&quot;Are you sure?&quot;)){
451
+ // return false;
452
+ // }
453
+ jQuery(this).parents('.delete-container').fadeOut();
454
+ var form = jQuery(this).parents('form');
455
+ jQuery.post(form.attr('action') + '.json', form.serialize(),
456
+ function(data){
457
+ var json = eval('(' + data + ')');
458
+ if(!json.success){
459
+ jQuery.jGrowl.info(json.message);
460
+ }
461
+ });
462
+ return false;
463
+ });
464
+ }
465
+ </pre>
466
+ <p>
467
+ Copyright (c) 2009 Justin Ball, released under the MIT license
468
+ </p>
469
+
470
+ </div>
471
+
472
+
473
+ </div>
474
+
475
+
476
+ </div>
477
+
478
+
479
+ <!-- if includes -->
480
+
481
+ <div id="section">
482
+
483
+
484
+
485
+
486
+
487
+
488
+
489
+
490
+ <!-- if method_list -->
491
+
492
+
493
+ </div>
494
+
495
+
496
+ <div id="validator-badges">
497
+ <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
498
+ </div>
499
+
500
+ </body>
501
+ </html>