Display spinner while DataTables table loads Ruby on Rails

13,966

Solution 1

You can add in a spinner gif (find one here: http://www.ajaxload.info/) as a div where your table should be and then clear it when the table loads using initComplete.

Put something like this right below <div class="col-md-12">:

<img id="loadingSpinner" src="/myspinner.gif">

And then call your table like this:

$(document).ready(function() {
  var table = $('#app-list-table').DataTable({
    //any other datatables settings here
    "initComplete": function(settings, json) {
      $('#loadingSpinner').hide();
      //or $('#loadingSpinner').empty();
    }
  })
});

Solution 2

If the data is loaded in Ruby, there's no point in loading a spinner because the data has already loaded by then. This is a bare-bones ordering of what happens in your Rails app:

  1. Controller then view Ruby executes, rendering HTML
  2. HTML is sent to client
  3. Client requests linked CSS and JS in order
  4. CSS and JS execute in order
  5. Asynchronous JS finishes

So, the majority of your delay is happening at step 1, but a CSS/JS spinner won't load until step 4. If you want to use a spinner, you need to load the data via async Ajax, so you can load the spinner in 4, then finish loading data and remove spinner in 5. Using jQuery Ajax:

var spinner = new Spinner().spin(document.getElementById('spinner'));
$.ajax("/your/data/path.json")
.done(function(data) {
  // load data here, then load table:
  var table = $('#app-list-table').DataTable({ … })
  // remove spinner
  $('#spinner').remove();
});

You could of course add the spinner to your current code:

var spinner = new Spinner().spin(document.getElementById('spinner'));
$('#app-list-table').DataTable({ 
  …
  initComplete: function() { $('#spinner').remove(); }
})

However, again, since most of the delay happens in Ruby, you'll only see the spinner for a brief moment at the end of the delay. To see the spinner for the whole delay, use Ajax.

Share:
13,966
TheFlanman91
Author by

TheFlanman91

I work in IT and have a keen interest in programming across many platforms including Android, C#, Java, HTML/CSS, Ruby on Rails, etc.

Updated on June 28, 2022

Comments

  • TheFlanman91
    TheFlanman91 almost 2 years

    Using Rails I have built a web app. One of the pages of the web app displays a table which uses the DataTables API. This JSFiddle shows an example of what my web app looks like.

    The problem with this is that when I begin to add in large amounts of data (current test data is 1500 rows), the table loads each row first before running the javascript meaning you get an unformated table for a few seconds before the Javascript kicks in and DataTables activates.

    I would like to display a spinner, or processing message (something along those lines) in place of the table until the page has fully populated, once that has finished I would like to run my javascript activating DataTables.

    EDIT: My main issue is I'm not sure how to use Javascript to display the spinner while the table loads but then change to the table once the page has finished loading

    My code is as follows:

    HTML/eRB

    <div class="list">
        <div class="container">
            <div class="row">
                <div class="col-md-12">
                    <table id="app-list-table" class="display table" cellspacing="0">
                        <thead>
                            <tr class="table-headers">
                                <th>Header 1</th>
                                <th>Header 2</th>
                                <th>Header 3</th>
                                <th>Header 4</th>
                                <th>Header 5</th>
                                <th>Header 6</th>
                                <th>Header 7</th>
                                <th>Header 8</th>
                                <th>Header 9</th>
                                <th>Header 10</th>
                            </tr>
                        </thead>
                        <tbody>
                            <%= Server.find_each do |server| %>
                            <tr>
                                <td><%= link_to(server.server_name, server_path(server)) %></td>
                                <td><%= server.application %></td>
                                <td><%= server.server_role %></td>
                                <td><%= server.team_contact %></td>
                                <td><%= server.individual_contact %></td>
                                <td><%= server.business_owner %></td>
                                <td><%= server.vendor %></td>
                                <td><%= server.vendor_contact %></td>
                                <td><%= link_to("Click Here", server.main_doc) %></td>
                                <td><%= server.main_win %></td>
                            </tr>
                            <% end %>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
    

    Javascript

    $(document).ready(function() {
            var table = $('#app-list-table').DataTable({
                "scrollX": true
    
            });
        });
    

    Please let me know if there is anything else you would like me to include.

  • TheFlanman91
    TheFlanman91 over 8 years
    That worked perfectly for hiding the spinner once the table loaded! Thank you. One more thing though is to have the table hidden from the time the page loads until DataTables has initialised. Is there a javascript function ti initialise code when the page has first loaded?
  • jonmrich
    jonmrich over 8 years
    Unfortunately, you can't do that as far as I know. If datatables can't find the div for the table, you'll get errors and it won't load. This includes if the div is hidden or added after the fact.
  • TheFlanman91
    TheFlanman91 over 8 years
    I see.. Thanks for the help.
  • TheFlanman91
    TheFlanman91 over 8 years
    Thanks for this. I'm going to try and hid the div some other way but your spinner implementation helped
  • TheFlanman91
    TheFlanman91 over 8 years
    Apologies I'm not looking to use AJAX. Thanks for the answer though