Deborah
Deborah

Reputation: 4575

rails form submission with remote => true -- js file renders but does not execute

There is a similar question here and here but neither has the answer I'm looking for. I've also done a lot of searching for "rails format.js render" without being able to solve this.

In Rails 4, I have a validated form as follows:

<%= form_for(@message, :remote => true) do |form| %>
// don't want to call the js on submit here because 
// I don't want it to execute if the form did not validate

I'm calling the js in the controller:

def create
    @message = Message.new(params[:message])
      if @message.valid?
        NotificationsMailer.new_message(@message).deliver
        respond_to do |format|
          format.js { render "submit" }
        end
      else
        render :new
      end
  end

I have "submit.js.erb" in the "messages" folder:

alert('js was called!'); 

When I submit the form, Terminal verifies the file DOES render:

Rendered messages/submit.js.erb (0.5ms)

...but on the screen, nothing happens. No alert, and no executed javascript. I've also tried creating "submit.html.erb" and wrapping my javscript in a script tag, and the same thing happens - the file loads, but the script does not execute.

Why? What do I need to do to tell Rails to execute the js?

Edit: After visiting Kelvo's resources and trying many things, the answer seemed to be adding this to the application.js...

 $.ajaxSetup({  
    'beforeSend': function (xhr) {xhr.setRequestHeader('Content-Type', 'application/javascript');}  
 }); 

It also turned out that a manual line break and indentation (since it was not wrapping in my IDE) in my actual "submit.js.erb" was causing it to fail to execute, so there were really two problems.

Upvotes: 2

Views: 4566

Answers (2)

klvmungai
klvmungai

Reputation: 824

This may be due to the fact that the returned content is not being evaluated. The browser does receive the file but does not know what to do with it, you have to include some JavaScript to handle the response as explained here :

You probably don't want to just sit there with a filled out <form>, though. You probably want to do something upon a successful submission. To do that, bind to the ajax:success event. On failure, use ajax:error. Check it out:

in your case you might try out

$(document).ready(function(){
  $("#new_message").on("ajax:success", function (e, data, status, xhr){
     eval(xhr.responseText);
  });
});

in order to evaluate the js code.

you can read more on events fired during "data-remote" requests here

EDIT : forgot to mention, this script has to be included on the HTML file containing the form. Maybe just add it under your form.

Upvotes: 3

devender
devender

Reputation: 46

This may be due to, returned content also including your default layout.

Try this:

format.js {render layout: 'no_layout', action: 'submit'}

Hope this helps...

Upvotes: 1

Related Questions