Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making jQuery works with Turbolinks

I have a Rails 4 app, which uses Turbolinks. My understanding is that Turbolinks breaks jQuery code, as Turbolinks does not load new page, but only get new elements.

Therefore, navigating to new page may not trigger .ready, although it always triggers .page:load, and thus new jQuery code won't initialize.

I have a lot of jQuery code, so I don't want to modify my jQuery code to be compatible with Turbolinks.

Is it possible to add a javascript code to my application.js that overwrites .ready event to include page:load as well? How should I do it?

like image 939
AdamNYC Avatar asked Sep 27 '13 05:09

AdamNYC


People also ask

Why we use Turbolinks in Rails?

Turbolinks Overview It is intended to speed up navigating between pages of your application. It works by intercepting all link clicks that would navigate to a page within the app, and instead makes the request via AJAX, replacing the body with the received content.

How Turbo links work?

Turbolinks works by automatically fetching your page, swapping its DOM's body, and mixing it with the head . This allows the library to understand what has changed on the page without having to infer a full load.

What is data Turbolinks track?

Turbolinks can track the URLs of asset elements in <head> from one page to the next and automatically issue a full reload if they change. This ensures that users always have the latest versions of your application's scripts and styles.


4 Answers

Rather than wait for $(document).ready to fire for your jQuery, just use page:load instead:

$(document).on 'page:load' ->
  <your code>

Alternatively, you can set up the jquery.turbolinks gem: https://github.com/kossnocorp/jquery.turbolinks

like image 199
Tyler Avatar answered Oct 11 '22 19:10

Tyler


With turbolinks 5.0.0, the events changed to turbolinks:load. See full list of turbolinks events.

The documentation recommends following code:

document.addEventListener("turbolinks:load", function() {
  // ...
})

The jquery.turbolinks fork located at https://github.com/dalpo/jquery.turbolinks already reflects these changes and allows for a seamless drop-in of turbolinks. Nevertheless, I would go for the turbolinks:load event to have full control and not require another library.

like image 33
koppor Avatar answered Oct 11 '22 18:10

koppor


i had to use the page:change event:

js:

$(document).on('page:change', function () {
    <code here>
});

coffee script:

$(document).on 'page:change' ->
    <code here>
like image 23
wasd-wasd Avatar answered Oct 11 '22 19:10

wasd-wasd


With TurboLinks 5 / Rails 5 ... I would recommend instantiating DataTables like this.

It will prevent the heading and footer paging from showing up multiple times when the back button is used.

$(document).on 'turbolinks:load', ->
  tableElementIds = [
    '### TABLE ID HERE ###'
  ]
  i = 0
  while i < tableElementIds.length
    tableElementId = tableElementIds[i]
    if $.isEmptyObject($.find(tableElementId))
      i++
      continue
    table = undefined
    if $.fn.DataTable.isDataTable(tableElementId)
      table = $(tableElementId).DataTable()
    else
      table = $(tableElementId).DataTable(### OPTIONS HERE ###)

    document.addEventListener 'turbolinks:before-cache', ->
      table.destroy()
      return

    i++

  return
like image 21
aldefouw Avatar answered Oct 11 '22 19:10

aldefouw