//>>built // wrapped by build app define("dojox/widget/Portlet", ["dijit","dojo","dojox","dojo/require!dijit/TitlePane,dojo/fx"], function(dijit,dojo,dojox){ dojo.experimental("dojox.widget.Portlet"); dojo.provide("dojox.widget.Portlet"); dojo.require("dijit.TitlePane"); dojo.require("dojo.fx"); dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{ // summary: A container widget that is designed to be contained // in a dojox.layout.GridContainer. Child widgets can insert // an icon into the title bar of the Portlet, which when // clicked, executes the "toggle" method of the child widget. // A child widget must specify the attribute // "portletIconClass", and the optional class // "portletIconHoverClass", as well as the // "toggle" function. // resizeChildren: Boolean // If true, when the Portlet is resized, any child widgets // with a 'resize' method have that method called. resizeChildren: true, // closable: Boolean // If true, a close button is placed in the title bar, // and the Portlet can be hidden. If false, the Portlet // cannot be closed. closable: true, // _parents: Array // An array of all the StackContainer widgets that this Portlet // is contained in. These are used to determine if the portlet // is visible or not. _parents: null, // _size: Object // Cache of the previous size of the portlet, used to determine // if the size has changed and if the child widgets should be // resized. _size: null, // dragRestriction: Boolean // To remove the drag capability. dragRestriction : false, buildRendering: function(){ this.inherited(arguments); // Hide the portlet until it is fully constructed. dojo.style(this.domNode, "visibility", "hidden"); }, postCreate: function(){ this.inherited(arguments); // Add the portlet classes dojo.addClass(this.domNode, "dojoxPortlet"); dojo.removeClass(this.arrowNode, "dijitArrowNode"); dojo.addClass(this.arrowNode, "dojoxPortletIcon dojoxArrowDown"); dojo.addClass(this.titleBarNode, "dojoxPortletTitle"); dojo.addClass(this.hideNode, "dojoxPortletContentOuter"); // Choose the class to add depending on if the portlet is draggable or not. dojo.addClass(this.domNode, "dojoxPortlet-" + (!this.dragRestriction ? "movable" : "nonmovable")); var _this = this; if(this.resizeChildren){ // If children should be resized when the portlet size changes, // listen for items being dropped, when the window is resized, // or when another portlet's size changes. this.subscribe("/dnd/drop", function(){_this._updateSize();}); this.subscribe("/Portlet/sizechange", function(widget){_this.onSizeChange(widget);}); this.connect(window, "onresize", function(){_this._updateSize();}); // Subscribe to all possible child-selection events that could affect this // portlet var doSelectSubscribe = dojo.hitch(this, function(id, lastId){ var widget = dijit.byId(id); if(widget.selectChild){ var s = this.subscribe(id + "-selectChild", function(child){ var n = _this.domNode.parentNode; while(n){ if(n == child.domNode){ // Only fire this once, as the widget is now visible // at least once, so child measurements should be accurate. _this.unsubscribe(s); _this._updateSize(); break; } n = n.parentNode; } }); // Record the StackContainer and child widget that this portlet // is in, so it can figure out whether or not it is visible. // If it is not visible, it will not update it's size dynamically. var child = dijit.byId(lastId); if(widget && child){ _this._parents.push({parent: widget, child: child}); } } }); var lastId; this._parents = []; // Find all parent widgets, and if they are StackContainers, // subscribe to their selectChild method calls. for(var p = this.domNode.parentNode; p != null; p = p.parentNode){ var id = p.getAttribute ? p.getAttribute("widgetId") : null; if(id){ doSelectSubscribe(id, lastId); lastId = id; } } } // Prevent clicks on icons from causing a drag to start. this.connect(this.titleBarNode, "onmousedown", function(evt){ if (dojo.hasClass(evt.target, "dojoxPortletIcon")) { dojo.stopEvent(evt); return false; } return true; }); // Inform all portlets that the size of this one has changed, // and therefore perhaps they have too this.connect(this._wipeOut, "onEnd", function(){_this._publish();}); this.connect(this._wipeIn, "onEnd", function(){_this._publish();}); if(this.closable){ this.closeIcon = this._createIcon("dojoxCloseNode", "dojoxCloseNodeHover", dojo.hitch(this, "onClose")); dojo.style(this.closeIcon, "display", ""); } }, startup: function(){ if(this._started){return;} var children = this.getChildren(); this._placeSettingsWidgets(); // Start up the children dojo.forEach(children, function(child){ try{ if(!child.started && !child._started){ child.startup() } } catch(e){ console.log(this.id + ":" + this.declaredClass, e); } }); this.inherited(arguments); //this._updateSize(); dojo.style(this.domNode, "visibility", "visible"); }, _placeSettingsWidgets: function(){ // summary: Checks all the children to see if they are instances // of dojox.widget.PortletSettings. If they are, // create an icon for them in the title bar which when clicked, // calls their toggle() method. dojo.forEach(this.getChildren(), dojo.hitch(this, function(child){ if(child.portletIconClass && child.toggle && !child.attr("portlet")){ this._createIcon(child.portletIconClass, child.portletIconHoverClass, dojo.hitch(child, "toggle")); dojo.place(child.domNode, this.containerNode, "before"); child.attr("portlet", this); this._settingsWidget = child; } })); }, _createIcon: function(clazz, hoverClazz, fn){ // summary: // creates an icon in the title bar. var icon = dojo.create("div",{ "class": "dojoxPortletIcon " + clazz, "waiRole": "presentation" }); dojo.place(icon, this.arrowNode, "before"); this.connect(icon, "onclick", fn); if(hoverClazz){ this.connect(icon, "onmouseover", function(){ dojo.addClass(icon, hoverClazz); }); this.connect(icon, "onmouseout", function(){ dojo.removeClass(icon, hoverClazz); }); } return icon; }, onClose: function(evt){ // summary: // Hides the portlet. Note that it does not // persist this, so it is up to the client to // listen to this method and persist the closed state // in their own way. dojo.style(this.domNode, "display", "none"); }, onSizeChange: function(widget){ // summary: // Updates the Portlet size if any other Portlet // changes its size. if(widget == this){ return; } this._updateSize(); }, _updateSize: function(){ // summary: // Updates the size of all child widgets. if(!this.open || !this._started || !this.resizeChildren){ return; } if(this._timer){ clearTimeout(this._timer); } // Delay applying the size change in case the size // changes very frequently, for performance reasons. this._timer = setTimeout(dojo.hitch(this, function(){ var size ={ w: dojo.style(this.domNode, "width"), h: dojo.style(this.domNode, "height") }; // If the Portlet is in a StackWidget, and it is not // visible, do not update the size, as it could // make child widgets miscalculate. for(var i = 0; i < this._parents.length; i++){ var p = this._parents[i]; var sel = p.parent.selectedChildWidget if(sel && sel != p.child){ return; } } if(this._size){ // If the size of the portlet hasn't changed, don't // resize the children, as this can be expensive if(this._size.w == size.w && this._size.h == size.h){ return; } } this._size = size; var fns = ["resize", "layout"]; this._timer = null; var kids = this.getChildren(); dojo.forEach(kids, function(child){ for(var i = 0; i < fns.length; i++){ if(dojo.isFunction(child[fns[i]])){ try{ child[fns[i]](); } catch(e){ console.log(e); } break; } } }); this.onUpdateSize(); }), 100); }, onUpdateSize: function(){ // summary: // Stub function called when the size is changed. }, _publish: function(){ // summary: Publishes an event that all other portlets listen to. // This causes them to update their child widgets if their // size has changed. dojo.publish("/Portlet/sizechange",[this]); }, _onTitleClick: function(evt){ if(evt.target == this.arrowNode){ this.inherited(arguments); } }, addChild: function(child){ // summary: // Adds a child widget to the portlet. this._size = null; this.inherited(arguments); if(this._started){ this._placeSettingsWidgets(); this._updateSize(); } if(this._started && !child.started && !child._started){ child.startup(); } }, destroyDescendants: function(/*Boolean*/ preserveDom){ this.inherited(arguments); if(this._settingsWidget){ this._settingsWidget.destroyRecursive(preserveDom); } }, destroy: function(){ if(this._timer){ clearTimeout(this._timer); } this.inherited(arguments); }, _setCss: function(){ this.inherited(arguments); dojo.style(this.arrowNode, "display", this.toggleable ? "":"none"); } }); dojo.declare("dojox.widget.PortletSettings", [dijit._Container, dijit.layout.ContentPane],{ // summary: // A settings widget to be used with a dojox.widget.Portlet. // description: // This widget should be placed inside a dojox.widget.Portlet widget. // It is used to set some preferences for that Portlet. It is essentially // a ContentPane, and should contain other widgets and DOM nodes that // do the real work of setting preferences for the portlet. // portletIconClass: String // The CSS class to apply to the icon in the Portlet title bar that is used // to toggle the visibility of this widget. portletIconClass: "dojoxPortletSettingsIcon", // portletIconHoverClass: String // The CSS class to apply to the icon in the Portlet title bar that is used // to toggle the visibility of this widget when the mouse hovers over it. portletIconHoverClass: "dojoxPortletSettingsIconHover", postCreate: function(){ // summary: // Sets the require CSS classes on the widget. // Start the PortletSettings widget hidden, always. dojo.style(this.domNode, "display", "none"); dojo.addClass(this.domNode, "dojoxPortletSettingsContainer"); // Remove the unwanted content pane class. dojo.removeClass(this.domNode, "dijitContentPane"); }, _setPortletAttr: function(portlet){ // summary: // Sets the portlet that encloses this widget. this.portlet = portlet; }, toggle: function(){ // summary: // Toggles the visibility of this widget. var n = this.domNode; if(dojo.style(n, "display") == "none"){ dojo.style(n,{ "display": "block", "height": "1px", "width": "auto" }); dojo.fx.wipeIn({ node: n }).play(); }else{ dojo.fx.wipeOut({ node: n, onEnd: dojo.hitch(this, function(){ dojo.style(n,{"display": "none", "height": "", "width":""}); } )}).play(); } } }); dojo.declare("dojox.widget.PortletDialogSettings", dojox.widget.PortletSettings,{ // summary: // A settings widget to be used with a dojox.widget.Portlet, which displays // the contents of this widget in a dijit.Dialog box. // dimensions: Array // The size of the dialog to display. This defaults to [300, 300] dimensions: null, constructor: function(props, node){ this.dimensions = props.dimensions || [300, 100]; }, toggle: function(){ // summary: // Shows and hides the Dialog box. if(!this.dialog){ dojo["require"]("dijit.Dialog"); this.dialog = new dijit.Dialog({title: this.title}); dojo.body().appendChild(this.dialog.domNode); // Move this widget inside the dialog this.dialog.containerNode.appendChild(this.domNode); dojo.style(this.dialog.domNode,{ "width" : this.dimensions[0] + "px", "height" : this.dimensions[1] + "px" }); dojo.style(this.domNode, "display", ""); } if(this.dialog.open){ this.dialog.hide(); }else{ this.dialog.show(this.domNode); } } }); });