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 events not firing from links loaded through rails-ujs #32438

Closed
hughkelsey opened this issue Apr 3, 2018 · 6 comments
Closed

Rails-ujs events not firing from links loaded through rails-ujs #32438

hughkelsey opened this issue Apr 3, 2018 · 6 comments

Comments

@hughkelsey
Copy link
Contributor

Steps to reproduce

I've created a quick example app here: https://shielded-beach-23078.herokuapp.com/examples
The source is here: https://github.com/hughkelsey/rails-ujs-issue

  1. Visit https://shielded-beach-23078.herokuapp.com/examples
  2. Click on any of the links, they will load some basic content with a link through rails-ujs
  3. Click on the link that was loaded by rails-ujs
  4. This will reload the same partial through rails-ujs

Expected behavior

The ajax:complete event should fire whenever the data-remote: true link is clicked.

Actual behavior

The ajax:complete event fires for the links initially loaded but not for the links loaded through rails-ujs.

System configuration

Rails version: 5.2rc2
Ruby version: 2.4.1

This issue was originally noticed in 5.1 but the test case above is in 5.2rc2

@willianveiga
Copy link
Contributor

Could you please provide the source code of your example?

@y-yagi
Copy link
Member

y-yagi commented Apr 5, 2018

ajax:complete event is always called when executing ajax. It does not matter whether it is loaded contents.

complete: (args...) -> fire(element, 'ajax:complete', args)

options.complete?(xhr, xhr.statusText)

It seems that the listener for ajax:completex is not enough for the application you made.
Does it work as expected if you change as follows?

diff --git a/app/views/examples/_number_with_link.html.erb b/app/views/examples/_number_with_link.html.erb
index 4fe0f54..3c01b39 100644
--- a/app/views/examples/_number_with_link.html.erb
+++ b/app/views/examples/_number_with_link.html.erb
@@ -1,6 +1,6 @@
 <p>
   You clicked <%= @number %>. <br />
-  Now click this link loaded through ajax:  <%= link_to "Link ##{@number}", example_path(@number), remote: true %>
+  Now click this link loaded through ajax:  <%= link_to "Link ##{@number}", example_path(@number), remote: true, id: 'link' %>
 </p>
 <p>
   loaded at: <%= Time.now %>
diff --git a/app/views/examples/show.js.erb b/app/views/examples/show.js.erb
index 646cda1..e8f8715 100644
--- a/app/views/examples/show.js.erb
+++ b/app/views/examples/show.js.erb
@@ -1 +1,7 @@
 document.getElementById('show').innerHTML = "<%= escape_javascript(render partial: 'number_with_link') %>"
+
+var link = document.getElementById('link');
+link.addEventListener('ajax:complete', function (xhr, status) {
+  console.log('Native ajax:complete')
+  document.getElementById('timer').innerHTML = `<p>Native ajax:complete at ${new Date}</p>`
+}) 

@hughkelsey
Copy link
Contributor Author

Thanks for looking in to this. Your patch works and is similar to a workaround I'm using now. I've implemented it here https://shielded-beach-23078.herokuapp.com/ with some basic annotation as to where the event came from.

I can see from the source that fire should bubble up the custom event.

My understanding from this is the events from the ujs loaded content are getting fired , they are just not bubbling to document up like the events from the initial content. Is that correct?

@y-yagi
Copy link
Member

y-yagi commented Apr 5, 2018

I think that is correct in my understanding. Perhaps there may be browsers that it works, but its behavior is not guaranteed.

@y-yagi
Copy link
Member

y-yagi commented Apr 5, 2018

Anyway, this does not seem Rails' issue. I close this. Thanks.

@y-yagi y-yagi closed this as completed Apr 5, 2018
@hughkelsey
Copy link
Contributor Author

I'm thinking it's a race condition of sorts. The element that fired the request is being replaced by the incoming content before the ajax:complete should be fired so maybe it's not bubbling out.

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

3 participants