Display spinner while DataTables table loads Ruby

2019-02-17 07:33发布

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.

4条回答
何必那么认真
2楼-- · 2019-02-17 07:46

If you are looking for a way to hide the datatable until it's ready, it is possible to do this by putting the datatable inside a div that is initially set to display:none and then showing the div after you've initialised the datatable... I also included an opaque overlay div over the whole page while the datatable(s) are loading and a delay of 500 ms to force the loading effect.

<script type="text/javascript" language="javascript" >
$(document).ready(function () {

	$(function(){
	   function loadDataTable(){
		
			var dataTableId = $('#dataTableId').dataTable({"initComplete": function(settings, json) {$('.overlay').hide();});
			$('#divContatingDataTable').show();
	};
	   window.setTimeout(loadDataTable, 500);
	});

});
</script>
<style type="text/css">
	.overlay {
		background: #ffffff;
		position: absolute;
		top: 0;
		right: 0;
		bottom: 0;
		left: 0;
		width:100%;
		height:100%;
		text-align: center;
		opacity: 0.8;
	}
</style>
<div class="overlay">
	This div / overlay contains a loading message / image and can be styled however you like
	<img class="loading" src="loading.gif" />
</div>


<div id="divContatingDataTable" style="display:none;">
	<!-- Datatable contents with id dataTableId go here -->
</div>

查看更多
做自己的国王
3楼-- · 2019-02-17 07:51

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();
    }
  })
});
查看更多
你好瞎i
4楼-- · 2019-02-17 07:55

Ive used the code provided on the link below, but insteat of using an old jquery version you should use the latest one (3.x), otherwise Datatables will crash. Hope this help

http://bradsknutson.com/blog/display-loading-image-while-page-loads/

查看更多
唯我独甜
5楼-- · 2019-02-17 08:06

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.

查看更多
登录 后发表回答