External ports on a group

Hi Guru,

I’m trying to create dinamical ports over a group, but I can’t find an example that shows how to create those outside the main shape of the group… above what I get with my code:
group_ports

and what I really need:
group_ports_new

I need to create those ports when I drag and drop a node within that group.
Here’s the code for the group:

      myDiagram.groupTemplate =
        $(go.Group, "Auto",
          { 
            background: "transparent",
            ungroupable: true,
            // highlight when dragging into the Group
            mouseDragEnter: function(e, grp, prev) { highlightGroup(e, grp, true); },
            mouseDragLeave: function(e, grp, next) { highlightGroup(e, grp, false); },
            computesBoundsAfterDrag: true,
            // when the selection is dropped into a Group, add the selected Parts into that Group;
            // if it fails, cancel the tool, rolling back any changes
            mouseDrop: finishDrop,
            handlesDragDropForMembers: true,  // don't need to define handlers on member Nodes and Links
            // Groups containing Groups lay out their members horizontally
            layout: makeLayout(false),
			cursor: "move"
          },
		  new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
          new go.Binding("layout", "horiz", makeLayout),
          new go.Binding("background", "isHighlighted", function(h) {
            return h ? "rgba(0,255,0,0.6)" : "transparent";
          }).ofObject(),
          $(go.Shape, "Rectangle",
            { fill: null, stroke: defaultColor(false), strokeWidth: 2 },
            new go.Binding("stroke", "horiz", defaultColor),
            new go.Binding("stroke", "color")),
          $(go.Panel, "Vertical",  // title above Placeholder
            $(go.Panel, "Horizontal",  // button next to TextBlock
              {
			    name: "hover-screenshot-panel",
				stretch: go.GraphObject.Horizontal, 
				background: defaultColor(false), 
     			portId: "totale",
     			// allows links to/from all sides
     			fromSpot: go.Spot.Right,
     			toSpot: go.Spot.Left,
     			fromLinkable: true,
     			toLinkable: true,
     			cursor:"pointer"
			  
			  },
              new go.Binding("background", "horiz", defaultColor),
              new go.Binding("background", "color"),
              $("SubGraphExpanderButton",
                { alignment: go.Spot.Right, margin: 5 }),
              $(go.TextBlock,
                {
                  alignment: go.Spot.Left,
                  editable: false,
                  margin: 5,
                  font: defaultFont(false),
                  opacity: 0.75,  // allow some color to show through
                  stroke: "#404040"
                },
                new go.Binding("font", "horiz", defaultFont),
                new go.Binding("text", "text").makeTwoWay())
            ),	// end Horizontal Panel
			$(go.Placeholder,
              { 
			    padding: 15, 
			    alignment: go.Spot.TopLeft 
			  })
		  ),  // end Vertical Panel
			$(go.Panel, "Vertical",{alignment: new go.Spot(1, 0.5) },
				new go.Binding("itemArray", "rightArray"),
				{
				  //row: 3, column: 2,
				  itemTemplate:
					$(go.Panel,
					  {
						_side: "right",
						fromSpot: go.Spot.Right, toSpot: go.Spot.Right,
						fromLinkable: true, toLinkable: false, 
						cursor: "pointer",
						contextMenu: portMenu
					  },
					  new go.Binding("portId", "portId"),
					  $(go.Shape, "Rectangle",
						{
						  stroke: null, strokeWidth: 0,
						  desiredSize: portSize,
						  margin: new go.Margin(1, 0),
						  fill: "blue"
						}
					  )
						//new go.Binding("fill", "portColor"))
					)  // end itemTemplate
				}
			 )  // end Vertical Panel
        );

Is also possible to write text within those ports?
Thx in advance
F

The “Auto” Panel is designed for putting elements within the main element, such as an element within a border. https://gojs.net/latest/intro/panels.html#AutoPanels

The “Spot” Panel is designed for arranging elements around the main element, including partly or completely outside of the main element. https://gojs.net/latest/intro/panels.html#SpotPanels

Clearly you want to use a “Spot” Panel instead of an “Auto” Panel. I think you want a variable number of port objects, so it is natural to bind the Panel.itemArray to an Array of port descriptor objects, and have the Panel.itemTemplate be a port, as you have done. But to position that collection of port panels, you’ll want to have that panel be aligned relative to the “Spot” Panel. Basically structure it like:

Panel, "Spot"
    ... the main body of the group ...
    Panel, "Vertical" or "Table", binding itemArray to Array of port descriptors
        ... ports, either "Horizontal" or "TableRow" panels ...

Your itemTemplate could be either a “Horizontal” Panel (if the container is a “Vertical” Panel) or a “TableRow” Panel (if the container is a “Table” Panel).

I can’t get it work, or more probably I don’t understand your suggestion…
the structure of the group is like that:

$(go.Group, "Auto",
....
 $(go.Panel, "Vertical",
    $(go.Panel, "Horizontal",
      ...
    } // end of horizontal
  }, // end of vertical
 $(go.Panel, "Vertical",
   new go.Binding("itemArray", "rightArray"),
   ...
  } // end of panel vertical
} // end of group auto

For this example I took some part from https://gojs.net/latest/samples/dynamicPorts.html for adding dynamic ports and some other from https://gojs.net/latest/samples/regrouping.html for draggin’ groups.
Now I tried to put “Spot” on the main body of group and “TableRow” on the vertical panel as you suggest and the result is this:
group_spot
What’s wrong?

by the way the itemTemplate was already “TableRow” here’s the code:

      var fieldTemplate =
        $(go.Panel, "TableRow",  // this Panel is a row in the containing Table
          new go.Binding("portId", "id"),  // this Panel is a "port"
          {
            background: "transparent",         // so this port's background can be picked by the mouse
            fromSpot: go.Spot.LeftRightSides,  // links only go from the right side to the left side
            toSpot: go.Spot.LeftRightSides,
            // allow drawing links from or to this port:
            fromLinkable: true, 
            fromMaxLinks: 1, 
            toLinkable: false, 
            toMaxLinks: 1
          },
          $(go.TextBlock,
            { margin: new go.Margin(0, 2, 0, 10), 
        	  column: 1, 
        	  font: "bold 12px sans-serif",
			  stroke:"white",
        	  alignment: go.Spot.Left, 
              fromLinkable: false, 
              toLinkable: false,
			  shadowVisible: false
        	  },
              new go.Binding("text", "name")),
          $(go.Shape, "TriangleRight", { 
        	  alignment: go.Spot.Right, 
        	  width: 9, 
        	  height: 9, 
        	  column: 3, 
        	  margin: 0, 
        	  //fill: "#5EA9BE",
        	  fill: "#FFFFFF",
        	  fromLinkable: true, 
        	  toLinkable: false,
			  shadowVisible: false			  
			  })
        );

So I only put “Spot” on the go.Group and the result was that I showed before…

Group, Spot
    Panel, Auto  // the main body of the group
        Shape
        Panel, Vertical
            Panel, Horizontal  // the title bar
                . . .
            Placeholder
    Panel, Vertical, alignment: go.Spot.Right
        Panel, Horizontal   // copies of itemTemplate, which are or which contain ports
            Shape
            TextBlock
        . . .

Great! It works
(without your pattern I would have taken years to figure it out…)
Many thx
ciao
F