We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

How to implement a contextual menu for a node

Hi,

We need to offer our users a contextual menu for certain node types.
Typically this is accomplished by intercepting a right-click event.

Do you have a suggested approach or examples?

Thanks in advance.

Jim

15 Replies

SG Shyam G Syncfusion Team November 3, 2014 05:07 PM UTC

Hi Jim

Thanks for using Syncfusion products.

We have created a simple sample to represent how to render context menu. We suggest you to set “Diagram1.Model.EnableContextMenu as true” to render context menu. To render a specific context menu item, please follow the below code snippet. We have some issues in rendering specific context menu item and in custom context menu. The fix for this issue is estimated to be available on service pack release, which is scheduled to release in the end of November.

 

$(window).load(function () {             

             var diagram = $("#Diagram1").data("ejDiagram");          

             var contextMenu = $.extend(true, {}, diagram.model.contextMenu);

             $("#Diagram1").ejDiagram({

                 //render context menu

                 contextMenu: contextMenu           

            })           

        });

        //render a particular contextmenu item

        ej.datavisualization.Diagram.Locale["en-US"] = {

            cut: "Cut",

        }

Sample:http://www.syncfusion.com/downloads/support/directtrac/general/WebApplication21_(2)-1979191829.zip

Please let me know if any concerns.

Regards,

Shyam G



JJ Jim Jacobs December 15, 2014 02:13 PM UTC

Hi Shyam,

Thanks for the code, but let me do a better job of explaining my requirement.
I have attached several screenshots.
One shows our current diagram solution and the type of context menu we want when you right-click on a shape.
Also, we need to be able to base the menu on the type of node (probably identified through an addInfo property).
The other 2 screenshots show what I currently get using the code that you provided.  In one case a node is selected; in the other the node is NOT selected.

Can you provide an approach (and code is always nice as well) that will enable us to have custom context menus that fire events that we can handle, and be based on the type of node.
We need access to the node object itself to interrogate various properties like database key, which will be saved in an addInfo property.

Can the use of your ejMenu be employed in this solution?

Thanks in advance for your assistance on this important requirememt.

Jim

Attachment: Syncfusion__Context_Menu__Requirement_20534f61.zip


SG Shyam G Syncfusion Team December 16, 2014 01:39 PM UTC

Hi Jim

 

Thanks for the update.

 

Query

Response

Thanks for the code, but let me do a better job of explaining my requirement.
I have attached several screenshots.
One shows our current diagram solution and the type of context menu we want when you right-click on a shape.
Also, we need to be able to base the menu on the type of node (probably identified through an addInfo property).
The other 2 screenshots show what I currently get using the code that you provided.  In one case a node is selected; in the other the node is NOT selected.

Can you provide an approach (and code is always nice as well) that will enable us to have custom context menus that fire events that we can handle, and be based on the type of node.
We need access to the node object itself to interrogate various properties like database key, which will be saved in an addInfo property.

We are glad to inform you that we have created a sample to render custom context menu and it is available in the below link for download. Please see the code snippet below.

 

var diagramId = "Diagram1";

        $(window).load(function () {

            var diagram = $("#Diagram1").data("ejDiagram");

            var contextMenu = $.extend(true, {}, diagram.model.contextMenu);

            contextMenu.items.push({ name: "process", text: "process" }, { name: "process1", text: "process1" }, { name: "process2", text: "process2" }, { name: "process3", text: "process3" });

            $("#Diagram1").ejDiagram({ contextMenu: contextMenu });

        });

 

        ej.datavisualization.Diagram.Locale["en-US"] = {

            cut: "Cut",

            copy: "Copy",

            paste: "Paste",

            undo: "Undo",

            redo: "Redo",

            selectAll: "SelectAll",

            grouping: "Grouping",

            group: "Group",

            ungroup: "Ungroup",

            order: "Order",

            bringToFront: "BringToFront",

            moveForward: "MoveForward",

            sendBackward: "SendBackward",

            sendToBack: "SendToBack",

            //custom menu

            process: "process",

            process1: "process1",

            process2: "process2",

            process3: "process3",

        }

 

 

        function nodeclick(args) {

            var diagram = $("#Diagram1").data("ejDiagram");

            var node = diagram.selectionList[0];

            if (node) {

                if (node.addInfo.Id == "one") {

                    document.getElementById(diagramId + "_contextMenu_process2").style.display = "none";

                    document.getElementById(diagramId + "_contextMenu_process3").style.display = "none";

                    document.getElementById(diagramId + "_contextMenu_process").style.display = "block";

                    document.getElementById(diagramId + "_contextMenu_process1").style.display = "block";

                }

                if (node.addInfo.Id == "two") {

                    document.getElementById(diagramId + "_contextMenu_process").style.display = "none";

                    document.getElementById(diagramId + "_contextMenu_process1").style.display = "none";

                    document.getElementById(diagramId + "_contextMenu_process2").style.display = "block";

                    document.getElementById(diagramId + "_contextMenu_process3").style.display = "block";

                }

            }

        }

 

