Rails - How do I get my remote form to respond with JS?

10,790

Solution 1

I just found the problem:

I was submitting my comments form with javascript: this.form.submit(). That worked fine when I wasn't using :remote=>true. However for some reason breaks when I make the form :remote=>true.

If I use an actual submit button, the code in my question works fine.

OR if I change my JavaScript from this.form.submit() to using jQuery to select the form by id and submit that, that works too:

$("#new_comment_<%= @item.id %>").submit();

Solution 2

I came across this question when trying to figure out something similar in 2020, using Rails 6.

I have a form created with form_with, which is remote: true by default, and I was submitting it in a Stimulus.js controller using the submit() function on the HTMLFormElement. This didn't work, but using a <input type="submit"> button instead worked, just like in the original question.

The reason behind this is that calling submit() in JavaScript doesn't trigger the onsubmit event on the form, while clicking a <input type="submit"> button does trigger this event (MDN docs). Rails' handling of remote: true depends on this event being fired, so the behaviour breaks.

I used the workaround from this answer to submit my form in JavaScript, and the remote: true behaviour now works as expected.

Also, if you're using rails-ujs, you can use this wrapper to submit the form (source):

form = document.querySelector('form');
Rails.fire(form, 'submit');

I hope this helps someone else!

Solution 3

You should add :format => :js onto your form_for

And possibly update,

format.js { render :nothing => true } 
Share:
10,790
Abby Fichtner
Author by

Abby Fichtner

I'm Harvard Innovation Lab's Hacker in Residence where I help students hack on cool side projects and start tech companies. I blog about technology and innovation on [HackerChick.com][2]

Updated on July 06, 2022

Comments

  • Abby Fichtner
    Abby Fichtner almost 2 years

    I have a page that list items. Below each item it lists out any comments for that item (comments is a nested resource under items).

    You can add a new comment in-line on the items page. When you do that, it was reloading the whole page so I want to change it to use Ajax and just use jQuery to insert the comment.

    So I changed my comments/_form.html.erb to use :remote=>true

    <%= form_for([@item,@comment], :remote=>true) do |f| %>
    

    I added a format.js in my comments_controller:

    def create
      @comment = Comment.new(params[:comment])
      @comment.save
    
      respond_to do |format|
        format.js
        format.html { redirect_to items_path}
      end
    end
    

    And created a simple comments/create.js.erb to insert the new comment onto the page:

    $("#comments").append("<%= j(render(@comment)) %>");
    

    However, when I submit a comment (even with the :remote=>true on the form) it keeps reloading the whole page/ignoring my .js file.

    So I deleted format.html from the respond_to (since I don't want to use that option), but then it gives me the error Completed 406 Not Acceptable in 4ms (ActiveRecord: 0.2ms)

    How can I get it to stay on the current page and respond with my create.js?

  • Abby Fichtner
    Abby Fichtner over 11 years
    bullfrog: where exactly would I add it? I tried doing: <%= form_for([@item,@comment], :remote=>true, :url=>item_comments_path(:format=>:js)) do |f| %> but that doesn't do the right thing - it takes me off of the page I want to stay on and loads a page that displays the contents of my create.js as if it were a textfile
  • bullfrog
    bullfrog over 11 years
    try <%= form_for([@item,@comment], :format => :js, :remote=>true) do |f| %>
  • Abby Fichtner
    Abby Fichtner over 11 years
    same thing: it takes me off of the page I want to stay on and loads a page that displays the contents of my create.js as if it were a text file. any idea why it would do that?
  • bullfrog
    bullfrog over 11 years
    have you included jquery_ujs ?
  • Abby Fichtner
    Abby Fichtner over 11 years
    yep. and my new action for comments also uses ajax w/ jquery and that one works fine. can't figure out how that works but the create doesn't.
  • Abby Fichtner
    Abby Fichtner over 11 years
    thanks for your help, see my answer below. I'll have to post another question about why my form.submit() isn't working...
  • konyak
    konyak over 9 years
    Thanks bullfrog! I had the same problem and solved it by including jquery_ujs
  • Spectator6
    Spectator6 about 4 years
    Thank you for your answer @gueorgui ! I was encountering a similar issue on Rails 6.x with a *.js file not being called in the respond_to block upon form submission. The funny thing here was that it was with a form that was previously working as intended! After pulling my hair out for the past two days, simply re-including rails-ujs in application.js did the trick. Very weird!