9

I'm using datatables and have data being collected from a database to an array then displayed onscreen. All this works fine.

If the data is around 2000 rows and 7 columns it only takes a couple of seconds, however if it's 10,000 rows and 7 columns it can take around 30 -40 seconds, so I would like to add an overlay that greys out the screen and displays "Loading.. Please Wait"

I've tried various scripts and code that I've found on this site and online, but none seem to work. I usually get the delay followed by a flash of the overlay and then it's gone.

Can any one help ?

This is the datatables code I'm using :

UPDATE: This is the page without the DB queries.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>TEST</title>
<style type="text/css">
    @import "layout_page.css";
    @import "layout_table.css";
    html { overflow-y: scroll; };
</style>
<link href="layout.css" rel="stylesheet" type="text/css">
<script src="jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="jquery.dataTables.min.js" type="text/javascript"></script>
<script src="jquery.jeditable.js" type="text/javascript"></script>
<script src="jquery.dataTables.editable.js" type="text/javascript"></script>
</head>
<body id="dt_test">
<div id="container"><div id="layout">

<?php

if(!function_exists('json_encode'))
{
    include_once('JSON.php');
    $GLOBALS['JSON_OBJECT'] = new Services_JSON();
    function json_encode($value)
    { return $GLOBALS['JSON_OBJECT']->encode($value); }

    function json_decode($value)
    { return $GLOBALS['JSON_OBJECT']->decode($value); }
}


//
// DB QUERIES
??
    $result = json_encode($data);
?>

<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
    $('#demo').html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="example"></table>' );
    $('#example').dataTable( {
        "aaData": <?php echo $result ?>,
        "aoColumns": [
            { "sTitle": "Order" },
            { "sTitle": "Name" },
            { "sTitle": "Rank" },
            { "sTitle": "Number", "sClass": "center" },
            { "sTitle": "Locale", "sClass": "center" },
        { "sTitle": "Email", "sClass": "center" },
            { "sTitle": "Description", "sClass": "center" }
            ],
            "bJQueryUI": true,
            "bProcessing": true,
            "bSort": false,
            "bSortClasses": false,
            "bDeferRender": false,
            "sPaginationType": "full_numbers",
            "aLengthMenu": [[10, 25, 50, 100, 250, 500, -1], [10, 25, 50, 100, 250, 500, "All"]],

        "fnRowCallback": function( nRow, aData, iDisplayIndex ) {
            var id = "users"+":"+aData[0];
            $(nRow).attr("id",id);
            return nRow;
        }
    } );
    $('#example').dataTable().makeEditable({
            sUpdateURL: "update.php",
    });
} );
</script>

<div class='demo' id='demo' name='demo'></demo></div>

</div></div>
</body>
</html>

How would I add an overly that is displayed BEFORE anything else... then is removed one the table is ready ?

UPDATE: Updated my original post with the entire page minus the DB Queries. I need the Overlay to display BEFORE any DB queries happen and before datatables starts processing the table.

Thanks

MacMan
  • 925
  • 1
  • 14
  • 32

3 Answers3

8

You can do something like this :

CSS :

#overlay {
    height: 100%;
    width: 100%;
    position: absolute;
    top: 0px;
    left: 0px;
    z-index: 99999;
    background-color: gray;
    filter: alpha(opacity=75);
    -moz-opacity: 0.75;
    opacity: 0.75;
    display: none;
}
#overlay h2 {
    position: fixed;
    margin-left: 40%;
    top: 40%;
}

markup :

<div id="overlay"><h2>Loading .. Please wait</h2></div>

when you want to show the message / overlay eg just before dataTable :

$("#overlay").show();

callback in your dataTable() when it has finished initalizing :

$('#example').dataTable( {
   ...
   fnInitComplete : function() {
      $("#overlay").hide();
   }
});
davidkonrad
  • 83,997
  • 17
  • 205
  • 265
  • Updated my original post with the entire page minus the DB Queries. I need the Overlay to display BEFORE any DB queries happen and before datatables starts processing the table. – MacMan Nov 18 '13 at 14:07
  • Why dont you use the above approach? Why an empty onclosed `
    `?? `#layout` covers the entire screen, you should not have anything but the message inside it. If you implement it as described, and place `$("#overlay").show();` as the very first line in your `$(document).ready(function()`, it will work.
    – davidkonrad Nov 18 '13 at 14:16
  • Thanks.. I have tried that but it doesn't show anything. I'm using Chrome to test this.. – MacMan Nov 18 '13 at 14:22
  • Me too :) And have tested with firefox also. Think you got it wrong. See this fiddle -> http://jsfiddle.net/v7YmW/ for implementation. cannot reproduce 10000 rows, so you must click to hide the overlay. – davidkonrad Nov 18 '13 at 14:30
  • Thanks. I'll try this again. It's almost as if the DB queries are being run first. – MacMan Nov 18 '13 at 15:00
  • Hmm.. still not working for me. I've added it as you have but I don;t get the loading overlay at all ! – MacMan Nov 18 '13 at 15:44
  • Go this working by loading my datatables page into a div from a separate php page. Thanks for your help :) – MacMan Nov 19 '13 at 14:13
-1

A long-running JavaScript will freeze the browser, preventing it from being updated. To accommodate this, you need to add a delay (even a 0ms delay) between displaying the overlay, and starting the script. Add this delay using setTimeout():

$("#overlay").show();
setTimeout(function () {
    // initialize dataTable here
}, 0);

In your case specifically, it looks like you initialize the dataTable immediately when the page loads. Is it correct that you want the page to load with the overlay visible, then hide it when the data is loaded, and never show it again (unless the page is reloaded)? In that case, just put the overlay on the page visible by default. Only use JavaScript to hide it.

#overlay {
    display: block;  /* Default visible!! */
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background-color: rgba(255, 255, 255, 0.5);
}
    ...
    <div id="overlay"></div>
</body>
// dataTable initialization code here
$("#overlay").hide();

Edit: In actually testing this, I found Chrome was inconsistent. In most cases it would not render the page unless I put in at least a few ms delay before initializing the datatable. In theory, a 0ms delay should be enough, but in practice, this seems not to be the case.

http://jsfiddle.net/DgSuJ/

gilly3
  • 87,962
  • 25
  • 144
  • 176
  • Thanks.. not sure why these aren't working for me. When I load the page there is the delay and then the page processes. No overlay ! – MacMan Nov 19 '13 at 08:54
-1

I got a very easy solution online for me and it worked in an excellent way. You can also try with this solution:

In the initialization of datatable, use this code:

$(document).ready(function() { $('#example').dataTable({ "order": [[ 0, 'asc' ]] }); $('#example').show(); } );

In your HTML code, hide the table initially as display:none. Use like this:

<table id="example" cellspacing="0" width="100%" style="display:none">

codewitharefin
  • 1,398
  • 15
  • 24