Ask A Question

Notifications

You’re not receiving notifications from this thread.

Properly adding Turbolinks 5 event handling

Chris Zempel asked in General

Here's what I understand:

  • Turbolinks preserves the window and document from request to request
  • As a result, I should add click/change listeners to the window/document once when the js is first loaded so that it can execute when the relevant element click happens (the element may not be loaded on the page yet)

This is possible because of "event delegation," or when you click on a specific child element of the document, you're effectively clicking on the entire body and it will sequentially trigger that event up the DOM tree all the way to the document root.

This is why the TL readme says:

When possible, avoid using the turbolinks:load event to add event listeners directly to elements on the page body. Instead, consider using event delegation to register event listeners once on document or window.

Where I'm stuck is, how do I add an event listener to window to listen for specific elements that may not exist yet? I'd prefer to do this with css selectors and not with if statements checking them, but at this point I'm not even sure if thats an option.

I'd like the $.on style of setting things up, but it seems like I'll have to check the element the event was triggered on before deciding what to do.

here's some example code of a place where I'd like to do that. This displays different filter options based on what other filter options are selected:

document.addEventListener "turbolinks:load", ->
  $('#school_type').on 'change', ->
    selection = this.options[this.selectedIndex].value
    if selection == "HighSchool"
      $("[data-behavior='college-division-select']").css(display:'none')
      $("[data-behavior='high-school-enrollment-select']").css(display:'block')
    else
      $("[data-behavior='high-school-enrollment-select']").css(display:'none')
      $("[data-behavior='college-division-select']").css(display:'block')
  .trigger('change')

It works, but how could I catch the change event happening on the #school_type element on the window?

Lastly, but also firstly, is this something even worth worrying about?

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 81,536+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more.

    © 2024 GoRails, LLC. All rights reserved.