PDA

View Full Version : Loading indicator



harley.333
4 Apr 2007, 6:01 PM
Perhaps the following should be default behavior:


this.grid.getDataSource().on("beforeload", function() {
Ext.get(this.grid.id).dom.style.cursor = "wait";
}, this, true);
this.grid.getDataSource().on("load", function() {
Ext.get(this.grid.id).dom.style.cursor = "pointer";
}, this, true);

harley.333
4 Apr 2007, 6:05 PM
8-| BTW, how would someone go about adding this Jack's Grid class so that all Grids get the behavior? I'm not going to modify his source, and I'd prefer not to create my own Grid class overriding his.

mikegiddens
4 Apr 2007, 8:08 PM
Well I am not to sure how accurate that would be. For example the existing cursor may not be pointer and the Ext has to take that into consideration. I do agree that there should be a cursor wait but for me I use grids in different way.

Example: I have an advanced search in an west panel while my grid is in the center. Even if I put document.body.style.cursor = '<cursor>'; in the before and load I still have fields that overrule the document cursor. I do not know a way to apply a cursor change to a whole window but that would be the best for me.

Just my 2 cents.

finco
6 Apr 2007, 11:58 AM
Where would that code be placed?

Joe
6 Apr 2007, 6:40 PM
Adding popup "Loading...." message to the grid

Summary: This code shows how to make a popup that says loading while the grid loads data.

finco, you asked 'Where would that code be placed?'
harley.333, you asked 'how would someone go about adding this Jack's Grid class so that all Grids get the behavior?'

finco, a quick answer - try to add this.grid = grid; and plug in his code before ds.load();

For the complex answer but easy to use plug-in code - read on.
* please provide updates - anyone!

Background
I am new to JS so this post may need corrections, refactoring (replacement?), but it may help you get an idea of how to 'override code' without updating the base.

Note: Realizing we can create our own subclass of Grid to add functionality, this is a quick method of doing something like that. Sometimes you just want to "pull the strings" a little. So this shows a way to "attach" functionality to an existing object without actually sub-classing it. If you want to create a subclass - please share :o).

Overview:
1) Add following code to a js file and save
Example uses file called ModExt.js

2) Add one line to the grid to extend functionality.
ModExt.grid.addLoadingMsg( {grid:grid, msg:'Loading Someting Specific ...'} );

ModExt.js Contents


/**** Add on file for Ext JS (http://extjs.com)
*---
* by Joseph Francis (Apr-2007) [ExtJS Member: Joe]
* Note: Author open for comments, corrections, slocumization, etc.
*---
* Namespace: ModExt (Adds a new namespace for custom add-ons)
*---
* Setup: Add this file after your normal file to extend Ext functionality.
* Example: <script type="text/javascript" src="/<some-random-location>/ModExt.js">
****
* Add-ons:
* Grid - Add Loading Message
****
*/
//--- Define root namespace
ModExt = {};
//--- Define grid specific area
ModExt.grid = {};

/* Grid - Add Loading Message
*
* Add Loading Message:
* ModExt.grid.addLoadingMsg(o)
*
* Options:
* grid = Grid Object [Required]
* msg = Dialog Message Text. Default = 'Loading ....... '
* title = Dialog Title. Default = 'Please wait...'
*
* Sample Use:
* ModExt.grid.addLoadingMsg( {grid:grid, msg:'Loading Someting Specific ...'} );
*
* This demo code shows how to add a wait popup to an existing grid.
* This will make a popup that says loading, that covers the screen
* and when loaded, the popup goes away and animates to the grid.
*/

ModExt.grid.dlg = null;

ModExt.grid.getDialog = function(o){
var o = o || {};
var msg = o.msg || 'Loading ....... ';
var title = o.title || 'Please wait...';
if(ModExt.grid.dlg == null){
ModExt.grid.dlg = new Ext.BasicDialog(Ext.get(), {
autoCreate : true,
shadow: true,
closable: false,
draggable: true,
resizable:false,
constraintoviewport:false,
fixedcenter:true,
collapsible : false,
shim:true,
animateTarget: null,
modal: true,
width:200, height:100,
buttonAlign:"center"
});
ModExt.grid.dlg.bodyEl = ModExt.grid.dlg.body.createChild({
tag:"div",
html:'' + msg
});
}
ModExt.grid.dlg.setTitle(title);
ModExt.grid.dlg.bodyEl.dom.innerHTML = msg;
return ModExt.grid.dlg;
}

ModExt.grid.doneLoading = function(o){
ModExt.grid.dlg.hide();
},
ModExt.grid.addLoadingMsg = function(o){
if (!o.grid){return};

//--- Get grid and params from object or defaults
var grid = o.grid;

var msg = o.msg || 'Loading ....... ';
var title = o.title || 'Please wait...';

grid.getDataSource().on("load", function(){
ModExt.grid.gridloaded = true;
ModExt.grid.doneLoading();
});

grid.getDataSource().on("beforeload", function() {
//--- Show message box with params
ModExt.grid.gridloaded = false;
var dlg = ModExt.grid.getDialog({msg:msg, title:title});
dlg.on('show', function(){if(ModExt.grid.gridloaded == true){ModExt.grid.doneLoading()}});
dlg.show(ModExt.grid.animEl);
}, this, true);

}




The code has full comments but here is a summary:

Add the .js in the <script> file list.
This will provide you with a new function: ModExt.grid.addLoadingMsg(o)

