If your Rails app performs time consuming AJAX requests, such as image uploads or API calls, it might be nice to let the user know with a spinner animation.
To demonstrate the use of spinners, let’s assume we have a Rails application with an Image model that accepts file uploads via AJAX. While an image is uploading, will show the animated pure CSS spinner. When the upload is complete, we will hide the spinner again. This can be done easily with or without turbolinks in rails. TIP: Check out the AJAX Image Uploads Lesson first.
Lesson Resources
Lesson Checkpoints
1. Spinner CSS
First, we need to define the CSS for our spinner. There’s a variety of samples on the web, but we’re going to use the awesome SpinKit created by Tobias Ahlin. He takes advantage of the @keyframes
rule to create animations by continuously shifting from one CSS style to another.
assets/stylesheets/spinner.css
Head over to SpinKit and grab the CSS/HTML you want to use in your app. Drop the styles into the images.scss file and you're ready to go.
With the CSS defined, we just need to add a div with the spinner
class where it should appear on the page.
views/images/new.html.erb
<div class="spinner"></div>
Or use HippIcon Spinners
As an alternative, you might want to use the open soruce animated HippIcons spinners. This is a good way to go if your app is already using HippIcons, like us...
Loading...
2. Listen for AJAX with jQuery
At this point, our spinner is spinning endlessly on the page. We can use jQuery to toggle the visibility of the spinner. First, we are going to hide the spinner on page load. Second, we will listen for an AJAX call to start and show the spinner when this event occurs. Last, we will listen for the AJAX call to stop and re-hide the spinner.
javascripts/images.js
$( document ).ready(function() {
// hide spinner
$(".spinner").hide();
// show spinner on AJAX start
$(document).ajaxStart(function(){
$(".spinner").show();
});
// hide spinner on AJAX stop
$(document).ajaxStop(function(){
$(".spinner").hide();
});
});
3. Delaying the Spinner in Development
If you’re uploading images from your local machine, they will be uploaded almost instantaneously, thereby hiding the spinner very quickly. In development, it is useful to add a delay()
to the ajaxStop
event. The code below will delay hiding the spinner for 3 seconds after the AJAX call has stopped.
$(document).ajaxStop(function(){
$(".spinner").delay(3000).hide(0);
});
4. Spinners with Turbolinks
If your app uses the turbolinks gem, you will need to take a slightly different approach to using spinners. Turbolinks fires an ajax call each time the user clicks a link, so it's usually a good idea to show some sort of indicatator that the page content is loading. Using jQuery, we can show and hide spinners on the page between each page load.
$(document).on("page:fetch", function(){
$(".spinner").show();
});
$(document).on("page:receive", function(){
$(".spinner").hide();
});