You are here

Example of jsTree with different context menu for different node type

Submitted by Asif Nowaj, Last Modified on 2019-11-08

If you are wondering on how to let jsTree show different context menu for different nodes, you are at the right place. Context menu appears when a user right-click on a node. Probably you already have seen on how to show a customise context menu on jsTree's node right click. if not please have a quick look at jsTree with Custom Context Menuthen come back here to see how you can show different right click menu based on different condition.

For example, if you want to allow your users to delete "files" but not "folders" (by hiding the "delete" option from the context menu for folders) or to show Create new file, create new folder option for folders but not for files, please see the example below.

In this example, you will also be able see how you can use different icons for different nodes and different nodes for leaf nodes.

This can be achieved in many different ways using node's data property. li_attr property etc but here, a_attr has been used. Also, for simplicity, here two different functions has been used to create two different menu list, which could have been done more efficiently.

In this below example, I have used two different types of nodes, Folders and Files. for making icons different, glyphicon has been used from bootstrap css.

While you'll right click on a Folder, you will see full set of menus and submenus. But for File, you can only see remove and rename. You can take concept from here and implement your requirement if it differs what has been shown here.

When you clicks on a Folder node, below context menu will appear.

Context Menu For Folder Type Node

When you clicks on a File node, below context menu will appear.

Context Menu For File Type Node


<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Simple jsTree with different context menu for different node type</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
	<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
	<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jstree/3.3.8/themes/default/style.min.css" />
	<script src="//cdnjs.cloudflare.com/ajax/libs/jstree/3.3.8/jstree.min.js"></script>

    <script type="text/javascript">
        $(function () {
			
			var jsondata = [
                           { "id": "ajson1", "parent": "#", "text": "Simple root node", icon: 'glyphicon glyphicon-folder-open', "a_attr": {type:'folder'} },
                           { "id": "ajson2", "parent": "#", "text": "Root node 2", icon: 'glyphicon glyphicon-folder-open', "a_attr": {type:'folder'} },
                           { "id": "ajson3", "parent": "ajson2", "text": "Child 1", icon: 'glyphicon glyphicon-folder-open', "a_attr": {type:'folder'} },
                           { "id": "ajson4", "parent": "ajson2", "text": "Child 2", icon: 'glyphicon glyphicon-folder-open', "a_attr": {type:'folder'} },
            ];

            createJSTree(jsondata);
        });

		function getFolderContextMenu($node, tree)
		{
			return {
				"Create": {
					"separator_before": false,
					"separator_after": true,
					"label": "Create",
					"action": false,
					"submenu": {
						"File": {
							"seperator_before": false,
							"seperator_after": false,
							"label": "File",
							action: function (obj) {
								$node = tree.create_node($node, { text: 'New File', icon: 'glyphicon glyphicon-file', a_attr:{type:'file'} });
								tree.deselect_all();
								tree.select_node($node);
							}
						},
						"Folder": {
							"seperator_before": false,
							"seperator_after": false,
							"label": "Folder",
							action: function (obj) {
								$node = tree.create_node($node, { text: 'New Folder', icon:'glyphicon glyphicon-folder-open', a_attr:{type:'folder'} });
								tree.deselect_all();
								tree.select_node($node);
							}
						}
					}
				},
				"Rename": {
					"separator_before": false,
					"separator_after": false,
					"label": "Rename",
					"action": function (obj) {
						tree.edit($node);                                    
					}
				},
				"Remove": {
					"separator_before": false,
					"separator_after": false,
					"label": "Remove",
					"action": function (obj) {
						tree.delete_node($node);
					}
				}
			};
		}
		
		function getFileContextMenu($node, tree)
		{
			return {
				"Rename": {
					"separator_before": false,
					"separator_after": false,
					"label": "Rename",
					"action": function (obj) {
						tree.edit($node);                                    
					}
				},
				"Remove": {
					"separator_before": false,
					"separator_after": false,
					"label": "Remove",
					"action": function (obj) {
						tree.delete_node($node);
					}
				}
			};
		}
		
        function createJSTree(jsondata) {
            $('#SimpleJSTree').jstree({
                "core": {
                    "check_callback": true,
                    'data': jsondata
                    
                },
                "plugins": ["contextmenu"],
                "contextmenu": {
                    "items": function ($node) {
                        var tree = $("#SimpleJSTree").jstree(true);
						if($node.a_attr.type === 'file')
							return getFileContextMenu($node, tree);
						else
							return getFolderContextMenu($node, tree);                        
                    }
                }
            });
        }
    </script>
</head>
<body>
    <div id="SimpleJSTree"></div>
</body>
</html>

Discussion or Comment

If you have anything in mind to share, please bring it in the discussion forum here.

https://forum.everyething.com/jstree-f33/