- source codeProject Files in Zip (63.9 KB)
- mp4Full Size H.264 Video (21.5 MB)
- m4vSmaller H.264 Video (9.41 MB)
- webmFull Size VP8 Video (10.9 MB)
- ogvFull Size Theora Video (22.9 MB)
We’ll add Turbolinks to this application to see how it works. First we’ll add it to the list of gems in the gemfile then run bundle to install it.
turbolinks. Turbolinks doesn’t depend on jQuery so we can use it even if we don’t use jQuery in our application.
//= require jquery //= require jquery_ujs //= require turbolinks //= require_tree .
If we restart our Rails application now we can browse around it like before although we won’t notice much difference when we do. We can check to see if Turbolinks is active by opening the network inspector and then clicking around the site. When we do this it seems that a full page reload is happening each time we click a links and so Turbolinks isn’t active. This could be because the browser we’re using isn’t supported by Turbolinks and so we could upgrade it or use a different one. Turbolinks expects a recent browser but if it isn’t supported then it will degrade gracefully and our app will still work like we expect it to. Instead let’s try viewing our page again in a recent version of Chrome. When we do we’ll see that when we click a link now the page isn’t fully reloaded. Instead an AJAX request is made for the next page by the
body elements so that it looks like the new page. It also uses the Push State API to modify the URL so that of the new page. This technique is very similar to PJAX, which was covered in episode 294.
jQuery -> $('.edit_task input[type=checkbox]').click -> $(this).parent('form').submit()
This code listens for the
click event for each of the tasks’ checkboxes. When one is clicked, the form that contains the checkbox is submitted and the task is marked as complete. The important line in this code is the first one, which calls the
jQuery function. This code listens for the
ready event on the document which is triggered when the page’s DOM has finished loading. If we didn’t wrap the rest of the code in this function then jQuery would try attaching
click events to the matching checkboxes before they had loaded in.
When we use Turbolinks this callback is only triggered on the initial page load. This means that if we start on another page then move to the page for a task the DOM’s
ready event isn’t fired as we’re still technically on the same HTML page. There are several events that Turbolinks will trigger, one of which is called
page:load. We can use this to simulate the DOM ready behaviour in our CoffeeScript file.
ready = -> $('.edit_task input[type=checkbox]').click -> $(this).parent('form').submit() $(document).ready(ready) $(document).on('page:load', ready)
Now we set the function that checks the checkboxes to a variable called
ready and pass it to both the
document.ready and the
page:load events. This way the events for the checkboxes will be attached whether we’ve loaded the page via Turbolinks or not. With this change in place the checkboxes now work as we expect them to again and checking an incomplete task will move it to the completed list.
If we want this behaviour automatically we can use the JQuery Turbolinks gem. There is another way we can work around this problem. Instead of selecting elements and listening to their
click events we can listen to the document’s
click event and check to see when this event fires if the element that caused the event was the checkbox for a task.
$('document').on 'click', '.edit_task input[type=checkbox]', -> $(this).parent('form').submit()
It’s a good idea to keep an eye on the Turbolinks issue tracker as there are some issues that we should be aware of. There are several third-party libraries that are incompatible with Turbolinks such as Twitter Bootstrap and jQuery UI Calendar although work is in progress to make them compatible. Also there are some odd situations where reloading the page or clicking the back button in certain browsers can cause some unexpected behaviour such as submitting a POST request instead of a GET in certain circumstances. Workarounds for these issues exist that will disable Turbolinks in these situations, although they shouldn’t be needed in future versions of Turbolinks.
With all these issues you might be wondering whether using Turbolinks is worth it. One thing that may persuade you to use it is Turbolinks Test. This runs benchmarks to see if Turbolinks gives a speed boost in certain situations and most of the time it does, reducing response time by up to a half. Of course all applications are different but it’s easy to use this with your own applications to see if it’s responsiveness is improved.
If we create a new Rails 4 application and decide not to use Turbolinks we can easily remove it by commenting-out the gem in the gemfile and the