Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

ajax image upload #1903

Merged
merged 4 commits into from

4 participants

@ugisozols
Owner

Originally - #1739

@ugisozols
Owner

This probably needs to be squashed?

@parndt
Owner

Squash-ed

@travisbot

This pull request fails (merged 77d5016 into 3223ad9).

@parndt
Owner

@ugisozols looks like there's a failing spec ;-)

@travisbot

This pull request passes (merged 40b68ae into 3223ad9).

@parndt
Owner

:+1:

@parndt parndt merged commit 8fbf97c into from
@ugisozols
Owner

I did a poor job while reviewing #1739. It adds several things which make some code useless:

  • every image is sent in a separate post (instead of pushing an array of images) to create action so there's no need to check for array stuff
  • validations are happening on the client side so the validation code in model isn't used anymore (valid? checks in controller are redundant too)

Don't get me wrong @jipiboily - I really like the feature but I'm thinking about reverting this and doing it differently.

@jipiboily

No problem @ugisozols. This was an extension at first and implemented it almost as is instead of doing it from scratch, which might be a better idea.

I have minimal experience with Refinery (only one small project, well, project was large, but Refinery's use was tiny) and thought that changing as little as possible would be best to make sure I wouldn't break a non-JS fallback somewhere.

Feel free to make it better! :)

@ugisozols ugisozols referenced this pull request from a commit
@ugisozols ugisozols Revert "Merge pull request #1903 from resolve/imajax"
This reverts commit 8fbf97c, reversing
changes made to 3223ad9.

Conflicts:
	changelog.md
	images/app/controllers/refinery/admin/images_controller.rb
6c21635
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 27, 2012
  1. @jipiboily @parndt

    added ajaxy image uploading

    jipiboily authored parndt committed
  2. @ugisozols @parndt

    Don't show flash success message in modal window - just close it and …

    ugisozols authored parndt committed
    …show success message in the parent window.
  3. @ugisozols @parndt

    Add changelog entry about #1739.

    ugisozols authored parndt committed
  4. @ugisozols
