antonyboom
antonyboom

Reputation: 1181

Custom Contexmenu for different node in jstree angular directive

In my project I have tree based on jstee angular directive. I build this tree with help 2 api requests. This requests provide data for folder and end point child node (filters). Also I created custom context menu, with some functions for different types of node. In this context menu I defined variable check and with help this variable I set restrictions for operations with node. The full code of context menu looks like:

 $scope.contextMenu = {
            "create": {
                "label": "Create Folder",
                "icon": "ico/folder.png",
                "action": function (data) {
                    var inst = $.jstree.reference(data.reference),
                        obj = inst.get_node(data.reference),
                        id = obj['original']['id'];
                    var check = obj['original']['folderId'];

                    if (typeof check == "undefined") {
                        obj = {
                            text: prompt("put folder name"),
                            parent: id
                        };
                        eventService.createFolder(obj);
                        setTimeout(function () {
                            getTreeData();
                            $scope.load();
                        }, 100);
                    }
                    else {
                        alert("This function is not available");
                        return false
                    }
                    // inst.refresh(true)
                }
            },
            "rename": {
                "label": "Rename Folder",
                "icon": "ico/folder.png",
                "action": function (data) {
                    var inst = $.jstree.reference(data.reference),
                        obj = inst.get_node(data.reference),
                        check = obj['original']['folderId'];

                    if (typeof check == "undefined") {
                        var rename = {
                            id: obj.id,
                            text: prompt("put your name")
                        };
                        eventService.modifyFolder(rename);
                        inst.rename_node(obj, rename.text);
                    }
                    else {
                        alert("This function is not available");
                        return false
                    }
                }
            },
            "delete": {
                "label": "Delete Folder",
                "icon": "ico/folder.png",
                "action": function (data) {
                    var inst = $.jstree.reference(data.reference),
                        obj = inst.get_node(data.reference),
                        node = inst.get_selected(),
                        check = obj['original']['folderId'];

                    if (typeof check == "undefined") {
                        if (!node.length) {
                            return false;
                        }
                        eventService.deleteFolder(node);
                        inst.delete_node(node);
                    }
                    else {
                        alert("This function is not available");
                        return false
                    }
                }
            },
            "store": {
                "label": "Store Filter",
                "icon": "ico/file.png",
                "action": function (data) {
                    $scope.saveStateString();
                    var inst = $.jstree.reference(data.reference),
                        obj = inst.get_node(data.reference),
                        id = obj['original']['id'],
                        check = obj['original']['folderId'];

                    if (typeof check == "undefined") {
                        obj = {
                            body: $scope.state,
                            folderId: id,
                            text: prompt("put filter name")
                        };
                        // console.log(obj.body);
                        setTimeout(function () {
                            eventService.storeFilter(obj);
                        }, 1000);
                        setTimeout(function () {
                            getTreeData();
                            $scope.load();
                            alert("click to public filters to refresh the tree")
                        }, 1500)
                    } else {
                        alert("This function is not available");
                        return false
                    }
                }
            },
            "remove": {
                "label": "Remove Filter",
                "icon": "ico/file.png",
                "action": function (data) {
                    var inst = $.jstree.reference(data.reference),
                        node = inst.get_selected(),
                        obj = inst.get_node(data.reference),
                        check = obj['original']['folderId'];

                    if (typeof check == "undefined") {
                        alert("This function is not available");
                        return false
                    } else {
                        if (!node.length) {
                            return false;
                        }
                        eventService.deleteFilter(node);
                        inst.delete_node(node);
                    }
                }
            }
        };

Now I'm trying to split this context menu by type of node, that for each node I could see different context menu, I found some solutions here and it says:

$('#jstree').jstree({
    'contextmenu' : {
        'items' : customMenu
    },
    'plugins' : ['contextmenu', 'types'],
    'types' : {
        '#' : { /* options */ },
        'level_1' : { /* options */ },
        'level_2' : { /* options */ }
        // etc...
    }
});
function customMenu(node)
{
    var items = {
        'item1' : {
            'label' : 'item1',
            'action' : function () { /* action */ }
        },
        'item2' : {
            'label' : 'item2',
            'action' : function () { /* action */ }
        }
    }

    if (node.type === 'level_1') {
        delete items.item2;
    } else if (node.type === 'level_2') {
        delete items.item1;
    }

    return items;
}

I was trying to repeat this way in my app but always see "undefined" instead context menu.

Could anybody help me please to resolve my problem? Plunker with my code

Upvotes: 2

Views: 730

Answers (1)

Anton
Anton

Reputation: 796

Be sure you are using working jstree directive. I replaced mistakes in your directive

  if (config.plugins.indexOf('contextmenu') >= 0) {
                if (a.treeContextmenu) {
                    config.contextmenu = s[a.treeContextmenu];
                }
            }

            // if (config.plugins.indexOf('contextmenu') >= 0) {
            //     if (a.treeContextmenu) {
            //         config.contextmenu = config.contextmenu || {};
            //
            //         if (a.treeContextmenuaction != undefined) {
            //             config.contextmenu.items = function(e) {
            //                 return s.$eval(a.treeContextmenuaction)(e);
            //             }
            //         } else {
            //             config.contextmenu.items = function() {
            //                 return s[a.treeContextmenu];
            //             }
            //         }
            //     }
            // }

Your code should look like

$scope.contextMenu = {
    "items": function custom (node){

            // your menu
      }

     if(something){
           // do whatever
      }

     return items
 }

This is your working plunker!

Upvotes: 2

Related Questions