hendricd
08-16-2007, 01:56 PM
Setting a loadMask (true||{msg: 'Loading...'}) on the grid (and other widgets) hooks the onbeforeLoad Event of the attached datastore to the loadMask. But, the datastore load-processing can be so intensive that the expected DOM update for the mask may not be visible until after the datastore.[re]load operation completes. Kinda defeats the purpose of the mask?
Here's how to smooth things out a bit:
// Let's add a couple new convenience methods to Ext.LoadMask
Ext.apply(Ext.LoadMask.prototype,{
visible:false,
onBeforeLoad : function(){
if(!this.disabled && !this.visible){
this.el.mask(this.msg, this.msgCls);
this.visible = true;
}
},
onLoad : function(){
this.el.unmask(this.removeMask);
this.visible = false;
},
show:function(msg, append){
if(!this.disabled){
if(msg){
this.msg= append?this.msg + '<br/>'+ msg:msg;
}
this.onBeforeLoad();
}
},
showDefer:function(msg,fn,config){
config || (config={});
this.show(msg, config.append||false);
if(fn){
config = Ext.apply({scope:this,millis:100,"arguments":[],appendArguments:false},config);
fn.defer(config.millis,config.scope,[].concat(config.arguments),config.appendArguments);
}
},
hide:function(){ this.onLoad(); }
});Now the example:
<style type="text/css">
html, body {
font:normal 12px verdana;
margin:0px;
padding:0px;
border:0px none;
overflow:hidden;
height:100%;
}
</style>
<script language="JavaScript" type="text/javascript">
var App = function(){
return {
startMask:null,
init: function(){
this.cm = new Ext.grid.ColumnModel(yourColumns);
this.ds = new Ext.data.Store(yourOptions);
this.grid = new Ext.grid.Grid('your-grid-container', {
ds: this.ds,
cm: this.cm,
loadMask: {msg: 'Loading...'}
});
this.grid.render(); //this is what hooks the loadMask to datastore
if(this.startMask){
this.startMask.hide(); //enuff candy
}
this.grid.loadMask.show(); //force it 'on' now
var options = {callback:function(r, options, success){
if(success){App.grid.getSelectionModel().selectFirstRow();}
// .... do other stuff
}
};
//Give the DOM a chance to show your loadMask: defer the load for a few milliseconds !
this.ds.load.defer(100,this.ds,[options]);
//then, the datastore.load method will clean-up the mask, as usual, for you.
}
};
}(); //end App
Ext.onReady(function(){
// First, a generic document mask (candy) when the DOM is ready:
App.startMask = new Ext.LoadMask(document.body,{});
//the easy way
App.startMask.showDefer('Setting Up Your Grid...',App.init,{scope:App, millis:600});
// or, the classic way
//App.startMask.show('Setting Up Your Grid...');
//App.init.defer(600,App); //Give the startMask time to show itself.
}, App, true);
</script>
[edit] Added showDefer method to handle a defered call at the same time.
[tags: loadmask mask lagging]
Cheers,
Here's how to smooth things out a bit:
// Let's add a couple new convenience methods to Ext.LoadMask
Ext.apply(Ext.LoadMask.prototype,{
visible:false,
onBeforeLoad : function(){
if(!this.disabled && !this.visible){
this.el.mask(this.msg, this.msgCls);
this.visible = true;
}
},
onLoad : function(){
this.el.unmask(this.removeMask);
this.visible = false;
},
show:function(msg, append){
if(!this.disabled){
if(msg){
this.msg= append?this.msg + '<br/>'+ msg:msg;
}
this.onBeforeLoad();
}
},
showDefer:function(msg,fn,config){
config || (config={});
this.show(msg, config.append||false);
if(fn){
config = Ext.apply({scope:this,millis:100,"arguments":[],appendArguments:false},config);
fn.defer(config.millis,config.scope,[].concat(config.arguments),config.appendArguments);
}
},
hide:function(){ this.onLoad(); }
});Now the example:
<style type="text/css">
html, body {
font:normal 12px verdana;
margin:0px;
padding:0px;
border:0px none;
overflow:hidden;
height:100%;
}
</style>
<script language="JavaScript" type="text/javascript">
var App = function(){
return {
startMask:null,
init: function(){
this.cm = new Ext.grid.ColumnModel(yourColumns);
this.ds = new Ext.data.Store(yourOptions);
this.grid = new Ext.grid.Grid('your-grid-container', {
ds: this.ds,
cm: this.cm,
loadMask: {msg: 'Loading...'}
});
this.grid.render(); //this is what hooks the loadMask to datastore
if(this.startMask){
this.startMask.hide(); //enuff candy
}
this.grid.loadMask.show(); //force it 'on' now
var options = {callback:function(r, options, success){
if(success){App.grid.getSelectionModel().selectFirstRow();}
// .... do other stuff
}
};
//Give the DOM a chance to show your loadMask: defer the load for a few milliseconds !
this.ds.load.defer(100,this.ds,[options]);
//then, the datastore.load method will clean-up the mask, as usual, for you.
}
};
}(); //end App
Ext.onReady(function(){
// First, a generic document mask (candy) when the DOM is ready:
App.startMask = new Ext.LoadMask(document.body,{});
//the easy way
App.startMask.showDefer('Setting Up Your Grid...',App.init,{scope:App, millis:600});
// or, the classic way
//App.startMask.show('Setting Up Your Grid...');
//App.init.defer(600,App); //Give the startMask time to show itself.
}, App, true);
</script>
[edit] Added showDefer method to handle a defered call at the same time.
[tags: loadmask mask lagging]
Cheers,