dojo.provide('dojox.widget.Dialog'); dojo.experimental('dojox.widget.Dialog'); dojo.require('dijit.Dialog'); dojo.require('dojox.fx'); dojo.declare('dojox.widget.Dialog', dijit.Dialog, { // summary: A Lightbox-like Modal-dialog for HTML Content // // description: // An HTML-capable Dialog widget with advanced sizing // options, animated show/hide and other useful options. // // This Dialog is also very easy to apply custom styles to. // // It works identically to a `dijit.Dialog` with several // additional parameters. templatePath: dojo.moduleUrl('dojox.widget','Dialog/Dialog.html'), // sizeToViewport: Boolean // If true, fix the size of the dialog to the Viewport based on // viewportPadding value rather than the calculated or natural // stlye. If false, base the size on a passed dimension attribute. // Eitherway, the viewportPadding value is used if the the content // extends beyond the viewport size for whatever reason. sizeToViewport: false, // viewportPadding: Integer // If sizeToViewport="true", this is the amount of padding in pixels to leave // between the dialog border and the viewport edge. // This value is also used when sizeToViewport="false" and dimensions exceeded // by dialog content to ensure dialog does not go outside viewport boundary // viewportPadding: 35, // dimensions: Array // A two-element array of [widht,height] to animate the Dialog to if sizeToViewport="false" // Defaults to [300,300] dimensions: null, // easing: Function?|String? // An easing function to apply to the sizing animation. easing: null, // sizeDuration: Integer // Time (in ms) to use in the Animation for sizing. sizeDuration: dijit._defaultDuration, // sizeMethod: String // To be passed to dojox.fx.sizeTo, one of "chain" or "combine" to effect // the animation sequence. sizeMethod: "chain", // showTitle: Boolean // Toogle to show or hide the Title area. Can only be set at startup. showTitle: false, // draggable: Boolean // Make the pane draggable. Differs from dijit.Dialog by setting default to false draggable: false, // simply over-ride the default from dijit.Dialog // modal: Boolean // If true, this Dialog instance will be truly modal and prevent closing until // explicitly told to by calling hide() - Defaults to false to preserve previous // behaviors. modal: false, constructor: function(props, node){ this.easing = props.easing || dojo._defaultEasing; this.dimensions = props.dimensions || [300, 300]; }, _setup: function(){ // summary: Piggyback on dijit.Dialog's _setup for load-time options, deferred to // this.inherited(arguments); if(!this._alreadyInitialized){ this._navIn = dojo.fadeIn({ node: this.closeButtonNode }); this._navOut = dojo.fadeOut({ node: this.closeButtonNode }); if(!this.showTitle){ dojo.addClass(this.domNode,"dojoxDialogNoTitle"); } } }, layout: function(e){ this._setSize(); this.inherited(arguments); }, _setSize: function(){ // summary: cache and set our desired end position this._vp = dijit.getViewport(); var tc = this.containerNode, vpSized = this.sizeToViewport ; return this._displaysize = { w: vpSized ? tc.scrollWidth : this.dimensions[0], h: vpSized ? tc.scrollHeight : this.dimensions[1] }; // Object }, show: function(){ this._setSize(); dojo.style(this.closeButtonNode,"opacity", 0); dojo.style(this.domNode, { overflow: "hidden", opacity: 0, width: "1px", height: "1px" }); dojo.style(this.containerNode, { opacity: 0, overflow: "hidden" }); this.inherited(arguments); if(this.modal){ // prevent escape key from closing dialog // connect to body to trap this event from the Dialog a11y code, and stop escape key // from doing anything in the modal:true case: this._modalconnects.push(dojo.connect(dojo.body(), "onkeypress", function(e){ if(e.charOrCode == dojo.keys.ESCAPE){ dojo.stopEvent(e); } })); }else{ // otherwise, allow clicking on the underlay to close this._modalconnects.push(dojo.connect(dijit._underlay.domNode, "onclick", this, "onCancel")); } this._modalconnects.push(dojo.connect(this.domNode,"onmouseenter",this,"_handleNav")); this._modalconnects.push(dojo.connect(this.domNode,"onmouseleave",this,"_handleNav")); }, _handleNav: function(e){ // summary: Handle's showing or hiding the close icon var navou = "_navOut", navin = "_navIn", animou = (e.type == "mouseout" ? navin : navou), animin = (e.type == "mouseout" ? navou : navin) ; this[animou].stop(); this[animin].play(); }, // an experiment in a quicksilver-like hide. too choppy for me. /* hide: function(){ // summary: Hide the dialog // if we haven't been initialized yet then we aren't showing and we can just return if(!this._alreadyInitialized){ return; } this._fadeIn && this._fadeIn.stop(); if (this._scrollConnected){ this._scrollConnected = false; } dojo.forEach(this._modalconnects, dojo.disconnect); this._modalconnects = []; if(this.refocus){ this.connect(this._fadeOut,"onEnd",dojo.hitch(dijit,"focus",this._savedFocus)); } if(this._relativePosition){ delete this._relativePosition; } dojox.fx.sizeTo({ node: this.domNode, duration:this.sizeDuration || this.duration, width: this._vp.w - 1, height: 5, onBegin: dojo.hitch(this,function(){ this._fadeOut.play(this.sizeDuration / 2); }) }).play(); this.open = false; }, */ _position: function(){ if(!this._started){ return; } // prevent content: from firing this anim #8914 if(this._sizing){ this._sizing.stop(); this.disconnect(this._sizingConnect); delete this._sizing; } this.inherited(arguments); if(!this.open){ dojo.style(this.containerNode, "opacity", 0); } var pad = this.viewportPadding * 2; var props = { node: this.domNode, duration: this.sizeDuration || dijit._defaultDuration, easing: this.easing, method: this.sizeMethod }; var ds = this._displaysize || this._setSize(); props['width'] = ds.w = (ds.w + pad >= this._vp.w || this.sizeToViewport) ? this._vp.w - pad : ds.w; props['height'] = ds.h = (ds.h + pad >= this._vp.h || this.sizeToViewport) ? this._vp.h - pad : ds.h; this._sizing = dojox.fx.sizeTo(props); this._sizingConnect = this.connect(this._sizing,"onEnd","_showContent"); this._sizing.play(); }, _showContent: function(e){ // summary: Show the inner container after sizing animation var container = this.containerNode; dojo.style(this.domNode,"overflow","visible"); dojo.style(container, { height: this._displaysize.h + "px", width: this._displaysize.w + "px", overflow:"auto" }); dojo.anim(container, { opacity:1 }); } });