Sample:http://www.syncfusion.com/downloads/support/directtrac/general/customcontextmenu555266111.zip

 

Currently we have an issue in “contextMenuClick” event. We have already logged a defect report and fix for this issue is estimated to be available on volume 4 2014 release, which is scheduled to release in the mid of December.

Please note that you need to define default context menu along with the custom menu in    “ej.datavisualization.Diagram.Locale["en-US"]”  and you cannot define custom menu alone in “ej.datavisualization.Diagram.Locale["en-US"] . We have already logged a defect report and fix for this issue is estimated to be available on volume 4 2014 release, which is scheduled to release in the mid of December.

Can the use of your ejMenu be employed in this solution?

We are currently analyzing on your requirement of including ejMenu(context menu) in the diagram. However we will update you with more information in one business day(12/17/2014).

 

Please let me know if any concerns.

 

Regards,

Shyam G



SG Shyam G Syncfusion Team December 17, 2014 01:17 PM UTC

Hi Jim

 

Thanks for your patience

 

Query

Response

Can the use of your ejMenu be employed in this solution?

We are glad to inform you that we have created a sample of custom context menu using ejMenu in the diagram.

 

Sample:http://www.syncfusion.com/downloads/support/directtrac/general/ejmenu-1077544391.zip

 

Please see the event below which is used in the context menu.

1.“ClientSideOnBeforeContextOpen”- This event fires before context menu gets open.

 

Code snippet:

<ej:Menu ID="Menu1" MenuType="ContextMenu" ClientSideOnBeforeContextOpen="open"   OpenOnClick="false" runat="server" ContextMenuTarget="#Diagram1">

       

 

    </ej:Menu>

 

function open(args) {

            var diagram = $("#Diagram1").data("ejDiagram");

                var node = diagram.selectionList[0];

                if (node) {

                    if (node.addInfo.Id == "one") {

                        document.getElementById("process").style.display = "none";

                        document.getElementById("process1").style.display = "none";

                        document.getElementById("process2").style.display = "block";

                        document.getElementById("process3").style.display = "block";

                    }

                    if (node.addInfo.Id == "two") {

                        document.getElementById("process2").style.display = "none";

                        document.getElementById("process3").style.display = "none";

                        document.getElementById("process").style.display = "block";

                        document.getElementById("process1").style.display = "block";

                    }

                }

            }

2.” ClientSideOnClick”- Fires when mouse click on menu items.

 

Code snippet:

<ej:Menu ID="Menu1" MenuType="ContextMenu"   ClientSideOnClick="onclick" OpenOnClick="false" runat="server" ContextMenuTarget="#Diagram1">

       

 

    </ej:Menu>

 

function onclick(args) {

            switch (args.text) {

                case "process": //some process;

                    break;

                case "process1":

                    //some process;

                    break;

                case "process2":

                    //some process;

                    break;

                case "process3":

                    //some process;

                    break;

               

            }

        }

 

 

Please let me know if any concerns.

 

Regards,

Shyam G



JJ Jim Jacobs December 18, 2014 08:31 PM UTC

Hi Shyam,

I think I'll wait for the December release to be available until I pursue this.
However, I do have a question based on examining the code snippets that you did provide.

