Reputation: 2648
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
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
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
Reputation: 1633
You should add :format => :js
onto your form_for
And possibly update,
format.js { render :nothing => true }
Upvotes: 2