Hide or show node element with button onclick

Hi all,

As the title stated above,

  1. I have set the element’s visible to false:

         ...
         $(go.Panel, "Table", { name: "SCORE", visible: false },
          ...
         )
    
  2. I have created show and hide buttons:

         $("Button",
           { row: 4, 
             margin: 2,
             click: function(e, node) { node.findObject("SCORE").visible = "true"; },
             maxSize: new go.Size(115, 28)
           },
           $(go.TextBlock, "Show Score")
         ), //end row 4
         $("Button",
           { row: 5, 
             margin: 2,
             click: function(e, node) { node.findObject("SCORE").visible = "false"; },
             maxSize: new go.Size(115, 28)
           },
           $(go.TextBlock, "Hide Score"))
    

but I got an error stating “Uncaught TypeError: Cannot set property ‘visible’ of null”. I have no idea how to solve the error. Please help.

Thank you.

Brian

First, GraphObject.visible is a boolean property, so you should not be setting it to a string.

Second, the second argument to the GraphObject.click function will be the object on which the click is defined. In your case that would be a “Button”. But your “SCORE” Panel is not within the “Button”, is it? You need to get the Node by using GraphObject.part.

Third, what you are trying to do is what the “PanelExpanderButton” is for: GoJS Buttons -- Northwoods Software

Hi Walter,

Thanks for the reply.

Here are my sample codes:

<body>
<div id="myDiagramDiv" style="width:100%; height:100%;"></div>
<script>
var $ = go.GraphObject.make;
diagram =
$(go.Diagram, "myDiagramDiv",
  {
    contentAlignment: go.Spot.TopCenter,
  }
);

  diagram.nodeTemplate =
    $(go.Node, "Auto",
      $(go.Shape,
        { fill: "gold" }),
      $(go.Panel, "Table",
        $(go.Panel, "Table",
          { column: 0 },
          $(go.TextBlock,
            { column: 0, margin: new go.Margin(3, 3, 0, 3),
              font: "bold 12pt sans-serif" }, new go.Binding("text", "title")),
          $("PanelExpanderButton", "TEXT1",
            { column: 1 }
          ),
          $(go.TextBlock,
            { name: "TEXT1", row: 1, column: 0 },
            new go.Binding("text", "text1"))
        )
      )
    );
    
  diagram.add(
    $(go.Part, "Table",
      { position: new go.Point(300, 10), selectable: false },
      $("PanelExpanderButton", "TEXT1",
        { row: 0, column: 0 }
      ),
      $(go.TextBlock, "Show/Hide Score",
        { row: 0, column: 1, font: "bold 9pt sans-serif" }
      )
    ));

  diagram.model = new go.GraphLinksModel([
    {
      key: 1,
      title: "Test 1",
      text1: "Hello World"
    },
    {
      key: 2,
      title: "Test 2",
      text1: "Hello World"
    }
  ]);
</script>
</body>

Is it possible to have one PanelExpanderButton that act on all nodes’ element? Thus, based on the example above, the PanelExpanderButton on the right will collapse/show the text on both nodes.

Thank you.

Brian

I think it would be a bit confusing to have a button on a node affect other nodes. Would you expect clicking on those buttons in other nodes to also affect all similar nodes?

If you want to implement that, I think you will need to implement a regular “Button” whose GraphObject.click event handler iterates through all of the Diagram.nodes and modifies them as desired. Remember to perform everything within a single transaction.

Would you expect clicking on those buttons in other nodes to also affect all similar nodes?

I am expecting by clicking a regular button outside the presented nodes, it will affect all the nodes.

Update

I think it is impossible for the button to expand/collapse the node if it is placed outside of the node and it is so odd to have button on a node affects the other nodes. So, I use javascript to append a parameter with its value true or false to the web url and fetch the parameter value to the GraphObject.visible. Note that the page is reloaded at each time the button is clicked.

Oh, OK, so you are changing your design so that it is an HTML Button, not part of any GoJS Node.

Whether or not you involve the server and reconstruct the whole Diagram each time is your choice. I strongly suspect that rebuilding the diagram is quite unnecessary and is wasteful of both server resources and time on the client.

Hi Walter,

so you are changing your design so that it is an HTML Button, not part of any GoJS Node

I am doing so because there is no way (maybe yes?) to create a rectangular gojs button that expands or collapses all nodes and with my limited knowledge on gojs, this is the only solution that I can think of right now. No doubt that my way of doing so is wasteful of resources but it is time consuming if users have to expand or collapse each nodes one by one.

I have been trying to answer the doubt: Is it possible to add a button to the diagram, which it is not located on the node but it is able to affect the node? but it seems not possible. Can you please guide me on this.

Thank you.

Update

I carefully re-read your comment above:

implement a regular “Button” whose GraphObject.click event handler iterates through all of the Diagram.nodes and modifies them as desired.

Is this the solution that I am looking for? Since in your previous sentences, you mentioned button on a node affect other nodes. So I guess it is a button on a node, not button outside the node.

It really doesn’t matter where the code is – you just need to iterate over all of the Diagram.nodes, and so it doesn’t matter if it’s a GoJS “Button” on a Node or a Link or an HTML button outside of the Diagram.

function allNodes(show) {
  myDiagram.commit(function(diag) {
    diag.nodes.each(function(n) {
      var panel = n.findObject("TEXT1");
      if (panel) panel.visible = show;
    });
  }, "toggle visibility");
}
1 Like