Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rails-ujs doesn't submit remote forms submitted with JavaScript via XHR #29546

Closed
mrhead opened this issue Jun 23, 2017 · 6 comments
Closed

rails-ujs doesn't submit remote forms submitted with JavaScript via XHR #29546

mrhead opened this issue Jun 23, 2017 · 6 comments

Comments

@mrhead
Copy link
Contributor

mrhead commented Jun 23, 2017

I've found an inconsistency between jquery_ujs and rails-ujs. With jquery_ujs a remote form submitted with JavaScript is submitted via XHR, but with rails-ujs it is submitted via normal HTML request.

I am not sure if this is an intentional change or a bug.

Steps to reproduce

rails new rails-ujs-form-test
cd rails-ujs-form-test
rails g controller home index

Edit app/views/home/index.html.erb and add:

<form url="/" method="post" data-remote="true">
</form>

Start rails server:

rails s

Visit http://localhost:3000/home/index

Open developer console and run:

document.querySelector("form").submit()

Expected behavior

Form is submitted via XHR request.

Actual behavior

Form is submitted via standard HTML request.

System configuration

Rails version: 5.1.1 and rails master
Ruby version: 2.4.1

@mrhead mrhead changed the title rails-ujs doesn't submit remote forms submitted via JavaScript via XHR rails-ujs doesn't submit remote forms submitted with JavaScript via XHR Jun 24, 2017
@padi
Copy link
Contributor

padi commented Jul 6, 2017

@mrhead You might be interested in watching this particular issue #29046

@padi
Copy link
Contributor

padi commented Jul 7, 2017

@mrhead I've recently encountered this issue as well. By looking at the current rails-ujs codebase, seems like as a temporary replacement, we can let the rails-ujs handle the XHR form submission.
If anyone's more familiar with rails-ujs, correct me if I'm wrong.

Example usage (if using jQuery):

nativeFormElement = $(this)[0]; //get the native form element
Rails.handleRemote.call(nativeFormElement, event); // throws error on callback after succesful request, because we don't have the proper 'submit' CustomEvent object as a target
// or ...
Rails.handleRemote.call(nativeFormElement, event);
// or ...
Rails.fire(nativeFormElement, 'submit'); // s̶e̶e̶m̶s̶ ̶t̶o̶ ̶c̶u̶r̶r̶e̶n̶t̶l̶y̶ ̶s̶u̶b̶m̶i̶t̶ ̶v̶i̶a̶ ̶X̶H̶R̶ ̶t̶w̶i̶c̶e̶ this works just fine.

See https://github.com/rails/rails/blob/master/actionview/app/assets/javascripts/rails-ujs/features/remote.coffee#L16

@padi
Copy link
Contributor

padi commented Jul 10, 2017

@mrhead I've given this much thought over the weekend and it turns out that .submit() is unreliable to use. See MDN's documentation of submit() (https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit), specifically, how it does not guarantee the onsubmit event handler to be triggered.

As far as using Web API, It's better to use the more recent dispatchEvent(), e.g.

form = document.querySelector('form');
form.dispatchEvent(new Event('submit', {bubbles: true})); // you can specify more options in `Event()` for reliability across different browsers.

Or use just use a convenient wrapper provided by rails-ujs.js:

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

In light of this, I think this issue can be closed.

@mrhead
Copy link
Contributor Author

mrhead commented Jul 11, 2017

@padi Whoa, nice investigation! 👏

@koenhandekyn
Copy link

koenhandekyn commented Aug 23, 2018

i've extracted some minor documentation from this into the rails-ujs wiki

https://github.com/rails/jquery-ujs/wiki/How-to-trigger-a-form-submit-from-code

@feliperaul
Copy link

Arrived here after migrating from jquery_ujs to rails-ujs. Even tough the most voted comment says that .submit() is unreliable, I haven't had a single issue with it in 10 years of using vanilla form.submit() to have it intercepted and posted via Ajax by jquery_ujs.

So, for the time being, we're downgrading back to jquery_ujs unfortunately, because in a huge codebase it would be a gigantic effort to update code to use Rails.fire.

It would be very nice if someone with better JS skills could debug why the previous library managed to get it right and the new one doesn't.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants