Abby Fichtner
Abby Fichtner

Reputation: 2648

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

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?

Upvotes: 8

Views: 12023

Answers (3)

gosha
gosha

Reputation: 406

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!

Upvotes: 4

Abby Fichtner
Abby Fichtner

Reputation: 2648

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();

Upvotes: 5

bullfrog
bullfrog

Reputation: 1633

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

And possibly update,

format.js { render :nothing => true } 

Upvotes: 2

Related Questions