How to enable `sorttable.js` on Rails4 with turbol

2019-05-31 16:33发布

问题:

  • Rails 4.2.0, turbolinks (2.5.3)
  • jquery-rails (4.0.3), jquery-ui-rails (5.0.3)
  • sorttable.js
  • App used on Chrome, Firefox, and IE

WHAT SHOULD HAPPEN: Whether a redirect, render, or just clicking to a new page in the app, any table with class sorttable (I edited it in the original JS) should be sortable by column heading.

WHAT ACTUALLY HAPPENS: I am on a contacts page. I hit refresh, and logger statements in the JS appear. The plugin works as expected. If I navigate to Home, then back to Contacts, the file is still listed in the page source, but no logger statements appear. The plugin does not work.

Our application.js reads as such:

//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require jquery_nested_form
//= require bootstrap
//= require sorttable
//= require_directory .
//= require autocomplete-rails
//= require turbolinks
//= require bootstrap-switch

Disabling Turbolinks per-page or altogether is not a solution for us. I am open to using gems if the file just does not work with turbolinks; however, the gem should add little code to the app. We'd rather not have classes dedicated to choosing which column to sort. Also, some columns to-be-sorted are not from ActiveRecord (like 2 attributes in 1 cell).

回答1:

After much debugging, I figured out why turbolinks does not like sorttable.js. The JS file includes triggers (some based on browser type) to initiate sorttable on document load. Such event listener is incompatible with turbolinks. What I have done to make this work is the following.

  1. Move vendor/assets/javascripts/sorttable.js to app/views/shared/js/_sorttable.html.haml

  2. Prefix the new file with :javascript (%script{languauge: "javascript"}), and indent all following lines 2 spaces

  3. Remove sorttable from application.js

  4. At the top of all related pages, add the following code block:

    = render 'shared/js/sorttable'
    %script
      $(document).on("page:change", sorttable.init)
    

For code examples and further explanation, please see this gist.