Reputation: 4908
We are upgrading a Rails 6 app to Rails 7 and cannot submit ajax requests. They just do normal form submits and the page reloads. We are doing this with javascript.
The result of the form submit is loaded into a different div
on the page by javascript inside the js.erb
.
Here is the form:
<%= form_with model: EmailTemplate.new, url: preview_send_now_email_templates_path,
html: { id: 'emailPreviewForm' },
format: :js, method: :post, remote: true, data: { turbo: false },
authenticity_token: true do |f| %>
<input type="hidden" name="email_template_id" value="1234">
<input type="hidden" name="order_id" value="5678">
<% end %>
On the page that generates HTML that looks like this:
<form data-turbo="false" id="emailPreviewForm" action="/email_templates/preview_send_now" accept-charset="UTF-8" method="post">
<input type="hidden" name="authenticity_token" value="yaddayadda" autocomplete="off" />
<input type="hidden" name="email_template_id" value="1234">
<input type="hidden" name="order_id" value="5678">
</form>
And we submit it by Javascript like this:
document.getElementById('emailPreviewForm').submit();
In a brand new Rails 7 app this works - it submits via Ajax and doesn't do a page reload. Oddly, it doesn't see the format as javascript, which makes me think there is some sort of conflict going on in the writing out of these tags.
This could very well be me not understanding some significant changes in Rails 7, but, it seems to me that it shouldn't cause such a significant thing to stop working.
UPDATE
At mike-a's suggestion I added:
config.action_view.form_with_generates_remote_forms = true
To my application.rb
. To be honest, this did not seem to change anything. Adding the local: false
was the thing that added remote: true
into the form definition.
I also changed the form to this:
<%= form_with model: EmailTemplate.new,
url: preview_send_now_email_templates_path(format: :js),
html: { id: 'emailPreviewForm2' },
method: :post, local: false,
authenticity_token: true do |f| %>
<input type="hidden" name="email_template_id" value="1234">
<input type="hidden" name="order_id" value="5678">
<% end %>
Which gave me:
<form id="emailPreviewForm2" action="/email_templates/preview_send_now.js" accept-charset="UTF-8" data-remote="true" method="post">
<input type="hidden" name="authenticity_token" value="yaddayadda" autocomplete="off" />
<input type="hidden" name="email_template_id" value="1234">
<input type="hidden" name="order_id" value="5678">
</form>
Adding the format: :js
to the path at least fixed that. But otherwise, doing document.getElementById('emailPreviewForm2').submit();
still simply submits and loads the resulting rendered js.erb
file into the browser.
It is not remote
.
I do have turbo
loaded (because I am slowly converting things to hotwire and turbo). Actually, this situation is forcing me to convert a lot more than I wanted to!
Upvotes: 5
Views: 3034
Reputation: 3229
Can you try replacing remote: true
with local: false
? I don't see a remote option for form_with
in the Rails docs. You may also want to read about that option in the docs as the default changed in Rails 6.1. https://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_with
So if you were upgrading from Rails 6.0, and aren't setting config.action_view.form_with_generates_remote_forms
in your configuration, the default could have changed on you.
Another thought, if the above doesn't change anything: in Rails 6 the remote forms functionality was provided by ujs (unobtrusive javascript). I believe in Rails 7 ujs is gone and something else is used (Turbo?). Perhaps your fresh Rails 7 project works because it brings in Turbo (or whatever new js library is doing the work), but in your upgraded Rails project you aren't bringing that new dependency in. Sorry for being vague... I don't know the new frontend changes very well. I'm just throwing out things to look into.
Upvotes: 3