dboyd68
dboyd68

Reputation: 1104

Ajax form doesn't when when multipart +file upload is true

can't quite get this to work.

I have

class QuestionsController < ApplicationController

which renders a form

<%= form_for [question, QuestionResponse.new], remote: true, :html => {:multipart => true} do |f| %>
 <%= f.text_area :text, cols: 30, rows: 8, %>
 <%= f.file_field :image, id:"file4", title: "Attach Photo" %>
 <%= f.submit "Reply", class: "btn-green" %>
<% end %>

than I have

QuestionResponsesController

 def create
    @question = #retrieve from params
    @response = @question.response.new(params[:question_response])
    @question.save!
  end

This responds via javascript so I have

create.js

$("#<%= j "#{@question.id}_new_response"%>").before('<%= j render("response", response:@response)%>');

If I don't attach a file this works fine

When I attach I file I get Template is missing

Missing template question_responses/create, application/create with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :arb, :coffee]}. 

Figured it was because rails decided it should respond to html where before it worked out .js response.

I tried:

  1. adding format: :js to form_for
  2. adding respond_to :js to QuestionResponsesController controller.

This didn't work it just ended up rendering the javascript in the browser rather than execute it.

Any ideas? Guessing it's simple.

Upvotes: 0

Views: 4027

Answers (2)

Richard Peck
Richard Peck

Reputation: 76774

We've implemented Ajax file upload (http://video-conference-demo.herokuapp.com -- register & try uploading new profile image)


JQuery File Upload

The way we did it was to use JQuery-File-Upload with Ajax:

#app/views/your_view.html.erb
<!-- New Avatar Upload Form -->
<%= form_for :upload, :html => {:multipart => true, :id => "avatar"}, :method => :put, url: profile_path(current_user.id), "data_id" => current_user.id do |f| %>
    <div class="btn btn-success fileinput-button avatar" id="avatar_container">
        <%= f.file_field :avatar, :title => "Upload New" %>
        <%= image_tag(@user.profile.avatar.url, :width=> '100%', :id => "avatar_img", :alt => name?(@user)) %>
    </div>
<% end %>

We handle the upload with this JS:

$('#avatar').fileupload({

    url: '/profile/' + $(this).attr('data_id'),
    dataType: 'json',
    type: 'post',

    add: function (e, data) {
         data.submit();
    },
    success: function (data, status) {;
         //handle data
    }
});

This is the controller code:

def update
     @profile = User.find(current_user.id)
     @profile.profile.update(upload_params)

     respond_to do |format|
          format.html { render :nothing => true }
          format.js   { render :partial => 'profiles/update.js' }
          format.json { 
              render :json => @profile.profile.as_json(:only => [:id, :avatar], :methods => [:avatar_url])
          }
     end
end

Code

I'd say your problem will be with how you're saving your question:

QuestionResponsesController

 def create
    @question = #retrieve from params
    @response = @question.response.new(question_response_params)
    @question.save!
  end

  private

  def question_response_params
      params.require(:question_response).permit(:text, :image)
  end

Upvotes: 1

Surya
Surya

Reputation: 15992

Unfortunately there is no easy and universal way to send multipart forms via ajax.

However you can use couple of other ways to achieve this:

  1. Jquery file upload: https://github.com/blueimp/jQuery-File-Upload rails plugin available here: https://github.com/tors/jquery-fileupload-rails
  2. jQuery ajaxForm: http://malsup.com/jquery/form/#file-upload

Also, you can check this post: Ruby on Rails AJAX file upload out for your reference.

HTH :)

Upvotes: 3

Related Questions