82e73b08ec9cf5e8045111828971425eb68190ec
[tine20] / tine20 / Tinebase / js / ux / PopupWindow.js
1 /*
2  * Tine 2.0
3  * 
4  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
5  * @author      Cornelius Weiss <c.weiss@metaways.de>
6  * @copyright   Copyright (c) 2007-2008 Metaways Infosystems GmbH (http://www.metaways.de)
7  *
8  */
9  
10 Ext.ns('Ext.ux');
11
12 /**
13  * Class for handling of native browser popup window.
14  * <p>This class is intended to make the usage of a native popup window as easy as dealing with a modal window.<p>
15  * <p>Example usage:</p>
16  * <pre><code>
17  var win = new Ext.ux.PopupWindow({
18      name: 'TasksEditWindow',
19      width: 700,
20      height: 300,
21      url:index.php?method=Tasks.editTask&taskId=5
22  });
23  * </code></pre>
24  * 
25  * @namespace   Ext.ux
26  * @class       Ext.ux.PopupWindow
27  * @extends     Ext.Component
28  */
29 Ext.ux.PopupWindow = function(config) {
30     Ext.apply(this, config);
31     this.contentPanelConstructorConfig = this.contentPanelConstructorConfig || {};
32
33     this.addEvents({
34         /**
35          * @event beforecolse
36          * @desc Fires before the Window is closed. A handler can return false to cancel the close.
37          * @param {Ext.ux.PopupWindow}
38          */
39         "beforeclose" : true,
40         /**
41          * @event render
42          * @desc  Fires after the viewport in the popup window is rendered
43          * @param {Ext.ux.PopupWindow}
44          */
45         "render" : true,
46         /**
47          * @event close
48          * @desc  Fired, when the window got closed
49          */
50         "close" : true
51     });
52
53     Ext.ux.PopupWindow.superclass.constructor.call(this);
54 };
55
56 Ext.extend(Ext.ux.PopupWindow, Ext.Component, {
57     /**
58      * @cfg    {String}
59      * @param  {String} url
60      * @desc   url to open
61      */
62     url: null,
63     /**
64      * @cfg {String} internal name of new window
65      */
66     name: 'new window',
67     /**
68      * @cfg {Int} width of new window
69      */
70     width: 500,
71     /**
72      * @cfg {Int} height of new window
73      */
74     height: 500,
75     /**
76      * @cfg {Bolean}
77      */
78     modal: false,
79     /**
80      * @cfg {String}
81      */
82     layout: 'fit',
83     /**
84      * @cfg {String}
85      */
86     title: null,
87     /**
88      * @cfg {String} Name of a constructor to create item property
89      */
90     contentPanelConstructor: null,
91     /**
92      * @cfg {Object} Config object to pass to itemContructor
93      */
94     contentPanelConstructorConfig: null,
95     /**
96      * @property {Browser Window}
97      */
98     popup: null,
99     /**
100      * @property {Ext.ux.PopupWindowMgr}
101      */
102     windowManager: null,
103
104     renderTo: 'useRenderFn',
105
106     /**
107      * @private
108      */
109     initComponent: function(){
110         if (! this.title) {
111             this.title = Tine.title;
112         }
113         
114         this.windowManager = Ext.ux.PopupWindowMgr;
115
116         this.stateful = true;
117         this.stateId = 'ux.popupwindow-' + this.contentPanelConstructor;
118         this.on('resize', this.saveState, this, {delay:100});
119
120         Ext.ux.PopupWindow.superclass.initComponent.call(this);
121         
122         //limit the window size
123         this.width = Math.min(screen.availWidth, this.width);
124         this.height = Math.min(screen.availHeight, this.height);
125     },
126
127     render: function() {
128         // open popup window first to save time
129         if (! this.popup) {
130             this.popup = Tine.Tinebase.common.openWindow(this.name, this.url, this.width, this.height);
131         }
132
133         //. register window ( in fact register complete PopupWindow )
134         this.windowManager.register(this);
135
136         // does not work on reload!
137         //this.popup.PopupWindow = this;
138
139         // strange problems in FF
140         //this.injectFramework(this.popup);
141
142         // NOTE: Do not register unregister with this events,
143         //       as it would be broken on window reloads!
144         /*
145          if (this.popup.addEventListener) {
146          this.popup.addEventListener('load', this.onLoad, true);
147          this.popup.addEventListener('unload', this.onClose, true);
148          } else if (this.popup.attachEvent) {
149          this.popup.attachEvent('onload', this.onLoad);
150          this.popup.attachEvent('onunload', this.onClose);
151          } else {
152          this.popup.onload = this.onLoad;
153          this.popup.onunload = this.onClose;
154          }
155          */
156     },
157
158     getState : function() {
159         return {
160             width: this.popup.innerWidth,
161             height: this.popup.innerHeight
162         };
163     },
164
165     /**
166      * rename window name
167      * 
168      * @param {String} new name
169      */
170     rename: function(newName) {
171         this.windowManager.unregister(this);
172         this.name = this.popup.name = newName;
173         this.windowManager.register(this);
174     },
175     
176     /**
177      * Sets the title text for the panel and optionally the icon class.
178      * 
179      * @param {String} title The title text to set
180      * @param {String} iconCls (optional) iconCls A user-defined CSS class that provides the icon image for this panel
181      */
182     setTitle: function(title, iconCls) {
183         if (this.popup && this.popup.document) {
184             this.popup.document.title = Ext.util.Format.stripTags(title);
185         }
186     },
187     
188     /**
189      * Closes the window, removes it from the DOM and destroys the window object. 
190      * The beforeclose event is fired before the close happens and will cancel 
191      * the close action if it returns false.
192      */
193     close: function() {
194         if(this.fireEvent("beforeclose", this) !== false){
195             this.fireEvent('close', this);
196
197             var popup = this.popup;
198
199             this.destroy();
200
201             if (popup.history && popup.history.length > 1) {
202                 popup.history.back();
203             } else {
204                 Ext.ux.PopupWindow.close(popup);
205             }
206         }
207     },
208     
209     /**
210      * @private
211      * 
212      * called after this.popups native onLoad
213      * note: 'this' references the popup, whereas window references the parent
214      */
215     onLoad: function() {
216         this.Ext.onReady(function() {
217             //console.log(this);
218             //console.log(window);
219         }, this);
220     },
221     
222     /**
223      * @private
224      * 
225      * note: 'this' references the popup, whereas window references the parent
226      */
227     onClose: function() {
228
229     },
230     
231     /**
232      * @private
233      */
234     destroy: function() {
235         Ext.ux.PopupWindow.superclass.destroy.call(this);
236         
237         this.purgeListeners();
238         this.windowManager.unregister(this);
239
240         this.popup = null;
241     }
242 });
243
244 /**
245  * close window and show close message
246  *
247  * @static
248  * @param win
249  */
250 Ext.ux.PopupWindow.close = function(win) {
251     win = win || window;
252     win.close();
253
254     // FIXME there is somthing very fishy here ... / this throws lots of errors
255     // defer messagebox as it should not be displayed too early
256     //    window.setTimeout(function(){
257     //        if (! win) {
258     //            return;
259     //        }
260     //
261     //        win.Ext.MessageBox.alert(
262     //            i18n._('Window can be closed'),
263     //            String.format(i18n._('This Window can be closed now. To avoid this message please deactivate your browsers popup blocker for {0}'), Tine.title),
264     //            function() {
265     //                win.close();
266     //            }
267     //        );
268     //    }, 500);
269 };