dojox/widget/Portlet.js

  • Provides:

    • dojox.widget.Portlet
  • Requires:

    • dijit.TitlePane in common in project dijit
    • dojo.fx in common in project dojo
  • dojox.widget.Portlet

    • type
      Function
    • chains:
      • dijit.TitlePane: (prototype)
      • dijit.TitlePane: (call)
      • dijit._Container: (call)
    • mixins:
      • dijit._Container.prototype: (prototype)
    • 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.
  • dojox.widget.Portlet.resizeChildren

    • type
      Boolean
    • summary
      If true, when the Portlet is resized, any child widgets
      with a 'resize' method have that method called.
  • dojox.widget.Portlet.closable

    • type
      Boolean
    • summary
      If true, a close button is placed in the title bar,
      and the Portlet can be hidden. If false, the Portlet
      cannot be closed.
  • dojox.widget.Portlet._parents

    • type
      Array
    • summary
      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.
  • dojox.widget.Portlet._size

    • type
      Object
    • summary
      Cache of the previous size of the portlet, used to determine
      if the size has changed and if the child widgets should be
      resized.
  • dojox.widget.Portlet.dragRestriction

    • type
      Boolean
    • summary
      To remove the drag capability.
  • dojox.widget.Portlet.buildRendering

    • type
      Function
    • source: [view]
        this.inherited(arguments);


        // Hide the portlet until it is fully constructed.
        dojo.style(this.domNode, "visibility", "hidden");
    • summary
  • dojox.widget.Portlet.postCreate

    • type
      Function
    • source: [view]
        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", "");
        }
    • summary
  • dojox.widget.Portlet.startup

    • type
      Function
    • source: [view]
        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");
    • summary
  • dojox.widget.Portlet._placeSettingsWidgets

    • type
      Function
    • source: [view]
        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;
         }
        }));
    • 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.
  • dojox.widget.Portlet._createIcon

    • type
      Function
    • parameters:
      • clazz: (typeof )
      • hoverClazz: (typeof )
      • fn: (typeof )
    • source: [view]
        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;
    • summary
      creates an icon in the title bar.
  • dojox.widget.Portlet.onClose

    • type
      Function
    • parameters:
      • evt: (typeof )
    • source: [view]
        dojo.style(this.domNode, "display", "none");
    • 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.
  • dojox.widget.Portlet.onSizeChange

    • type
      Function
    • parameters:
      • widget: (typeof )
    • source: [view]
        if(widget == this){
         return;
        }
        this._updateSize();
    • summary
      Updates the Portlet size if any other Portlet
      changes its size.
  • dojox.widget.Portlet._updateSize

    • type
      Function
    • source: [view]
        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);
    • summary
      Updates the size of all child widgets.
  • dojox.widget.Portlet.onUpdateSize

    • type
      Function
    • source: [view]
        // summary:
        //  Stub function called when the size is changed.
    • summary
      Stub function called when the size is changed.
  • dojox.widget.Portlet._publish

    • type
      Function
    • source: [view]
        dojo.publish("/Portlet/sizechange",[this]);
    • summary
      Publishes an event that all other portlets listen to.
      This causes them to update their child widgets if their
      size has changed.
  • dojox.widget.Portlet._onTitleClick

    • type
      Function
    • parameters:
      • evt: (typeof )
    • source: [view]
        if(evt.target == this.arrowNode){
         this.inherited(arguments);
        }
    • summary
  • dojox.widget.Portlet.addChild

    • type
      Function
    • parameters:
      • child: (typeof )
    • source: [view]
        this._size = null;
        this.inherited(arguments);


        if(this._started){
         this._placeSettingsWidgets();
         this._updateSize();
        }
        if(this._started && !child.started && !child._started){
         child.startup();
        }
    • summary
      Adds a child widget to the portlet.
  • dojox.widget.Portlet.destroyDescendants

    • type
      Function
    • parameters:
      • preserveDom: (typeof Boolean)
    • source: [view]
        this.inherited(arguments);
        if(this._settingsWidget){
         this._settingsWidget.destroyRecursive(preserveDom);
        }
    • summary
  • dojox.widget.Portlet.destroy

    • type
      Function
    • source: [view]
        if(this._timer){
         clearTimeout(this._timer);
        }
        this.inherited(arguments);
    • summary
  • dojox.widget.Portlet._setCss

    • type
      Function
    • source: [view]
        this.inherited(arguments);
        dojo.style(this.arrowNode, "display", this.toggleable ? "":"none");
    • summary
  • dojox.widget.Portlet.closeIcon

    • summary
  • dojox.widget.Portlet._settingsWidget

    • summary
  • dojox.widget.Portlet._timer

    • summary
  • dojox.widget.Portlet._size.w

    • summary
  • dojox.widget.PortletSettings

    • type
      Function
    • chains:
      • dijit._Container: (prototype)
      • dijit._Container: (call)
      • dijit.layout.ContentPane: (call)
    • mixins:
      • dijit.layout.ContentPane.prototype: (prototype)
    • 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.
  • dojox.widget.PortletSettings.portletIconClass

    • type
      String
    • summary
      The CSS class to apply to the icon in the Portlet title bar that is used
      to toggle the visibility of this widget.
  • dojox.widget.PortletSettings.portletIconHoverClass

    • type
      String
    • summary
      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.
  • dojox.widget.PortletSettings.postCreate

    • type
      Function
    • source: [view]
      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");
    • summary
  • dojox.widget.PortletSettings._setPortletAttr

    • type
      Function
    • parameters:
      • portlet: (typeof )
    • source: [view]
        this.portlet = portlet;
    • summary
      Sets the portlet that encloses this widget.
  • dojox.widget.PortletSettings.toggle

    • type
      Function
    • source: [view]
        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();
        }
    • summary
      Toggles the visibility of this widget.
  • dojox.widget.PortletSettings.portlet

    • summary
  • dojox.widget.PortletDialogSettings

    • type
      Function
    • chains:
      • dojox.widget.PortletSettings: (prototype)
      • dojox.widget.PortletSettings: (call)
    • summary
      A settings widget to be used with a dojox.widget.Portlet, which displays
      the contents of this widget in a dijit.Dialog box.
    • parameters:
      • props: (typeof )
      • node: (typeof )
    • source: [view]
        this.dimensions = props.dimensions || [300, 100];
  • dojox.widget.PortletDialogSettings.dimensions

    • type
      Array
    • summary
      The size of the dialog to display.	This defaults to [300, 300]
  • dojox.widget.PortletDialogSettings.toggle

    • type
      Function
    • source: [view]
        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);
        }
    • summary
      Shows and hides the Dialog box.
  • dojox.widget.PortletDialogSettings.dialog

    • summary
  • dojox.widget

    • type
      Object
    • summary
  • dojox

    • type
      Object
    • summary