4 * Copyright(c) 2006-2007, Ext JS, LLC.
6 * Originally Released Under LGPL - original licence link has changed is not relivant.
9 * <script type="text/javascript">
13 * @class Roo.BasicDialog
14 * @extends Roo.util.Observable
15 * Lightweight Dialog Class. The code below shows the creation of a typical dialog using existing HTML markup:
17 var dlg = new Roo.BasicDialog("my-dlg", {
26 dlg.addKeyListener(27, dlg.hide, dlg); // ESC can also close the dialog
27 dlg.addButton('OK', dlg.hide, dlg); // Could call a save function instead of hiding
28 dlg.addButton('Cancel', dlg.hide, dlg);
31 <b>A Dialog should always be a direct child of the body element.</b>
32 * @cfg {Boolean/DomHelper} autoCreate True to auto create from scratch, or using a DomHelper Object (defaults to false)
33 * @cfg {String} title Default text to display in the title bar (defaults to null)
34 * @cfg {Number} width Width of the dialog in pixels (can also be set via CSS). Determined by browser if unspecified.
35 * @cfg {Number} height Height of the dialog in pixels (can also be set via CSS). Determined by browser if unspecified.
36 * @cfg {Number} x The default left page coordinate of the dialog (defaults to center screen)
37 * @cfg {Number} y The default top page coordinate of the dialog (defaults to center screen)
38 * @cfg {String/Element} animateTarget Id or element from which the dialog should animate while opening
39 * (defaults to null with no animation)
40 * @cfg {Boolean} resizable False to disable manual dialog resizing (defaults to true)
41 * @cfg {String} resizeHandles Which resize handles to display - see the {@link Roo.Resizable} handles config
42 * property for valid values (defaults to 'all')
43 * @cfg {Number} minHeight The minimum allowable height for a resizable dialog (defaults to 80)
44 * @cfg {Number} minWidth The minimum allowable width for a resizable dialog (defaults to 200)
45 * @cfg {Boolean} modal True to show the dialog modally, preventing user interaction with the rest of the page (defaults to false)
46 * @cfg {Boolean} autoScroll True to allow the dialog body contents to overflow and display scrollbars (defaults to false)
47 * @cfg {Boolean} closable False to remove the built-in top-right corner close button (defaults to true)
48 * @cfg {Boolean} collapsible False to remove the built-in top-right corner collapse button (defaults to true)
49 * @cfg {Boolean} constraintoviewport True to keep the dialog constrained within the visible viewport boundaries (defaults to true)
50 * @cfg {Boolean} syncHeightBeforeShow True to cause the dimensions to be recalculated before the dialog is shown (defaults to false)
51 * @cfg {Boolean} draggable False to disable dragging of the dialog within the viewport (defaults to true)
52 * @cfg {Boolean} autoTabs If true, all elements with class 'x-dlg-tab' will get automatically converted to tabs (defaults to false)
53 * @cfg {String} tabTag The tag name of tab elements, used when autoTabs = true (defaults to 'div')
54 * @cfg {Boolean} proxyDrag True to drag a lightweight proxy element rather than the dialog itself, used when
55 * draggable = true (defaults to false)
56 * @cfg {Boolean} fixedcenter True to ensure that anytime the dialog is shown or resized it gets centered (defaults to false)
57 * @cfg {Boolean/String} shadow True or "sides" for the default effect, "frame" for 4-way shadow, and "drop" for bottom-right
58 * shadow (defaults to false)
59 * @cfg {Number} shadowOffset The number of pixels to offset the shadow if displayed (defaults to 5)
60 * @cfg {String} buttonAlign Valid values are "left," "center" and "right" (defaults to "right")
61 * @cfg {Number} minButtonWidth Minimum width of all dialog buttons (defaults to 75)
62 * @cfg {Array} buttons Array of buttons
63 * @cfg {Boolean} shim True to create an iframe shim that prevents selects from showing through (defaults to false)
65 * Create a new BasicDialog.
66 * @param {String/HTMLElement/Roo.Element} el The container element or DOM node, or its id
67 * @param {Object} config Configuration options
69 Roo.BasicDialog = function(el, config){
70 this.el = Roo.get(el);
71 var dh = Roo.DomHelper;
72 if(!this.el && config && config.autoCreate){
73 if(typeof config.autoCreate == "object"){
74 if(!config.autoCreate.id){
75 config.autoCreate.id = el;
77 this.el = dh.append(document.body,
78 config.autoCreate, true);
80 this.el = dh.append(document.body,
81 {tag: "div", id: el, style:'visibility:hidden;'}, true);
85 el.setDisplayed(true);
86 el.hide = this.hideAction;
90 Roo.apply(this, config);
92 this.proxy = el.createProxy("x-dlg-proxy");
93 this.proxy.hide = this.hideAction;
94 this.proxy.setOpacity(.5);
98 el.setWidth(config.width);
101 el.setHeight(config.height);
103 this.size = el.getSize();
104 if(typeof config.x != "undefined" && typeof config.y != "undefined"){
105 this.xy = [config.x,config.y];
107 this.xy = el.getCenterXY(true);
109 /** The header element @type Roo.Element */
110 this.header = el.child("> .x-dlg-hd");
111 /** The body element @type Roo.Element */
112 this.body = el.child("> .x-dlg-bd");
113 /** The footer element @type Roo.Element */
114 this.footer = el.child("> .x-dlg-ft");
117 this.header = el.createChild({tag: "div", cls:"x-dlg-hd", html: " "}, this.body ? this.body.dom : null);
120 this.body = el.createChild({tag: "div", cls:"x-dlg-bd"});
123 this.header.unselectable();
125 this.header.update(this.title);
127 // this element allows the dialog to be focused for keyboard event
128 this.focusEl = el.createChild({tag: "a", href:"#", cls:"x-dlg-focus", tabIndex:"-1"});
129 this.focusEl.swallowEvent("click", true);
131 this.header.wrap({cls:"x-dlg-hd-right"}).wrap({cls:"x-dlg-hd-left"}, true);
133 // wrap the body and footer for special rendering
134 this.bwrap = this.body.wrap({tag: "div", cls:"x-dlg-dlg-body"});
136 this.bwrap.dom.appendChild(this.footer.dom);
139 this.bg = this.el.createChild({
140 tag: "div", cls:"x-dlg-bg",
141 html: '<div class="x-dlg-bg-left"><div class="x-dlg-bg-right"><div class="x-dlg-bg-center"> </div></div></div>'
143 this.centerBg = this.bg.child("div.x-dlg-bg-center");
146 if(this.autoScroll !== false && !this.autoTabs){
147 this.body.setStyle("overflow", "auto");
150 this.toolbox = this.el.createChild({cls: "x-dlg-toolbox"});
152 if(this.closable !== false){
153 this.el.addClass("x-dlg-closable");
154 this.close = this.toolbox.createChild({cls:"x-dlg-close"});
155 this.close.on("click", this.closeClick, this);
156 this.close.addClassOnOver("x-dlg-close-over");
158 if(this.collapsible !== false){
159 this.collapseBtn = this.toolbox.createChild({cls:"x-dlg-collapse"});
160 this.collapseBtn.on("click", this.collapseClick, this);
161 this.collapseBtn.addClassOnOver("x-dlg-collapse-over");
162 this.header.on("dblclick", this.collapseClick, this);
164 if(this.resizable !== false){
165 this.el.addClass("x-dlg-resizable");
166 this.resizer = new Roo.Resizable(el, {
167 minWidth: this.minWidth || 80,
168 minHeight:this.minHeight || 80,
169 handles: this.resizeHandles || "all",
172 this.resizer.on("beforeresize", this.beforeResize, this);
173 this.resizer.on("resize", this.onResize, this);
175 if(this.draggable !== false){
176 el.addClass("x-dlg-draggable");
177 if (!this.proxyDrag) {
178 var dd = new Roo.dd.DD(el.dom.id, "WindowDrag");
181 var dd = new Roo.dd.DDProxy(el.dom.id, "WindowDrag", {dragElId: this.proxy.id});
183 dd.setHandleElId(this.header.id);
184 dd.endDrag = this.endMove.createDelegate(this);
185 dd.startDrag = this.startMove.createDelegate(this);
186 dd.onDrag = this.onDrag.createDelegate(this);
191 this.mask = dh.append(document.body, {tag: "div", cls:"x-dlg-mask"}, true);
192 this.mask.enableDisplayMode("block");
194 this.el.addClass("x-dlg-modal");
197 this.shadow = new Roo.Shadow({
198 mode : typeof this.shadow == "string" ? this.shadow : "sides",
199 offset : this.shadowOffset
202 this.shadowOffset = 0;
204 if(Roo.useShims && this.shim !== false){
205 this.shim = this.el.createShim();
206 this.shim.hide = this.hideAction;
215 var bts= this.buttons;
217 Roo.each(bts, function(b) {
226 * Fires when a key is pressed
227 * @param {Roo.BasicDialog} this
228 * @param {Roo.EventObject} e
233 * Fires when this dialog is moved by the user.
234 * @param {Roo.BasicDialog} this
235 * @param {Number} x The new page X
236 * @param {Number} y The new page Y
241 * Fires when this dialog is resized by the user.
242 * @param {Roo.BasicDialog} this
243 * @param {Number} width The new width
244 * @param {Number} height The new height
249 * Fires before this dialog is hidden.
250 * @param {Roo.BasicDialog} this
255 * Fires when this dialog is hidden.
256 * @param {Roo.BasicDialog} this
261 * Fires before this dialog is shown.
262 * @param {Roo.BasicDialog} this
267 * Fires when this dialog is shown.
268 * @param {Roo.BasicDialog} this
272 el.on("keydown", this.onKeyDown, this);
273 el.on("mousedown", this.toFront, this);
274 Roo.EventManager.onWindowResize(this.adjustViewport, this, true);
276 Roo.DialogManager.register(this);
277 Roo.BasicDialog.superclass.constructor.call(this);
280 Roo.extend(Roo.BasicDialog, Roo.util.Observable, {
281 shadowOffset: Roo.isIE ? 6 : 5,
286 buttonAlign: "right",
291 * Sets the dialog title text
292 * @param {String} text The title text to display
293 * @return {Roo.BasicDialog} this
295 setTitle : function(text){
296 this.header.update(text);
301 closeClick : function(){
306 collapseClick : function(){
307 this[this.collapsed ? "expand" : "collapse"]();
311 * Collapses the dialog to its minimized state (only the title bar is visible).
312 * Equivalent to the user clicking the collapse dialog button.
314 collapse : function(){
316 this.collapsed = true;
317 this.el.addClass("x-dlg-collapsed");
318 this.restoreHeight = this.el.getHeight();
319 this.resizeTo(this.el.getWidth(), this.header.getHeight());
324 * Expands a collapsed dialog back to its normal state. Equivalent to the user
325 * clicking the expand dialog button.
329 this.collapsed = false;
330 this.el.removeClass("x-dlg-collapsed");
331 this.resizeTo(this.el.getWidth(), this.restoreHeight);
336 * Reinitializes the tabs component, clearing out old tabs and finding new ones.
337 * @return {Roo.TabPanel} The tabs component
339 initTabs : function(){
340 var tabs = this.getTabs();
341 while(tabs.getTab(0)){
344 this.el.select(this.tabTag+'.x-dlg-tab').each(function(el){
346 tabs.addTab(Roo.id(dom), dom.title);
354 beforeResize : function(){
355 this.resizer.minHeight = Math.max(this.minHeight, this.getHeaderFooterHeight(true)+40);
359 onResize : function(){
361 this.syncBodyHeight();
364 this.fireEvent("resize", this, this.size.width, this.size.height);
368 onKeyDown : function(e){
369 if(this.isVisible()){
370 this.fireEvent("keydown", this, e);
375 * Resizes the dialog.
376 * @param {Number} width
377 * @param {Number} height
378 * @return {Roo.BasicDialog} this
380 resizeTo : function(width, height){
381 this.el.setSize(width, height);
382 this.size = {width: width, height: height};
383 this.syncBodyHeight();
384 if(this.fixedcenter){
387 if(this.isVisible()){
391 this.fireEvent("resize", this, width, height);
397 * Resizes the dialog to fit the specified content size.
398 * @param {Number} width
399 * @param {Number} height
400 * @return {Roo.BasicDialog} this
402 setContentSize : function(w, h){
403 h += this.getHeaderFooterHeight() + this.body.getMargins("tb");
404 w += this.body.getMargins("lr") + this.bwrap.getMargins("lr") + this.centerBg.getPadding("lr");
405 //if(!this.el.isBorderBox()){
406 h += this.body.getPadding("tb") + this.bwrap.getBorderWidth("tb") + this.body.getBorderWidth("tb") + this.el.getBorderWidth("tb");
407 w += this.body.getPadding("lr") + this.bwrap.getBorderWidth("lr") + this.body.getBorderWidth("lr") + this.bwrap.getPadding("lr") + this.el.getBorderWidth("lr");
410 h += this.tabs.stripWrap.getHeight() + this.tabs.bodyEl.getMargins("tb") + this.tabs.bodyEl.getPadding("tb");
411 w += this.tabs.bodyEl.getMargins("lr") + this.tabs.bodyEl.getPadding("lr");
418 * Adds a key listener for when this dialog is displayed. This allows you to hook in a function that will be
419 * executed in response to a particular key being pressed while the dialog is active.
420 * @param {Number/Array/Object} key Either the numeric key code, array of key codes or an object with the following options:
421 * {key: (number or array), shift: (true/false), ctrl: (true/false), alt: (true/false)}
422 * @param {Function} fn The function to call
423 * @param {Object} scope (optional) The scope of the function
424 * @return {Roo.BasicDialog} this
426 addKeyListener : function(key, fn, scope){
427 var keyCode, shift, ctrl, alt;
428 if(typeof key == "object" && !(key instanceof Array)){
429 keyCode = key["key"];
430 shift = key["shift"];
436 var handler = function(dlg, e){
437 if((!shift || e.shiftKey) && (!ctrl || e.ctrlKey) && (!alt || e.altKey)){
439 if(keyCode instanceof Array){
440 for(var i = 0, len = keyCode.length; i < len; i++){
442 fn.call(scope || window, dlg, k, e);
448 fn.call(scope || window, dlg, k, e);
453 this.on("keydown", handler);
458 * Returns the TabPanel component (creates it if it doesn't exist).
459 * Note: If you wish to simply check for the existence of tabs without creating them,
460 * check for a null 'tabs' property.
461 * @return {Roo.TabPanel} The tabs component
463 getTabs : function(){
465 this.el.addClass("x-dlg-auto-tabs");
466 this.body.addClass(this.tabPosition == "bottom" ? "x-tabs-bottom" : "x-tabs-top");
467 this.tabs = new Roo.TabPanel(this.body.dom, this.tabPosition == "bottom");
473 * Adds a button to the footer section of the dialog.
474 * @param {String/Object} config A string becomes the button text, an object can either be a Button config
475 * object or a valid Roo.DomHelper element config
476 * @param {Function} handler The function called when the button is clicked
477 * @param {Object} scope (optional) The scope of the handler function (accepts position as a property)
478 * @return {Roo.Button} The new button
480 addButton : function(config, handler, scope){
481 var dh = Roo.DomHelper;
483 this.footer = dh.append(this.bwrap, {tag: "div", cls:"x-dlg-ft"}, true);
485 if(!this.btnContainer){
486 var tb = this.footer.createChild({
488 cls:"x-dlg-btns x-dlg-btns-"+this.buttonAlign,
489 html:'<table cellspacing="0"><tbody><tr></tr></tbody></table><div class="x-clear"></div>'
491 this.btnContainer = tb.firstChild.firstChild.firstChild;
496 minWidth: this.minButtonWidth,
499 if(typeof config == "string"){
500 bconfig.text = config;
503 bconfig.dhconfig = config;
505 Roo.apply(bconfig, config);
509 if ((typeof(bconfig.position) != 'undefined') && bconfig.position < this.btnContainer.childNodes.length-1) {
510 bconfig.position = Math.max(0, bconfig.position);
511 fc = this.btnContainer.childNodes[bconfig.position];
514 var btn = new Roo.Button(
516 this.btnContainer.insertBefore(document.createElement("td"),fc)
517 : this.btnContainer.appendChild(document.createElement("td")),
518 //Roo.get(this.btnContainer).createChild( { tag: 'td'}, fc ),
521 this.syncBodyHeight();
524 * Array of all the buttons that have been added to this dialog via addButton
529 this.buttons.push(btn);
534 * Sets the default button to be focused when the dialog is displayed.
535 * @param {Roo.BasicDialog.Button} btn The button object returned by {@link #addButton}
536 * @return {Roo.BasicDialog} this
538 setDefaultButton : function(btn){
539 this.defaultButton = btn;
544 getHeaderFooterHeight : function(safe){
547 height += this.header.getHeight();
550 var fm = this.footer.getMargins();
551 height += (this.footer.getHeight()+fm.top+fm.bottom);
553 height += this.bwrap.getPadding("tb")+this.bwrap.getBorderWidth("tb");
554 height += this.centerBg.getPadding("tb");
559 syncBodyHeight : function()
561 var bd = this.body, // the text
562 cb = this.centerBg, // wrapper around bottom.. but does not seem to be used..
564 var height = this.size.height - this.getHeaderFooterHeight(false);
565 bd.setHeight(height-bd.getMargins("tb"));
566 var hh = this.header.getHeight();
567 var h = this.size.height-hh;
570 bw.setLeftTop(cb.getPadding("l"), hh+cb.getPadding("t"));
571 bw.setHeight(h-cb.getPadding("tb"));
573 bw.setWidth(this.el.getWidth(true)-cb.getPadding("lr"));
574 bd.setWidth(bw.getWidth(true));
576 this.tabs.syncHeight();
578 this.tabs.el.repaint();
584 * Restores the previous state of the dialog if Roo.state is configured.
585 * @return {Roo.BasicDialog} this
587 restoreState : function(){
588 var box = Roo.state.Manager.get(this.stateId || (this.el.id + "-state"));
589 if(box && box.width){
590 this.xy = [box.x, box.y];
591 this.resizeTo(box.width, box.height);
597 beforeShow : function(){
599 if(this.fixedcenter){
600 this.xy = this.el.getCenterXY(true);
603 Roo.get(document.body).addClass("x-body-masked");
604 this.mask.setSize(Roo.lib.Dom.getViewWidth(true), Roo.lib.Dom.getViewHeight(true));
611 animShow : function(){
612 var b = Roo.get(this.animateTarget).getBox();
613 this.proxy.setSize(b.width, b.height);
614 this.proxy.setLocation(b.x, b.y);
616 this.proxy.setBounds(this.xy[0], this.xy[1], this.size.width, this.size.height,
617 true, .35, this.showEl.createDelegate(this));
622 * @param {String/HTMLElement/Roo.Element} animateTarget (optional) Reset the animation target
623 * @return {Roo.BasicDialog} this
625 show : function(animateTarget){
626 if (this.fireEvent("beforeshow", this) === false){
629 if(this.syncHeightBeforeShow){
630 this.syncBodyHeight();
631 }else if(this.firstShow){
632 this.firstShow = false;
633 this.syncBodyHeight(); // sync the height on the first show instead of in the constructor
635 this.animateTarget = animateTarget || this.animateTarget;
636 if(!this.el.isVisible()){
638 if(this.animateTarget && Roo.get(this.animateTarget)){
650 this.el.setXY(this.xy);
652 this.adjustAssets(true);
655 // IE peekaboo bug - fix found by Dave Fenwick
659 this.fireEvent("show", this);
663 * Focuses the dialog. If a defaultButton is set, it will receive focus, otherwise the
664 * dialog itself will receive focus.
667 if(this.defaultButton){
668 this.defaultButton.focus();
670 this.focusEl.focus();
675 constrainXY : function(){
676 if(this.constraintoviewport !== false){
679 var s = this.container.getSize();
680 this.viewSize = [s.width, s.height];
682 this.viewSize = [Roo.lib.Dom.getViewWidth(),Roo.lib.Dom.getViewHeight()];
685 var s = Roo.get(this.container||document).getScroll();
687 var x = this.xy[0], y = this.xy[1];
688 var w = this.size.width, h = this.size.height;
689 var vw = this.viewSize[0], vh = this.viewSize[1];
690 // only move it if it needs it
692 // first validate right/bottom
693 if(x + w > vw+s.left){
697 if(y + h > vh+s.top){
701 // then make sure top/left isn't negative
713 if(this.isVisible()){
714 this.el.setLocation(x, y);
724 this.xy = this.el.getXY();
730 adjustAssets : function(doShow){
731 var x = this.xy[0], y = this.xy[1];
732 var w = this.size.width, h = this.size.height;
735 this.shadow.show(this.el);
741 if(this.shadow && this.shadow.isVisible()){
742 this.shadow.show(this.el);
744 if(this.shim && this.shim.isVisible()){
745 this.shim.setBounds(x, y, w, h);
750 adjustViewport : function(w, h){
752 w = Roo.lib.Dom.getViewWidth();
753 h = Roo.lib.Dom.getViewHeight();
756 this.viewSize = [w, h];
757 if(this.modal && this.mask.isVisible()){
758 this.mask.setSize(w, h); // first make sure the mask isn't causing overflow
759 this.mask.setSize(Roo.lib.Dom.getViewWidth(true), Roo.lib.Dom.getViewHeight(true));
761 if(this.isVisible()){
767 * Destroys this dialog and all its supporting elements (including any tabs, shim,
768 * shadow, proxy, mask, etc.) Also removes all event listeners.
769 * @param {Boolean} removeEl (optional) true to remove the element from the DOM
771 destroy : function(removeEl){
772 if(this.isVisible()){
773 this.animateTarget = null;
776 Roo.EventManager.removeResizeListener(this.adjustViewport, this);
778 this.tabs.destroy(removeEl);
791 for(var i = 0, len = this.buttons.length; i < len; i++){
792 this.buttons[i].destroy();
795 this.el.removeAllListeners();
796 if(removeEl === true){
800 Roo.DialogManager.unregister(this);
804 startMove : function(){
808 if(this.constraintoviewport !== false){
809 this.dd.constrainTo(document.body, {right: this.shadowOffset, bottom: this.shadowOffset});
814 endMove : function(){
816 Roo.dd.DD.prototype.endDrag.apply(this.dd, arguments);
818 Roo.dd.DDProxy.prototype.endDrag.apply(this.dd, arguments);
824 this.fireEvent("move", this, this.xy[0], this.xy[1]);
828 * Brings this dialog to the front of any other visible dialogs
829 * @return {Roo.BasicDialog} this
831 toFront : function(){
832 Roo.DialogManager.bringToFront(this);
837 * Sends this dialog to the back (under) of any other visible dialogs
838 * @return {Roo.BasicDialog} this
841 Roo.DialogManager.sendToBack(this);
846 * Centers this dialog in the viewport
847 * @return {Roo.BasicDialog} this
850 var xy = this.el.getCenterXY(true);
851 this.moveTo(xy[0], xy[1]);
856 * Moves the dialog's top-left corner to the specified point
859 * @return {Roo.BasicDialog} this
861 moveTo : function(x, y){
863 if(this.isVisible()){
864 this.el.setXY(this.xy);
871 * Aligns the dialog to the specified element
872 * @param {String/HTMLElement/Roo.Element} element The element to align to.
873 * @param {String} position The position to align to (see {@link Roo.Element#alignTo} for more details).
874 * @param {Array} offsets (optional) Offset the positioning by [x, y]
875 * @return {Roo.BasicDialog} this
877 alignTo : function(element, position, offsets){
878 this.xy = this.el.getAlignToXY(element, position, offsets);
879 if(this.isVisible()){
880 this.el.setXY(this.xy);
887 * Anchors an element to another element and realigns it when the window is resized.
888 * @param {String/HTMLElement/Roo.Element} element The element to align to.
889 * @param {String} position The position to align to (see {@link Roo.Element#alignTo} for more details)
890 * @param {Array} offsets (optional) Offset the positioning by [x, y]
891 * @param {Boolean/Number} monitorScroll (optional) true to monitor body scroll and reposition. If this parameter
892 * is a number, it is used as the buffer delay (defaults to 50ms).
893 * @return {Roo.BasicDialog} this
895 anchorTo : function(el, alignment, offsets, monitorScroll){
896 var action = function(){
897 this.alignTo(el, alignment, offsets);
899 Roo.EventManager.onWindowResize(action, this);
900 var tm = typeof monitorScroll;
901 if(tm != 'undefined'){
902 Roo.EventManager.on(window, 'scroll', action, this,
903 {buffer: tm == 'number' ? monitorScroll : 50});
910 * Returns true if the dialog is visible
913 isVisible : function(){
914 return this.el.isVisible();
918 animHide : function(callback){
919 var b = Roo.get(this.animateTarget).getBox();
921 this.proxy.setBounds(this.xy[0], this.xy[1], this.size.width, this.size.height);
923 this.proxy.setBounds(b.x, b.y, b.width, b.height, true, .35,
924 this.hideEl.createDelegate(this, [callback]));
929 * @param {Function} callback (optional) Function to call when the dialog is hidden
930 * @return {Roo.BasicDialog} this
932 hide : function(callback){
933 if (this.fireEvent("beforehide", this) === false){
942 // sometimes animateTarget seems to get set.. causing problems...
943 // this just double checks..
944 if(this.animateTarget && Roo.get(this.animateTarget)) {
945 this.animHide(callback);
948 this.hideEl(callback);
954 hideEl : function(callback){
958 Roo.get(document.body).removeClass("x-body-masked");
960 this.fireEvent("hide", this);
961 if(typeof callback == "function"){
967 hideAction : function(){
968 this.setLeft("-10000px");
969 this.setTop("-10000px");
970 this.setStyle("visibility", "hidden");
974 refreshSize : function(){
975 this.size = this.el.getSize();
976 this.xy = this.el.getXY();
977 Roo.state.Manager.set(this.stateId || this.el.id + "-state", this.el.getBox());
981 // z-index is managed by the DialogManager and may be overwritten at any time
982 setZIndex : function(index){
984 this.mask.setStyle("z-index", index);
987 this.shim.setStyle("z-index", ++index);
990 this.shadow.setZIndex(++index);
992 this.el.setStyle("z-index", ++index);
994 this.proxy.setStyle("z-index", ++index);
997 this.resizer.proxy.setStyle("z-index", ++index);
1000 this.lastZIndex = index;
1004 * Returns the element for this dialog
1005 * @return {Roo.Element} The underlying dialog Element
1013 * @class Roo.DialogManager
1014 * Provides global access to BasicDialogs that have been created and
1015 * support for z-indexing (layering) multiple open dialogs.
1017 Roo.DialogManager = function(){
1019 var accessList = [];
1023 var sortDialogs = function(d1, d2){
1024 return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
1028 var orderDialogs = function(){
1029 accessList.sort(sortDialogs);
1030 var seed = Roo.DialogManager.zseed;
1031 for(var i = 0, len = accessList.length; i < len; i++){
1032 var dlg = accessList[i];
1034 dlg.setZIndex(seed + (i*10));
1041 * The starting z-index for BasicDialogs (defaults to 9000)
1042 * @type Number The z-index value
1047 register : function(dlg){
1049 accessList.push(dlg);
1053 unregister : function(dlg){
1054 delete list[dlg.id];
1057 if(!accessList.indexOf){
1058 for( i = 0, len = accessList.length; i < len; i++){
1059 if(accessList[i] == dlg){
1060 accessList.splice(i, 1);
1065 i = accessList.indexOf(dlg);
1067 accessList.splice(i, 1);
1073 * Gets a registered dialog by id
1074 * @param {String/Object} id The id of the dialog or a dialog
1075 * @return {Roo.BasicDialog} this
1078 return typeof id == "object" ? id : list[id];
1082 * Brings the specified dialog to the front
1083 * @param {String/Object} dlg The id of the dialog or a dialog
1084 * @return {Roo.BasicDialog} this
1086 bringToFront : function(dlg){
1087 dlg = this.get(dlg);
1090 dlg._lastAccess = new Date().getTime();
1097 * Sends the specified dialog to the back
1098 * @param {String/Object} dlg The id of the dialog or a dialog
1099 * @return {Roo.BasicDialog} this
1101 sendToBack : function(dlg){
1102 dlg = this.get(dlg);
1103 dlg._lastAccess = -(new Date().getTime());
1111 hideAll : function(){
1112 for(var id in list){
1113 if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
1122 * @class Roo.LayoutDialog
1123 * @extends Roo.BasicDialog
1124 * Dialog which provides adjustments for working with a layout in a Dialog.
1125 * Add your necessary layout config options to the dialog's config.<br>
1126 * Example usage (including a nested layout):
1129 dialog = new Roo.LayoutDialog("download-dlg", {
1138 // layout config merges with the dialog config
1141 alwaysShowTabs: true
1144 dialog.addKeyListener(27, dialog.hide, dialog);
1145 dialog.setDefaultButton(dialog.addButton("Close", dialog.hide, dialog));
1146 dialog.addButton("Build It!", this.getDownload, this);
1148 // we can even add nested layouts
1149 var innerLayout = new Roo.BorderLayout("dl-inner", {
1159 innerLayout.beginUpdate();
1160 innerLayout.add("east", new Roo.ContentPanel("dl-details"));
1161 innerLayout.add("center", new Roo.ContentPanel("selection-panel"));
1162 innerLayout.endUpdate(true);
1164 var layout = dialog.getLayout();
1165 layout.beginUpdate();
1166 layout.add("center", new Roo.ContentPanel("standard-panel",
1167 {title: "Download the Source", fitToFrame:true}));
1168 layout.add("center", new Roo.NestedLayoutPanel(innerLayout,
1169 {title: "Build your own roo.js"}));
1170 layout.getRegion("center").showPanel(sp);
1175 * @param {String/HTMLElement/Roo.Element} el The id of or container element, or config
1176 * @param {Object} config configuration options
1178 Roo.LayoutDialog = function(el, cfg){
1181 if (typeof(cfg) == 'undefined') {
1182 config = Roo.apply({}, el);
1183 // not sure why we use documentElement here.. - it should always be body.
1184 // IE7 borks horribly if we use documentElement.
1185 // webkit also does not like documentElement - it creates a body element...
1186 el = Roo.get( document.body || document.documentElement ).createChild();
1187 //config.autoCreate = true;
1191 config.autoTabs = false;
1192 Roo.LayoutDialog.superclass.constructor.call(this, el, config);
1193 this.body.setStyle({overflow:"hidden", position:"relative"});
1194 this.layout = new Roo.BorderLayout(this.body.dom, config);
1195 this.layout.monitorWindowResize = false;
1196 this.el.addClass("x-dlg-auto-layout");
1197 // fix case when center region overwrites center function
1198 this.center = Roo.BasicDialog.prototype.center;
1199 this.on("show", this.layout.layout, this.layout, true);
1201 var xitems = config.items;
1202 delete config.items;
1203 Roo.each(xitems, this.addxtype, this);
1208 Roo.extend(Roo.LayoutDialog, Roo.BasicDialog, {
1210 * Ends update of the layout <strike>and resets display to none</strike>. Use standard beginUpdate/endUpdate on the layout.
1213 endUpdate : function(){
1214 this.layout.endUpdate();
1218 * Begins an update of the layout <strike>and sets display to block and visibility to hidden</strike>. Use standard beginUpdate/endUpdate on the layout.
1221 beginUpdate : function(){
1222 this.layout.beginUpdate();
1226 * Get the BorderLayout for this dialog
1227 * @return {Roo.BorderLayout}
1229 getLayout : function(){
1233 showEl : function(){
1234 Roo.LayoutDialog.superclass.showEl.apply(this, arguments);
1236 this.layout.layout();
1241 // Use the syncHeightBeforeShow config option to control this automatically
1242 syncBodyHeight : function(){
1243 Roo.LayoutDialog.superclass.syncBodyHeight.call(this);
1244 if(this.layout){this.layout.layout();}
1248 * Add an xtype element (actually adds to the layout.)
1249 * @return {Object} xdata xtype object data.
1252 addxtype : function(c) {
1253 return this.layout.addxtype(c);