436 lines
12 KiB
JavaScript
436 lines
12 KiB
JavaScript
//>>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);
|
|
}
|
|
}
|
|
});
|
|
|
|
});
|