-
9 Sep 2009 7:53 AM #1
Window hide then close vs window close... Problems re-opening the window.
Window hide then close vs window close... Problems re-opening the window.
I've got a window that animates on show and I also want it to animate on close. I can make it animate on close by calling hide and then calling close after hide, but re-opening the window causes the content to break. If I simply call close() without the animation, the content reloads just fine.
This works and destroys the window, but doesn't animate:
This animates, but doesn't correctly close/destroy the window:Code:mywindow.close(true);
This also animates but doesn't correctly destroy the window:Code:mywindow.hide(target) mywindow.on("hide",function(win){ win.close(true); },this)
Anyway, not sure what I can do here. The window definitely needs to animate when it's closed, but it doesn't seem to be destroyed properly when I call hide then close in the callback/hide handler.Code:mywindow.hide(target,function(win){ win.close(true); },this);
**edit**
Also just found out the 'beforehide' event gets fired on close. Is this intentional? Seems it should only be fired on hide.
**edit again**
Here's the full code for the window in case it helps:
Code:this.formWindow = new Ext.Window({ title: title, width: width, border: true, bodyBorder: true, height: height, shadow: true, modal: true, animateTarget: target, edit: edit, closable: false, cls: 'editor-window', resizable: false, buttons: [ { text: "Register Online", id: "RegisterButton"+this.id, hidden: hideRegister, handler: function() { this.registerOnline(); }, scope: this }, { text: " Download Event ", id: "DownloadButton"+this.id, hidden: hideDownload, handler: function() { this.downloadEvent(); }, scope: this }, { text: "Print", id: "PrintButton"+this.id, hidden: hidePrint, handler: function() { this.printForm(); }, scope: this }, { text: " Send Test Message ", id: "SendTestButton"+this.id, hidden: hideSend, handler: function() { this.sendTestMessage(); }, scope: this }, { text: "Send", id: "SendButton"+this.id, hidden: hideSend, handler: function() { this.sendMessage(); }, scope: this }, { text: "Submit", id: "SubmitButton"+this.id, hidden: hideSubmit, handler: function() { this.submitForm(); }, scope: this }, { text: "Save", id: "SaveButton"+this.id, disabled: true, hidden: hideSave, handler: function() { this.submitForm(); }, iconCls: 'save-button', scope: this }, { text: "Edit", id: "EditButton"+this.id, hidden: true, handler: function() { this.editForm(); }, scope: this }, { text: "Delete", id: "DeleteButton"+this.id, hidden: hideDelete, handler: function() { this.deletePost(); }, scope: this }, { text: "Cancel", id: "CancelButton"+this.id, hidden: hideCancel, handler: function(){ if (this.editMode) { this.restoreView(); } else { this.closeWindow(); } }, iconCls: 'cancel-button', scope: this }, { text: "Close", id: "CloseButton"+this.id, hidden: hideClose, handler: function(){ this.closeWindow(); }, scope: this } ] }); this.formWindow.on("render",function(win){ win.el.mask(); //this is here because IE is lame and height:'auto' doesn't work like other browsers //Ext tries to account for this in the mask() function, but the timing is off in this case. if (Ext.isIE) { var mask = win.el.child('.ext-el-mask'); mask.setHeight(800); } var text = this.formWindow.el.child(".x-window-header-text"); text.wrap({ tag: 'div', style: 'float:left;' }); var header = this.formWindow.el.child(".x-window-header"); var wrap = header.createChild({ tag: 'div', id: 'buttonwrap'+this.formWindow.id, style: 'float:right;margin-top:-3px;width:110px;' }); header.createChild({ tag: 'div', style: 'clear:both;' }); this.closeButton = new Ext.Component({ renderTo: wrap, autoEl:{ tag: 'div', style: 'float:right;width: 57px;height:18px;background-image:url(/library/Ext/OverrideImages/icons-close-help.png);cursor:pointer;background-position:0 0;' }, listeners: { render: { fn: function (button) { button.el.on("click",function(e,dom,stuff){ this.closeWindow(); },this); }, scope: this } } }); this.helpButton = new Ext.Component({ renderTo: wrap, autoEl:{ tag: 'div', style: 'float:left;width: 53px;height:18px;background-image:url(/library/Ext/OverrideImages/icons-close-help.png);cursor:pointer;background-position:0 -18px;' }, listeners: { render: { fn: function(button){ button.el.on("click",function(e,dom,stuff){ this.showHelp(dom,config.helpUrl); },this); }, scope: this } } }); var clear = new Ext.Component({ renderTo:wrap, autoEl: { tag: 'div', style: 'clear:both;' } }); },this); this.formWindow.on("beforeshow",function(){ this.formWindow.load({ url: url, loadScripts: true, scripts: true, callback: function() { var self = this; var temp = []; if (config.objEditWin) {temp.push("objEditWin")} if (config.objEditWinDesc) {temp.push("objEditWinDesc")} this.showEditors(temp); return true; }, scope: this }); },this); this.formWindow.on("show",function(win) { this.formWindow.el.child('.x-window-body').setStyle('overflow','auto'); var self = this; setTimeout(function(){ self.centerWindow(); self.formWindow.syncShadow(); },10); },this); this.formWindow.show(); closeWindow: function() { if (this.helpWin) { this.closeHelp(); } var target = Ext.get(Ext.get(document.body).select('.clsSignIn').elements[0]); if (this.formDirty || this.datesDirty || this.recurrenceDirty) { Ext.MessageBox.confirm("Close this window?","Any changes you have made will not be saved.<br/>Are you sure you want to close this window?",function(answer) { if (answer === "yes") { delete(this.renderd); delete(this.formDirty); delete(this.recurrenceDirty); delete(this.datesDirty); this.resetVars(); this.formWindow.close(true); //this.formWindow.hide(target,function(win){ // win.close(true); //},this); } },this); } else { this.resetVars(); this.formWindow.close(true); //this.formWindow.hide(target,function(win){ // win.close(true); //},this); } },
-
10 Sep 2009 7:00 AM #2
No ideas, eh?
-
10 Sep 2009 7:23 AM #3
What "ideas"? You call close on a Window with the default closeAction, and it gets destroyed.
Destroyed meaning you can't use it again.
If you just want to hide it, then just hide it.Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
10 Sep 2009 8:33 AM #4
I want it to animate before close. Close has no animation feature. Hide does. So, in order for it to animate on close, I have to call hide and then call close on the callback. Doing this does not properly destroy the window. If I call close, outright, it does destroy the window properly but doesn't animate.
I'm not reusing it... I'm destroying and re-creating. It needs to be this way because of the content being received from the server or I would just hide, update, and show.
-
10 Sep 2009 9:20 AM #5
Hide it and destroy in the callback.
But you said "re-opening the window causes the content to break".
Which means you are reusing it after destruction.Search the forum: http://www.google.com/coop/cse?cx=01...%3Az7of1ufqccu
Read the docs too: http://extjs.com/deploy/dev/docs/
Scope: http://extjs.com/forum/showthread.ph...642#post257642
-
10 Sep 2009 10:45 AM #6
I'm creating a new instance after destruction... By reusing I thought you meant re-opening the same window, which isn't the case.
calling destroy instead of closed fixes the problem, but doesn't close(true) automatically destroy? Weird.
Cool though and thanks for your help.
-
26 Sep 2009 7:56 PM #7
I just ran into basically the same problem zhegwood is describing last night while checking my app for leaks, though I don't care about the animate. I have a TabPanel in a ViewPort where the customer can open and close many Panels (interfaces) at will. Some of these interfaces manage prompt windows. The first time the customer requests the window, I create it. When the customer dismisses the window I hide it. On subsequent requests I re-show it.
The problem occurs when the customer closes the tab page and I call close() on a hidden window. When calling close() on a hidden window, the close event does not fire and the window is not destroyed.
Here's the problem:
Looking at the close() method we see that it unconditionally calls hide() and then relies upon the callback from hide() to fire the close event and call destroy().
If we look at the hide() method, we see that it returns prior to using the callback if the window is hidden causing the cleanup to be skipped.Code:close : function(){ if(this.fireEvent("beforeclose", this) !== false){ this.hide(null, function(){ this.fireEvent('close', this); this.destroy(); }, this); } }
I realized of course that I could simply call the destroy() method, however, since this method is not documented in the public interface I didn't feel too comfortable using it. So I came up with the following override if anyone is interested.Code:hide : function(animateTarget, cb, scope){ if(this.activeGhost){ // drag active? this.hide.defer(100, this, [animateTarget, cb, scope]); return; } if(this.hidden || this.fireEvent("beforehide", this) === false){ return; } if(cb){ this.on('hide', cb, scope, {single:true}); } ... ... ... }
Finally, if we care about the animation we can modify the override to this.Code:Ext.override(Ext.Window, { close : function(){ if(this.fireEvent("beforeclose", this) !== false){ if( this.hidden === false ){ this.hide(null, this.doClose, this); }else{ this.doClose(); } } }, doClose: function(){ this.fireEvent('close', this); this.destroy(); } });
Hope this helps...Code:Ext.override(Ext.Window, { close : function(animateTarget){ if(this.fireEvent("beforeclose", this) !== false){ if( this.hidden === false ){ this.hide(animateTarget || this.animateTarget, this.doClose, this); }else{ this.doClose(); } } }, doClose: function(){ this.fireEvent('close', this); this.destroy(); } });
-
11 Jan 2010 5:42 PM #8
Thanks arandal, that really helped
Thanks arandal, that really helped
Thanks for that override code, it helped with my situation, which was like zhegwood's.
Basically, I have a window where closable is set to false and I force the user to use my buttons. One of the buttons says this.close(); which correctly closes the window but for some reason does not perform the animation. If I set closable:true and click the "x" tool, Ext will correctly render the animation.
It's as if the 'x' tool does more than the this.close() method.
Anyway, thanks for the fix. Worked great.


Reply With Quote