0

I'm having an issue with one of my controller's AJAX functionality. Here's what I have:

class PhotosController < ApplicationController
  # ...
  def create
    @photo = Photo.new(params[:photo])
    @photo.image_content_type = MIME::Types.type_for(@photo.image_file_name).to_s
    @photo.image_width = Paperclip::Geometry.from_file(params[:photo][:image]).width.to_i
    @photo.image_height = Paperclip::Geometry.from_file(params[:photo][:image]).height.to_i
    @photo.save!

    respond_to do |format|
      format.js
    end
  end
  # ...
end

This is called through a POST request sent by this code:

$(function() {
  // add photos link
  $('a.add-photos-link').colorbox({
    overlayClose: false,
    onComplete: function() { wire_add_photo_modal(); }
  });

  function wire_add_photo_modal() {
    <% session_key = ActionController::Base.session_options[:key] %>
    $('#upload_photo').uploadify({
      uploader: '/swf/uploadify.swf',
      script: '/photos',
      cancelImg: '/images/buttons/cancel.png',
      buttonText: 'Upload Photo(s)',
      auto: true,
      queueID: 'queue',
      fileDataName: 'photo[image]',
      scriptData: {
        '<%= session_key %>': '<%= u cookies[session_key] %>',
        commit: 'Adding Photo',
        controller: 'photos',
        action: 'create',
        '_method': 'post',
        'photo[gallery_id]': $('#gallery_id').val(),
        'photo[user_id]': $('#user_id').val(),
        authenticity_token: encodeURIComponent('<%= u form_authenticity_token if protect_against_forgery? %>')
      },
      multi: true
    });
  }
});

Finally, I have my response code in app/views/photos/create.js.erb:

alert('photo added!');

My log file shows that the request was successful (the photo was successfully uploaded), and it even says that it rendered the create action, yet I never get the alert. My browser shows NO javascript errors.

Here's the log AFTER a request from the above POST request is submitted:

Processing PhotosController#create (for 127.0.0.1 at 2010-03-16 14:35:33) [POST]
Parameters: {"Filename"=>"tumblr_kx74k06IuI1qzt6cxo1_400.jpg", "photo"=>{"user_id"=>"1", "image"=>#<File:/tmp/RackMultipart20100316-54303-7r2npu-0>}, "commit"=>"Adding Photo", "_edited_session"=>"edited", "folder"=>"/kakagiloon/", "authenticity_token"=>"edited", "action"=>"create", "_method"=>"post", "Upload"=>"Submit Query", "controller"=>"photos"}
[paperclip] Saving attachments.
[paperclip] saving /public/images/assets/kakagiloon/thumbnail/tumblr_kx74k06IuI1qzt6cxo1_400.jpg
[paperclip] saving /public/images/assets/kakagiloon/profile/tumblr_kx74k06IuI1qzt6cxo1_400.jpg
[paperclip] saving /public/images/assets/kakagiloon/original/tumblr_kx74k06IuI1qzt6cxo1_400.jpg
Rendering photos/create
Completed in 248ms (View: 1, DB: 6) | 200 OK [http://edited.local/photos]

NOTE: I edited out all the SQL statements and I put "edited" in place of sensitive info.

What gives? Why aren't I getting my alert();?

Please let me know if you need anymore info to help me solve this issue! Thanks.


SOLUTION: Thanks to jitter for setting me straight about Uploadify's callbacks.

Controller:

class PhotosController < ApplicationController
  # ...
  def create
    @photo = Photo.new(params[:photo])
    @photo.image_content_type = MIME::Types.type_for(@photo.image_file_name).to_s
    @photo.image_width = Paperclip::Geometry.from_file(params[:photo][:image]).width.to_i
    @photo.image_height = Paperclip::Geometry.from_file(params[:photo][:image]).height.to_i
    @photo.save!

    respond_to do |format|
      format.js { render :layout => false }
    end
  end
  # ...
end

Javascript (Uploadify) callback:

$(function() {
  // add photos link
  $('a.add-photos-link').colorbox({
    overlayClose: false,
    onComplete: function() { wire_add_photo_modal($(this).parent()); }
  });

  function wire_add_photo_modal($parent) {
    <% session_key = ActionController::Base.session_options[:key] %>
    $('#upload_photo').uploadify({
      uploader: '/swf/uploadify.swf',
      script: '/photos',
      cancelImg: '/images/buttons/cancel.png',
      buttonText: 'Upload Photo(s)',
      auto: true,
      queueID: 'queue',
      fileDataName: 'photo[image]',
      scriptData: {
        '<%= session_key %>': '<%= u cookies[session_key] %>',
        commit: 'Adding Photo',
        controller: 'photos',
        action: 'create',
        '_method': 'post',
        'photo[gallery_id]': $('#gallery_id').val(),
        'photo[user_id]': $('#user_id').val(),
        authenticity_token: encodeURIComponent('<%= u form_authenticity_token if protect_against_forgery? %>')
      },
      multi: true,
      onComplete: function(event, queueID, fileObj, response, data) { 
        $parent.find('.gallery-photos').append(response);
      }
    });
  }
});

In create.js.haml (changed templating language from ERB, since I'm basically just returning HTML content):

- if @photo.gallery.nil?
  =render :partial => 'photos/photo', :locals => { :photo => @photo, :rel => 'unsorted' }
- else
  = render :partial => 'photos/photo', :locals => { :photo => @photo, :rel => gallery.title }

1 Answer 1

2

I can't see that you use any of uploadify's callbacks. Thus I guess it just ignores whatever the server sends as response. Try wiring up the onComplete option with a function if you want to send a meaningful response back to your javascript

Check the uploadify documentation for more

I imagine you could change app/views/photos/create.js.erb to

photo added!

and then do

$('#upload_photo').uploadify({
    ...
    onComplete: function(event, queueID, fileObj, response, data) {
        alert("Server said: "+response+" for file "+fileObj.name);
    }
    ...
});

If you want to add the photo to the page you can just let the server return the appropriate html snippet e.g. I imagine create.js.erb to create/output something like this

<img src="Xxx.jpg" width="..." height="..." />

All you need to do in the callback is

onComplete: function(event, queueID, fileObj, response, data) {
    $("selectorforwheretheimageshouldbeinserted").append(response);
    return true;
}
Sign up to request clarification or add additional context in comments.

1 Comment

The alert was just as a demonstration; I actually want to add the photo onto the page (AJAX update). I couldn't get this to work using Uploadify's callback since it's not aware of the new @photo object created by Rails, whereas the create.js.erb is. If I make Uploadify's OnComplete return false, however, I lose it's nice little auto-clear of the queue behavior (what it does by default, out of the box). Any ideas for a workaround?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.