It would seem that "something" has to be selected based on the "var node = diagram.selectionList[0];" statement.

This would seem contrary to how a contextual menu should work.  You should be able to right click on a node without it first having been selected (via left click).

Am I missing something?  Or is this an issue that will be resolved in the upcoming release?

Thanks for any clarification you can provide.

Jim


SG Shyam G Syncfusion Team December 19, 2014 11:46 AM UTC

Hi Jim

Thanks for the update.

Please note that Node gets selected only on the left click and it will not be selected on the right click. We consider “Node is not selected, when we right click on the node”  as a defect and created a new incident 133287 on behalf of you related to this forum. We suggest you to follow up the incident for further reference using your direct trac account

Please let me know if any concerns.

Regards,

Shyam G



JJ Jim Jacobs February 11, 2015 01:30 AM UTC

Hi,

I downloaded and installed 12.4.0.30 today and tried to get custom context menus working.
No luck so far.

Some observations.
  • I am not seeing my custom menu items shown in the context menu
  • I do not want Undo, Redo and the Group and Order menu items at all
  • It seems that I have to right-click on a node twice to see the context menu (the first right click simply selects the node)
  • I'm encountering errors trying to resolve my context menu items (see attached video)

Here's my relevant code snippets (primarily what you provided me):

The ejDiagram declaration:

                    <ej:Diagram ID="DiagramContent" runat="server" Height="100%" Width="100%" ClientDrop="dropHandler" OnClientNodeCollectionChange="nodecollectionchangeHandler"
                        OnClientSelectionChange="selectionChangeHandler" ClientItemClick="clickHandler" >
                    </ej:Diagram>

