uhm, don't know if it'll help you, BTW, I also had to figure a "way" to display some "loading pictures" (from now on, I'll call them "spinners") to my pages. I had to face 2 distinct problems: - loading components via Ajax (through LOAD() or web2py_component()) - prevent FOUC on very complex pages
for the first problem I actually "hacked" web2py.js (web2py_ajax.js or so). the ajax function needs to be modified.... the basic idea is to replace content of the target with a spinner (in this case, a div containing the message "loading...") before sending the request, and upon success replace it with the content actually loaded... you can add a beforeSend parameter for that and take care of replacing the content adding something to the success function. My code actually is something like this... function ajax(u,s,t) { query = ''; if (typeof s == "string") { d = jQuery(s).serialize(); if(d){ query = d; } } else { pcs = []; if (s != null && s != undefined) for(i=0; i<s.length; i++) { q = jQuery("[name="+s[i]+"]").serialize(); if(q){pcs.push(q);} } if (pcs.length>0){query = pcs.join("&");} } jQuery.ajax({ type: "POST", url: u, data: query, beforeSend: function( xhr ) { if(t) {jQuery("#" + t).html('<div id="loadingwindow">Loading...</div>')}; }, success: function(msg) { if(t) { if(t==':eval') eval(msg); else { jQuery("#loadingwindow").fadeOut(400, function () { jQuery("#" + t).html(msg).hide().fadeIn(400); }); } } } }); } for the second problem, I had to hide window contents because of some complex javascript needs to be run to validate several fields and to rearrange heavily the DOM (tabs, selects with a large number of options to turn into multiselects, a tree with jstree) until the "transformation" completes. Fortunately I could figure out what was the "script" block that is going to be always the last to be finished (not executed), so I can address that "event" with the "action" of displaying my page again. All this introduction to warn you about an hiccup in the following method: if you have built (like me) some widgets to be modular, you'll end up having various <script> blocks around your page: from what I can tell you can only be sure that they are executed "in order" of what is found in the page, but you can't tell what will be the last to stop executing. NB: this method works only if you must display a spinner in a one-time-only manner, e.g.: you have a complex page that needs to be temporarily "hidden" and you want to prevent FOUC. Truth told, I figured out this way to prevent FOUC and display the page after all DOM work is done : step 1: add to the css this rule #wloading.amloading { position: absolute; left: -10000px; } step 2: add a function to web2py.js (or anywhere else that you are sure it's loaded with every page) function finished_loading() { if ($('loadingwindow').length == 0) { setTimeout(function() { $("#wloading").removeClass("amloading"); $("#loadingwindow").remove(); }, 1500); } } step 3: define two "widgets" in models (can be elaborated further with positioning, simulating "modal" loading, etc etc etc.). Following is the basic ones def loading_widget_start(): script = """ $("#wloading").addClass("amloading"); $("#wloading").before('<div id="loadingwindow">Loading...</div>'); """ rtn = SCRIPT(script, _type="text/javascript") return rtn def loading_widget_stop(): script = """ setTimeout(function() { finished_loading(); }, 5000); """ rtn = SCRIPT(script, _type="text/javascript") return rtn step 4: embed every page that needs to be loaded in a <div id="wloading"> step 5: add {{=loading_widget_start()}} right after <div id="wloading"> and before the actual content step 6: put {{=loading_widget_stop()}} at the very end of the page (just to be sure) You can now use the finished_loading() "callback" after the most expensive <script> or complex functions and be sure that the content will be hidden until callback is called. If you don't call finished_loading() explicitely, the loading_widget_stop() will be called at the very end of your page and will wait 5 seconds before showing the page to the user. If you have further questions don't be afraid to ask. PS: I'm aware that I'm not using a document.ready event to fire all up, that kind of "blocks" the whole idea of using a function before all DOM is loaded.....from what I can tell as long as jquery is loaded in the <head> you can be sure that the library is loaded before the body, so working on a div that is declared just before the "managing it with jquery" <script> will work. I'm not a javascript guru, I'm just compelled to have a page working the way I (or my users) want in the shortest time possible. If you know a better and "traditional" method please tell me, I'm eager to learn and maybe you'll help others in the same "condition" :D