A YUI Loading Panel Widget
Probably needless to say, but here it is. A web page which is processing a lengthy Ajax request and doesn't provide a loading indicator of any kind will mostly mislead the user to think that the page has stopped responding. So the solution? Use a loading indicator of course. Here's a very handy loading indicator widget for Ajax programmers who use YUI.
Files
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.4.1/build/assets/skins/sam/skin.css">
How to Use
First, create a new instance of loading panel. After that, you can call show or hide method on the loading panel object.
var loadingPanel = new yuiLoadingPanel();
//loadingPanel.show();
//loadingPanel.show("Processing...");
//loadingPanel.hide();
The user can close the loading box by clicking on the cancel link. If you want to handle this situation, you can subscribe to the cancelEvent:
loadingPanel.cancelEvent.subscribe(function(e, a, o){
alert('You clicked cancel!');
});
$D = YAHOO.util.Dom;
$E = YAHOO.util.Event;
var yuiLoadingPanel = function(conf){
conf = conf == undefined ? new Array() : conf;
conf.id = conf.id == undefined ? 'yuiLoadingPanel':confi.id;
conf.header = conf.header == undefined ? 'Loading, please wait...':conf.header;
conf.width = conf.width == undefined ? '240px':conf.width;
this.conf = conf;
this.cancelEvent = new YAHOO.util.CustomEvent("cancelEvent", this);
this.init();
};
yuiLoadingPanel.prototype = {
init:function(){
var loadingPanel = new YAHOO.widget.Panel(this.conf.id,{
width:this.conf.width,
fixedcenter:true,
close:false,
draggable:false,
modal:true,
visible:false
});
loadingPanel.setBody(this.conf.header +
'<img src="http://us.i1.yimg.com/us.yimg.com/i/us/per/gr/gp/rel_interstitial_loading.gif" />');
loadingPanel.render(document.body);
$D.addClass(loadingPanel.id, 'tcc_lightboxLoader');
var cancelLink = document.createElement('a');
$D.setStyle(cancelLink, 'cursor', 'pointer');
cancelLink.appendChild(document.createTextNode('Cancel'));
$E.on(cancelLink, 'click', function(e, o){
o.self.loadingPanel.hide();
o.self.cancelEvent.fire();
}, {self:this});
loadingPanel.appendToBody(document.createElement('br'));
loadingPanel.appendToBody(cancelLink);
$D.setStyle(loadingPanel.body, 'text-align', 'center');
$D.addClass(document.body, 'yui-skin-sam');
this.loadingPanel = loadingPanel;
},
show:function(text){
if(text != undefined){
this.loadingPanel.setHeader(text);
}else{
this.loadingPanel.setHeader(this.conf.header);
}
this.loadingPanel.show();
},
hide:function(){
this.loadingPanel.hide();
}
};
If you find this post useful, consider donating a few bucks to help the server running cost.
More interesting posts ...
Subscribe to keep track of your comment.
51 Comments so far

2. var loadingPanel = new yuiLoadingPanel();
//loadingPanel.show();
//loadingPanel.show("Processing...");
//loadingPanel.hide();
1. Does this go into , section? I assume it needs to be enclosed into standard JavaScript tags <script., right?
2. I plugged all code into blank HTML page, into body and nothing happens when I click button. In Firefox, I get an errors:
YAHOO is not defined
$D = YAHOO.util.Dom;
and
loadingPanel is not defined
onclick(click clientX=0, clientY=0)
Do I need to install something else? Thanks.
You need to include YUI library files, which is described in the *File* section of this post.
<pre>
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.4.1/build/assets/skins/sam/skin.css">
<script type="text/javascript" src="http://yui.yahooapis.com/2.4.1/build/utilities/utilities.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.4.1/build/container/container-min.js"></script>
http://www.mredkj.com/vbnet/AnimatedGifOnPostback.html
any idea how to fix in your example?
change "show function" to this...
show:function(text){
if(text != undefined){
this.loadingPanel.setHeader(text);
}else{
this.loadingPanel.setHeader(this.conf.header);
setTimeout('document.images["Act"].src = "../Images/Activity.gif"', 200);
}
thanks for the code. I am playing with the panel, using it as a dialog (don't want to use the "Dialog" widget for some reasons in this case).
I realized that sometimes submit()'s or onClick()'s fire below the mask so I am disabling all buttons after calling the dlg.show().
However I did not know how to catch if someone cancels the dialog by clicking on "X" as I did not know how to hook onto the hideEvent(). Your code showed me how to subscribe to that event and it works like a charm.
Thx
F.
Sorry for my English.
I'm absolutely beginner in ajax.
I'm using a Ajax loader script in my page.
I understand that if I use YUI for this script. I must use YUI to load my pages on the site? So my Ajax page loader script is unnecessary?
Thx
Faster
I am not sure which Ajax script you are referring to, but if you meant "this one":http://javascript.internet.com/ajax/ajax-loader.html, then the answer is no. YUI has already encapsulated this functionality into its library, which is called the "Connection Manager":http://developer.yahoo.com/yui/connection/.
Go to this <a href="http://developer.yahoo.com/yui/docs/Panel.js.html">URL</a> and take a look the code that has "sizeMask: function ()", you'll see how mask is implemented in YUI. Use style.width, height, left, and top to adjust the mask.
Untested, good luck.
Many thanks
Sorry my bad english, i' am from hungary.
There is the modified source code:
<pre>
yuiLoadingPanel.prototype = {
...
...
...
hide:function(){
this.loadingPanel.hide();
},
updateBody:function(BodyContent,DoNotShowCancelLink){
this.loadingPanel.setBody(BodyContent);
if(!DoNotShowCancelLink){
var cancelLink = document.createElement('a');
$D.setStyle(cancelLink, 'cursor', 'pointer');
cancelLink.appendChild(document.createTextNode('Bezaras'));
$E.on(cancelLink, 'click', function(e, o){
o.self.loadingPanel.hide();
o.self.cancelEvent.fire();
}, {self:this});
this.loadingPanel.appendToBody(document.createElement('br'));
this.loadingPanel.appendToBody(cancelLink);
}
},
updateBodyWithTimedHide:function(BodyContent,Timer){
this.loadingPanel.setBody(BodyContent);
setTimeout(function(){this.loadingPanel.hide();}.bind(this), Timer);
},
updateBodyWithTimedFunctionCall:function(BodyContent,FunctionToCall,Timer){
this.loadingPanel.setBody(BodyContent);
eval("setTimeout(function(){this.loadingPanel.hide();" FunctionToCall "}.bind(this), Timer)");
}
};
Probably needless to say, but here it is. A web page which is processing a lengthy Ajax request and doesn't provide a loading indicator of any kind will mostly mislead the user to think that the page has stopped responding. So the solution? Use a load...
you can Submit your work portfolio, logo design and website design in daily updated web2.0 CSS Design Gallery. It's totally free.
Visit this site and submit your Portfolio.
http://www.csshook.com
Thanks
Jon
thanks for the code.
Thanks,
Creator
What am I doing wrong?