Within $(window).load(function():

    var contextMenu = $.extend(true, {}, diagram.model.contextMenu);
    contextMenu.items.push({ name: "taskDetails", text: "Details" }, { name: "taskRoles", text: "Roles" }, { name: "taskDataSpecs", text: "Data Specs" });
    $("#DiagramContent").ejDiagram({ contextMenu: contextMenu });
 ej.datavisualization.Diagram.Locale["en-US"] = {
        cut: "Cut",
        copy: "Copy",
        paste: "Paste",
        selectAll: "SelectAll",
        taskDetails: "Details",
        taskRoles: "Roles",
        taskDataSpecs: "Data Specs"
    }

The ClientItemClick handler:

            function clickHandler(args) {
                var diagramId = "DiagramContent";
                var node = diagram.selectionList[0];
                if (node) {
                    if (node.addInfo.NodeType) {
                        if (node.addInfo.NodeType == "Task") {
                            document.getElementById(diagramId + "_contextMenu_taskDetails").style.display = "block";
                            document.getElementById(diagramId + "_contextMenu_taskRoles").style.display = "block";
                            document.getElementById(diagramId + "_contextMenu_taskDataSpecs").style.display = "block";
                        } else {
                            document.getElementById(diagramId + "_contextMenu_taskDetails").style.display = "none";
                            document.getElementById(diagramId + "_contextMenu_taskRoles").style.display = "none";
                            document.getElementById(diagramId + "_contextMenu_taskDataSpecs").style.display = "none";
                        }
                    }
                }
            }

Any idea what I'm doing wrong?

Are the duplicate context menu items (which you've acknowledged as a defect) getting in my way?

This is a rather serious issue that we would like to address as soon as possible.

Thanks in advance.

Jim


Attachment: Syncfusion__Context_Menu_Challenge__10Feb2015_660ed0ee.zip


SG Shyam G Syncfusion Team February 11, 2015 01:18 PM UTC

Hi Jim

Thanks for using Syncfusion products.

Query

Response

  • I am not seeing my custom menu items shown in the context menu
  • I do not want Undo, Redo and the Group and Order menu items at all

We have created a sample of custom context menu and it is available in the below link for download. Please refer the code snippet below.

Code snippet:

<script>

        ej.datavisualization.Diagram.Locale["en-US"] = {           

            taskDetails: "Details",

            taskRoles: "Roles",

            taskDataSpecs: "Data Specs"

        }

        var diagramId = "Diagram1";

        $(window).load(function () {                       

            $("#Diagram1").ejDiagram({

                //menu item click event

                contextMenuClick: "menuClick",

                //custom context menu

                contextMenu: {

                    items: [

                    { name: "taskDetails", text: "Details" },

                    { name: "taskRoles", text: "Roles" },

                    { name: "taskDataSpecs", text: "Data Specs" }],

                    

                },

            });

        });

        function menuClick(args) {

            alert("menu item clicked");

             

        }

    </script>

Sample:http://www.syncfusion.com/downloads/support/directtrac/117513/customcontextmenusample1252285101.zip

It seems that I have to right-click on a node twice to see the context menu (the first right click simply selects the node)

Please note that when node is not selected, then it will be selected on the first right click and it shows the context menu only on the second right click. If the node is selected, then the context menu will be shown on the first right click. This is the default behavior of our diagram control.

Please let me know if any concerns.

Regards,

Shyam G




JJ Jim Jacobs March 9, 2015 03:19 PM UTC

Hi,

I've been somewhat successful in getting a contextual menu setup working using your Menu control - something you demonstrated earlier in this post.
Here's my Menu declaration:

    <ej:Menu ID="diagramContextMenu" MenuType="ContextMenu" ClientSideOnBeforeContextOpen="openDiagramContextMenu" ClientSideOnClick="DiagramContextMenuItemClicked" OpenOnClick="false" runat="server" ContextMenuTarget="#DiagramContent">
        <Items>
            <ej:MenuItem Id="copy_object" Text="Copy"></ej:MenuItem>
            <ej:MenuItem Id="paste_object" Text="Paste"></ej:MenuItem>
            <ej:MenuItem Id="cut_object" Text="Cut"></ej:MenuItem>
            <ej:MenuItem Id="delete_object" Text="Delete"></ej:MenuItem>
            <ej:MenuItem Id="select_all" Text="Select All"></ej:MenuItem>
            <ej:MenuItem Id="task_details" Text="Details"></ej:MenuItem>
            <ej:MenuItem Id="task_roles" Text="Roles"></ej:MenuItem>
            <ej:MenuItem Id="task_inputs" Text="Inputs"></ej:MenuItem>
            <ej:MenuItem Id="task_outputs" Text="Outputs"></ej:MenuItem>
            <ej:MenuItem Id="task_data_specs" Text="Data Specs"></ej:MenuItem>
            <ej:MenuItem Id="task_tool_specs" Text="Tool Specs"></ej:MenuItem>
            <ej:MenuItem Id="task_procedures" Text="Procedures"></ej:MenuItem>
            <ej:MenuItem Id="task_notes" Text="Notes"></ej:MenuItem>
        </Items>
    </ej:Menu>

And here's the function that fires on the ClientSideOnBeforeContextOpen event:

        function openDiagramContextMenu(args) {
            var diagram = $("#DiagramContent").data("ejDiagram");
            var node = diagram.selectionList[0];
            document.getElementById("task_details").style.display = "none";
            document.getElementById("task_roles").style.display = "none";
            document.getElementById("task_inputs").style.display = "none";
            document.getElementById("task_outputs").style.display = "none";
            document.getElementById("task_data_specs").style.display = "none";
            document.getElementById("task_tool_specs").style.display = "none";
            document.getElementById("task_procedures").style.display = "none";
            document.getElementById("task_notes").style.display = "none";
            if (node) {
                if (node.addInfo.NodeType) {
                    if (node.addInfo.NodeType == "Task") {
                        document.getElementById("paste_object").style.display = "none";
                        document.getElementById("select_all").style.display = "none";
                        document.getElementById("copy_object").style.display = "block";
                        document.getElementById("cut_object").style.display = "none";
                        document.getElementById("delete_object").style.display = "block";
                        document.getElementById("task_details").style.display = "block";
                        document.getElementById("task_roles").style.display = "block";
                        document.getElementById("task_inputs").style.display = "block";
                        document.getElementById("task_outputs").style.display = "block";
                        document.getElementById("task_data_specs").style.display = "block";
                        document.getElementById("task_tool_specs").style.display = "block";
                        document.getElementById("task_procedures").style.display = "block";
                        document.getElementById("task_notes").style.display = "block";
                    }
                } else {
                    document.getElementById("select_all").style.display = "none";
                    document.getElementById("copy_object").style.display = "block";
                    document.getElementById("cut_object").style.display = "block";
                    document.getElementById("paste_object").style.display = "none";
                    document.getElementById("delete_object").style.display = "block";
                }
            } else { // Must be on white space, in which case the only suitable menu item is Select All and possibly, Paste
                document.getElementById("select_all").style.display = "block";
                document.getElementById("copy_object").style.display = "none";
                document.getElementById("cut_object").style.display = "none";
                document.getElementById("paste_object").style.display = "block"; // should really only be enabled if copy or cut issued earlier
                document.getElementById("delete_object").style.display = "none";
            }
        }

As you can see from the attached video, the above works fine if I right-click on any node or connector.
The issue is when I click on whitespace.  I am NOT getting the menu I expect (with just 2 items).
Where is this menu coming from and how can I only get the simple 2-item menu I'm looking for?

By the way, when the page is initially loaded and I right-click on whitespace I see BOTH my menu and the one I don't want (you'll see this at the beginning of the video).
Subsequently I only see the single incorrect menu with 4 items.

Any thoughts?

Thanks

Jim


Attachment: Syncfusion__Issue_with_Context_Menus__09Mar2015_238ce62.zip


AK Ashok Kumar V Syncfusion Team March 10, 2015 01:18 PM UTC

Hi Jim,

Thanks for your update.

We are working on this with high priority and we will update you with more information in one business day on 11th March 2015.

Regards,

Ashok Kumar.




SG Shyam G Syncfusion Team March 11, 2015 11:54 AM UTC

Hi Jim

Thanks for your patience

We suggest you to set Model property “EnableContextMenu” as false in order to resolve your reported issue. We have created a simple sample and it is available in the below link for download.

Sample:http://www.syncfusion.com/downloads/support/directtrac/117513/contextmenu-1620889100.zip

Please let me know if any concerns.

Regards,

Shyam G




JJ Jim Jacobs March 11, 2015 01:23 PM UTC

Hi Shyam,

Sorry, that didn't work.
I set DiagramContent.Model.EnableContextMenu = false; in code behind.

See the attached screenshot showing what I get when I right-click on white space.

Jim


SG Shyam G Syncfusion Team March 12, 2015 02:01 PM UTC

Hi Jim

Thanks for the update.

We are afraid that we are unable to reproduce the reported issue at our end. Could you please provide us more details such as screenshot or video or modify the below sample to reproduce the reported issue at our end? This will help us to verify further and provide a better solution.

Here is the sample

Sample:http://www.syncfusion.com/downloads/support/directtrac/117513/contextmenu1-2030961451.zip

Here is the video

Video:http://www.syncfusion.com/downloads/support/directtrac/117513/contextmenuvideo1938265962.zip

Note: Please note that we could not find any screenshots from your previous update.

Please let me know if any concerns.

Regards,

Shyam G




JJ Jim Jacobs March 12, 2015 06:12 PM UTC

Hi Shyam,

I created a new diagram and guess what - everything works!
Which begs a question.
What would have been saved in the diagram data (JSON) that would have caused such an issue?
Are there any properties that are saved with the diagram that would somehow need to be changed should I change my code or declarations - such as page settings?

Thanks for any advice on this matter.

Jim



SG Shyam G Syncfusion Team March 13, 2015 01:43 PM UTC

Hi Jim

Thanks for the update.

Could you please confirm whether your mean the context menu is repeated twice after performing save and load the diagram? If yes, we are unable to reproduce the reported issue at our end. Could you please provide us more details such as video or modify the below sample to reproduce the reported issue at our end? This will help us to verify further and provide a better solution to you. Please refer the below sample and video below for further reference.

Here is the sample

Sample:http://www.syncfusion.com/downloads/support/directtrac/117513/contextmenusaveandload-732158269.zip

Here is the video

Video:http://www.syncfusion.com/downloads/support/directtrac/117513/contextmenuvideo-883618517.zip

Please let me know if any concerns.

Regards,

Shyam G



Loader.
Up arrow icon