Use as follows:


// ... Sample basic code ...
grid.render();
grid.addListener( "dblclick", ondbclick, this);
grid.addListener( "keypress", onkeypress, this);

//----- Plug in the one line here with options as shown
ModExt.grid.addLoadingMsg( {grid:grid, msg:'Loading Someting Specific ...'} );
//----- End of addition

ds.load();

// ... Continued...


More Discussion

Add to the base or not - that is the question
At first it seems the grid is "missing functionality" and that something should be added to the base. I have cases where my server sends out --> comments and it crashes Ext. But that is non standard, so it is 'not a bug', I have to 'over the top' fix it (beyond the scope of this post). So I feel for you. The other side of the coin is - as you can imagine - if every option needed was added to the base, we would be waiting a full minute for the "base" to download. Adding code into the center of the base classes makes it turn into luggage for those not using it. By plugging in or sub-classing, this provides layers like an onion that can be applied as needed, making for slimmer downloads, etc.

The reason I did the ModExt.grid thing was to show how to make a namespace (I think that is what it is called). Was that correct?

Ok - that is it, sorry for the long post, but lots to cover.

Comments?

justheatingup
7 Apr 2007, 5:07 PM
Joe, I think it would be sweeter if the progress bar was relative to the grid instead of the page. Maybe a progress bar inside the grid region? Currently, this prevents interaction with the rest of the page, which might be the desired functionality.

harley.333
7 Apr 2007, 5:18 PM
I agree. I want the loading indicator to be specific to the grid. Getting data from the server is async, so my users shouldn't have to wait until everything is done.

Joe
7 Apr 2007, 5:26 PM
Good Idea.

If you know how to make this happen - can you provide updated code? If not, I'll figure it out and post an update becuase I want this to be the case as well.

I just tossed this together - it far from a complete component. A graphical loading indicator would be nice, etc.

Before I went nuts down that line, I wanted to see if Jack or someone was going to come back and say .. why don't you just use the grid.jackAlreadyHadThisDone(oh) function :)

Also wanted to show how you can extend functionality without updating the base and did not want to over shadow that with a zillion options.

Hope this helps and thanks again for input / responses :)

justheatingup
8 Apr 2007, 11:01 PM
Hey Joe it's Abe.

You might want to take a look at this post for a different way of extending base classes.

http://extjs.com/forum/showthread.php?t=3803

Let me know what you think.

Joe
9 Apr 2007, 6:51 AM
Thank you for taking the time to point to that post. I did a very quick update to the function as shown below based on the link.

There may be better code - but this works. Please post better code if you have it.

Here is the quick mod:


var GridMods = function() {
return {

getDialog : function(o){
var o = o || {};
var msg = o.msg || 'Loading ....... ';
var title = o.title || 'Please wait...';
if(this.dlg == null){
this.dlg = new Ext.BasicDialog(Ext.id(), {
autoCreate : true,
shadow: true,
closable: false,
draggable: true,
resizable:false,
constraintoviewport:false,
fixedcenter:true,
collapsible : false,
shim:true,
animateTarget: null,
modal: true,
width:200, height:100,
buttonAlign:"center"
});
this.dlg.bodyEl = this.dlg.body.createChild({
tag:"div",
html:'' + msg
});
}
this.dlg.setTitle(title);
this.dlg.bodyEl.dom.innerHTML = msg;
return this.dlg;
},

doneLoading : function(){
this.gridloaded = null;
this.dlg.hide();
},
addLoadingMsg : function(o){
var grid = this;
var msg = o.msg || 'Loading ....... ';
var title = o.title || 'Please wait...';

this.getDataSource().on("load", function(){
this.gridloaded = true;
this.doneLoading();
}, this, true);

this.getDataSource().on("beforeload", function() {
//--- Show message box with params
this.gridloaded = false;
var dlg = this.getDialog({msg:this.waitMsg, title:this.waitTitle}); //msg:msg, title:title
dlg.on('show', function(){if(this.gridloaded == true){this.doneLoading()}});
dlg.show(this.animEl);
}, this, true);
this.waitMsg = msg;
this.waitTitle = title;
}

};
}();

Ext.apply(Ext.grid.Grid.prototype, {doneLoading: GridMods.doneLoading, addLoadingMsg: GridMods.addLoadingMsg, getDialog: GridMods.getDialog});




Then the code is updated as follows:



grid.addLoadingMsg( {msg:'Loading ' + 'Whatever makes since here'} );


I have not taken the time on this quick update to make this happen by default for all grids. If you have an update for that to happen (anyone) please post. Else I will look to post if anyone wants it.

Thanks for the pointer to the better way to do this.

jack.slocum
10 Apr 2007, 6:57 PM
Please see this thread:

http://extjs.com/forum/showthread.php?p=22065

Joe
10 Apr 2007, 7:12 PM
As usual, you are amazing Jack!

soniya_ahuja
19 Aug 2008, 3:20 AM
I was faced with the problem of displaying loading... message while a treeloader loaded data.

I tried the following with the variable in which treeloader was an attribute
e.g var viewTreeLoader = { .....
loader: new Ext.tree.TreeLoader({dataUrl: 'someurl' }),.....}

In the listeners for the above variable, based on Jack's post, I added the following snippet

beforeLoad: function()
{
loadMask: new Ext.LoadMask(this.el,
{msg:'Message while loading', store:this.loader});
}
And it worked \:D/