This page is out of date. Refresh to see the latest.
View
1  changelog.md
@@ -4,6 +4,7 @@
* Refactored wysiwyg fields into a partial. [#1796](https://github.com/resolve/refinerycms/pull/1796). [Rob Yurkowski](https://github.com/robyurkowski)
* Shortened all authentication helpers. [#1719](https://github.com/resolve/refinerycms/pull/1719). [Ryan Bigg](https://github.com/radar)
* Added canonical page id to body to allow CSS selectors to target specific pages instead of including special CSS files. [#1700](https://github.com/resolve/refinerycms/pull/1700) & [#1828](https://github.com/resolve/refinerycms/pull/1828). [Philip Arndt](https://github.com/parndt) & [Graham Wagener](https://github.com/gwagener/)
+* Added ajaxy image uploading. [#1739](https://github.com/resolve/refinerycms/pull/1739). [Jean-Philippe Boily](https://github.com/jipiboily)
* [See full list](https://github.com/resolve/refinerycms/compare/2-0-stable...master)
View
128 images/app/assets/javascript/refinery/images.js.coffee.erb
@@ -0,0 +1,128 @@
+$(document).ready ->
+ images = new Images
+ $("#new_image").submit (e) ->
+ if window.FileList && FormData
+ e.preventDefault()
+ images.upload_all()
+ $("#image_image").change (e) ->
+ images.file_list = e.target.files
+
+
+class Images
+ # TODO:
+ # - add a progress bar for each file maybe?
+ # - refresh images index after closing the dialog box...
+ constructor: ->
+ @authenticity_token = $("meta[name=\"csrf-token\"]").attr("content")
+ @form_action = $("#new_image").attr("action")
+ @cache_dom()
+
+ cache_dom: ->
+ @error_list = $("#error_list")
+ @success_list = $("#flash")
+ @error_explanation = $("#errorExplanation")
+ @upload_progress = $("#upload_progress")
+
+ before_upload_all: ->
+ @files = []
+ @errors = []
+ @total_files = @file_list.length
+ @uploaded = 0
+ @error_explanation.hide()
+
+ upload_all: ->
+ @before_upload_all()
+ for file in @file_list
+ @validate(file)
+ @files.push file
+ return @render_errors() if @errors.length > 0
+ $("#submit_button").hide()
+ $(".field").hide()
+ @progress "<%= ::I18n.t("refinery.admin.images.form.uploading")%>"
+ @upload_next()
+
+ after_upload_all: ->
+ $(".save-loader").hide()
+ @upload_progress.hide()
+ @success_list.show()
+ if @errors.length > 0
+ @render_errors()
+ else
+ if getParameterByName("modal") == "true"
+ window.parent.document.getElementById("dialog_frame").contentDocument.location.reload(true);
+ else
+ window.parent.location.reload(true)
+
+ validate: (file) ->
+ max_file_size = <%= Refinery::Images.max_image_size %>
+ if file.size > max_file_size
+ @errors.push "#{file.name} <%= ::I18n.t("refinery.admin.images.form.should_be_smaller")%> #{max_file_size} <%= ::I18n.t("refinery.admin.images.form.bytes_in_size")%>"
+ # TODO: set valid file types based on image model validation
+ valid_file_types = ["image/jpeg", "image/png", "image/gif", "image/tiff"]
+ if valid_file_types.indexOf(file.type) == -1
+ @errors.push "#{file.name} <%= ::I18n.t("refinery.admin.images.form.image_type")%>"
+
+ upload_next: ->
+ @do_upload(@files[0]) unless @files.length == 0
+ if @total_files > 0 && @files.length == 0
+ @after_upload_all()
+
+ do_upload: (file) =>
+ form = new FormData();
+ form.append "image[image]", file
+ form.append "authenticity_token", @authenticity_token
+ _this = @ # save current scope so we can use current object methods within $.ajax
+ $.ajax
+ type: 'POST'
+ url: @form_action
+ data: form
+ contentType: false
+ processData: false
+ success: (data) ->
+ _this.post_success(file)
+ error: (data) ->
+ _this.post_error(file, data.responseText)
+
+ after_do_upload: (file) ->
+ @files.remove file
+ @upload_next()
+
+ post_success: (file) ->
+ @progress file.name + " <%= ::I18n.t("refinery.admin.images.form.uploaded")%>"
+ @update_progress file
+ @after_do_upload file
+
+ post_error: (file, errors) ->
+ errors = JSON.parse(errors).image
+ @update_progress file, errors
+ for e in errors
+ @errors.push "#{file.name}: #{e}"
+ @after_do_upload file
+
+ render_errors: ->
+ $(".save-loader").hide()
+ @error_list.html("")
+ for error in @errors
+ @error_list.append("<li>#{error}</li>")
+ @error_explanation.show()
+
+ update_progress: (file, error = null) ->
+ @uploaded++
+ message = error || "<%= ::I18n.t("refinery.admin.images.form.last_complete")%>: #{file.name}"
+ @progress "#{@uploaded}/#{@total_files} <%= ::I18n.t("refinery.admin.images.form.uploaded")%> | #{message}"
+
+ progress: (text) ->
+ @upload_progress.html(text);
+
+# adds a remove method to Array
+Array::remove = (e) -> @[t..t] = [] if (t = @indexOf(e)) > -1
+
+getParameterByName = (name) ->
+ name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]")
+ regexS = "[\\?&]" + name + "=([^&#]*)"
+ regex = new RegExp(regexS)
+ results = regex.exec(window.location.search)
+ unless results?
+ ""
+ else
+ decodeURIComponent results[1].replace(/\+/g, " ")
View
2  images/app/controllers/refinery/admin/images_controller.rb
@@ -54,7 +54,7 @@ def create
unless params[:insert]
if @images.all?(&:valid?)
- flash.notice = t('created', :scope => 'refinery.crudify', :what => "'#{@images.map(&:title).join("', '")}'")
+ flash.notice = t('uploaded_successfully', :scope => 'refinery.admin.images.form')
if from_dialog?
@dialog_successful = true
render :nothing => true, :layout => true
View
10 images/app/views/refinery/admin/images/_form.html.erb
@@ -1,3 +1,4 @@
+<% content_for :after_javascript_libraries, javascript_include_tag('refinery/images') %>
<%= form_for @image, :url => (@url_override or @image.persisted? ? refinery.admin_image_path(@image) : refinery.admin_images_path),
:html => { :multipart => true } do |f| %>
@@ -5,6 +6,15 @@
:object => @image,
:include_object_name => false %>
+ <% if @image.errors.empty? %>
+ <div id="upload_progress"></div>
+
+ <div class="errorExplanation" id="errorExplanation" style="display:none;">
+ <p><%= t("refinery.admin.error_messages.problems_in_following_fields")%></p>
+ <ul id="error_list"></ul>
+ </div>
+ <% end %>
+
<div class='field'>
<% if action_name =~ /(edit)|(update)/ %>
<p>
View
9 images/config/locales/en.yml
@@ -15,6 +15,15 @@ en:
replace_image: " replace it with this one..."
current_image: Current Image
maximum_image_size: The maximum image size is %{bytes}.
+ uploading: "Uploading..."
+ there_was: "There was"
+ error: "error"
+ should_be_smaller: "should be smaller than"
+ bytes_in_size: "bytes in size"
+ image_type: "should be either a JPG, PNG or GIF"
+ uploaded: "uploaded"
+ last_complete: "Last upload complete"
+ uploaded_successfully: "Uploaded successfully"
actions:
create_new_image: Add new image
records:
View
9 images/config/locales/fr.yml
@@ -15,6 +15,15 @@ fr:
replace_image: " la remplacer par celle-ci..."
current_image: Image actuelle
maximum_image_size: "La taille de l'image ne doit pas excéder %{bytes}."
+ uploading: "Transfert en cours..."
+ there_was: "Il y a"
+ error: "erreur"
+ should_be_smaller: "devrait être plus petit que"
+ bytes_in_size: "octets"
+ image_type: "devrait être un fichier JPG, PNG ou GIF"
+ uploaded: "transféré"
+ last_complete: "Dernier transfert complété"
+ uploaded_successfully: "Transféré avec succès"
actions:
create_new_image: Ajouter une image
records:
View
4 images/spec/requests/refinery/admin/images_spec.rb
@@ -30,8 +30,8 @@ module Refinery
join("spec/fixtures/image-with-dashes.jpg")
click_button ::I18n.t('save', :scope => 'refinery.admin.form_actions')
end
-
- page.should have_content(::I18n.t('created', :scope => 'refinery.crudify', :what => "'Image With Dashes'"))
+ page.should have_content(::I18n.t("uploaded_successfully", :scope => "refinery.admin.images.form"))
+ page.should have_selector("img[src*='image-with-dashes.jpg']")
Refinery::Image.count.should == 1
end
Something went wrong with that request. Please try again.