PDA

View Full Version : Cancel loadmask



DavidSSL
29 Aug 2011, 4:22 AM
I would like to create an override for the loadmask http://docs.sencha.com/ext-js/4-0/#!/api/Ext.LoadMask
(http://docs.sencha.com/ext-js/4-0/#!/api/Ext.LoadMask)to work in the following way:

The UI should display a cancel button
Clicking on the cancel button should cancel the operation that was requested and remove the load mask.
I believe that to remove the loading mask, I'd just have to call the hide() method. However, what are the broad guidelines on how to inject the "Cancel" button and perform the event cancellation?

mitchellsimoens
29 Aug 2011, 12:32 PM
You can hook into the afterRender method and render a button or a link into the msgEl element.


Ext.define('MyLoadMask', {
extend : 'Ext.LoadMask',

afterRender: function() {
var me = this,
msgEl = me.msgEl;

//render whatever here

me.callParent(arguments);

//Listen for click on a link, not need if you use a button
me.mon(msgEl, {
delegate : '',
click : someFn
});
}
});

DavidSSL
30 Aug 2011, 12:45 AM
Thank you Mitchell. I have no doubt that this code will work. However, I think I'll encounter the same issues that I've been encountering with http://www.sencha.com/forum/showthread.php?145395-Writing-extension-in-Ext-Js-4&p=642651#post642651. Also, wouldn't you say that using Ext.override would be better http://edspencer.net/2009/07/extoverride-monkey-patching-ext-js.html as I want it throughout my application?

Any help wrt the way to write the code within an MVC architecture would be really welcome.

mitchellsimoens
30 Aug 2011, 4:56 AM
If you want to change everything then yes, override would be the way to go.

DavidSSL
30 Aug 2011, 6:27 AM
Ok,

I've decided to get the override working. First, I tried to get the Ed Spencer's code working http://edspencer.net/2009/07/extoverride-monkey-patching-ext-js.html but nothing happened. Then I tried to get the code provided for the overrides from here http://docs.sencha.com/ext-js/4-0/#!/video/17920271 going. Again nothing happened.

Finally, I tried to get things to a bare minimum and in my application class I've got the following code:



Ext.Loader.setConfig({ enabled: true });


Ext.override(Ext.LoadMask, {
afterRender: function () {
console.log('in');
}
});

Ext.application({
name: 'InventoryPartGrid',

appFolder: '../../Ext.js/app',


Still nothing happened. Can anyone point me in the right direction on how to wire this code up?

mitchellsimoens
30 Aug 2011, 6:28 AM
Is Ext.LoadMask present when you try to do the override?

DavidSSL
30 Aug 2011, 6:29 AM
Is Ext.LoadMask present when you try to do the override?

I am a bit lost here. What do you mean by this? What I can tell you is that the load mask appears and once the data has loaded, it disappears.

mitchellsimoens
30 Aug 2011, 6:33 AM
Meaning... when the Ext.override method executes, is Ext.LoadMask loaded or is it dynamically loaded when it is shown via Ext.Loader?

DavidSSL
30 Aug 2011, 6:39 AM
Meaning... when the Ext.override method executes, is Ext.LoadMask loaded or is it dynamically loaded when it is shown via Ext.Loader?

If I understand you correctly, I would say that the mask is dynamically loaded via Ext.Loader. I'm not explicitly calling the loading mask. Effectively, the load mask appears over the grid panel and as soon as the data has been populated inside the grid, the load mask disappears.

My apologies if I am not quite answering you but as a newbie, I am not familiar with all the ins and outs of Ext.Js.

Actually I'm a bit surprised by your question because it must mean that there's a gap in my knowledge.

From what I understood from the video, overriding the class would affect "all" instances of the overriden class. As I mentioned, the loading mask is being shown and so I assumed that my code should have worked as result.

DavidSSL
2 Sep 2011, 3:44 AM
Meaning... when the Ext.override method executes, is Ext.LoadMask loaded or is it dynamically loaded when it is shown via Ext.Loader?

The issue is that the Ext.override method never gets called.

DavidSSL
5 Sep 2011, 6:16 AM
You can hook into the afterRender method and render a button or a link into the msgEl element.


Ext.define('MyLoadMask', {
extend : 'Ext.LoadMask',

afterRender: function() {
var me = this,
msgEl = me.msgEl;

//render whatever here

me.callParent(arguments);

//Listen for click on a link, not need if you use a button
me.mon(msgEl, {
delegate : '',
click : someFn
});
}
});

Hi Mitchell, in the code that you've supplied, me.msgEl throws errors. Can you please advise on what it should be?

mitchellsimoens
5 Sep 2011, 6:48 AM
Playing around with it, this works for me:


Ext.define('MyLoadMask', {
extend : 'Ext.LoadMask',
alias : 'widget.myloadmask',

afterRender: function() {
var me = this,
el = me.el;

me.cancelEl = el.createChild({
tag : 'a',
html : 'Cancel'
});

me.callParent(arguments);

me.mon(me.cancelEl, {
click: function(e, t, o) {
me.hide();
}
});
}
});


Ext.create('MyLoadMask', Ext.getBody(), {
msg : 'Test'
}).show();

DavidSSL
5 Sep 2011, 6:59 AM
Hi Mitchell,

Thank you for the prompt answer. However, I'm trying to override it. I have tried overriding the afterRender event but that never gets called. So is that a bug? It only works if I override onLoad. So the code I've got is something like:

Ext.override(Ext.LoadMask, {
afterRender: function () {

console.log('afterRender called');

}
, onLoad: function () {
var me = this;

var msgEl = me.el;

msgEl.insertHtml('afterBegin', '<button>Cancel</button>');

this.callOverridden();


//console.log('onLoad executed');
//this.afterRender();
}
});

Ext.application({
name: 'InventoryPartGrid'
, uses: ['Ext.LoadMask']





This code kind of works, i.e. the button gets shown but the fact is that I don't want to have to manage the LoadMasks for the grid panel. I just want the framework to show the load mask but with a cancel button which will cancel the operation and remove the load mask. For instance, there might be situations whereby the loadmask appears but for one reason or another, it doesn't get hidden and hence the need for that cancel button.

Hope I've been clearer.

mitchellsimoens
5 Sep 2011, 7:05 AM
Ext.require('Ext.LoadMask', function() {

Ext.override(Ext.LoadMask, {
afterRender: function () {
var me = this,
el = me.el;

me.cancelEl = el.createChild({
tag : 'a',
html : 'Cancel'
});

me.callOverridden(arguments);

me.mon(me.cancelEl, {
click: function(e, t, o) {
me.hide();
}
});
}
});

});

DavidSSL
5 Sep 2011, 7:10 AM
Hi again Mitchell,

This code I would have expected it to work for sure and in fact I was getting there! However, the afterRender event never gets called and that's where I've been wasting a lot of time. I'm working with version 4.0.2a. Could that be the reason why?

mitchellsimoens
5 Sep 2011, 7:14 AM
You aren't really listening for an event... this is an internal method that fires an event but you are just hooking into the method instead of listening for the event.

In the code you posted, you overrode the afterRender method and didn't call the overriden method (callOverriden) so that is going to screw things up.

DavidSSL
5 Sep 2011, 7:19 AM
My apologies to keep this going but I copied your code verbatim and still the cancel button doesn't work. I've added a console.log('afterRender called') just before the declaration of 'me' but that never gets output to the console in firebug.

So yes I fully expect your code to work but in my case it isn't hence why I started using onLoad and why I mentioned the version of Ext js I'm using.

mitchellsimoens
5 Sep 2011, 7:23 AM
Seems there is a difference between 4.0.2a and 4.0.6 in LoadMask... In 4.0.2a it extends Ext.Base but in 4.0.6 it extends Ext.Component.

nahab
7 Feb 2014, 8:07 AM
Reincarnation.

I also tried your solution Mitchell but it works only for Components.

Since Ext.getBody() return Ext.Element and not Component it doesn't use extended LoadMask class at all instead there are hardcoded in Ext.dom.Element.mask()

nahab
10 Feb 2014, 5:33 AM
Final notes,

if you want that your customized LoadMask works you need either use Viewport - because it is component, or if you don't use it you can create some "dummy" Viewport that only be used for displaying your customized LoadMask. Like one below:



Ext.define('App.view.EmptyViewport', {
extend: 'Ext.container.Viewport',


alias: 'widget.emptyviewport',


layout: 'fit'
});


Notice layout used - with this one I haven't HTML page layouting side effects. But maybe in your case just creating of standard Ext.container.Viewport will not broke page layouting.

Then use it like this:



var vp = Ext.create('App.view.EmptyViewport');
this.loadMask = new Component.LoadMaskWithCancelling(vp, {msg: this.standardMessage})


PS. Just left this information here because my bank denied access to employees to wordpress :) Also I hope that one day this info will become helpful for anyone.