0

I am using jsTree to build a knowledge base for a customer support service. For this, I need to be able to send contents from each node to any of currently active users on my website.

This means that each time I call a context menu for a node, I need it to get currently active users via ajax, and then display them as menu items.

Now, I know that contextmenu is a function of node. But how to bind it to the results of an ajax function?

Something along the lines of:

"contextmenu": {
    "select_node": false,
    "show_at_node": false,
    "items": function(node) {
        $.ajax({
            url: 'some_url_with_actions_for_node',
            success: function (action_list) {
                return action_list;
            }
        })
    }
}

obviously the example above won't work, but you get the idea.

The docs say that the menu can be

a function that accepts a node and a callback function and calls the callback function with an object of actions available for that node (you can also return the items too)

so maybe there's a way to squeeze in the callback I need? I am just too bad at JS to figure this out.

kurtgn
  • 8,140
  • 13
  • 55
  • 91

2 Answers2

1

I'm not sure if you can make it by native jsTree context menu functionality since you make an async action. Without better solution I would just build the menu manually as below. Check demo - Fiddle Demo

...
'contextmenu': {
    'items': function(node) {

        // remove default context menu items
        var tmp = $.jstree.defaults.contextmenu.items();
        delete tmp.rename;
        delete tmp.remove;
        delete tmp.ccp;
        delete tmp.create;

        tmp = {
            loading: {
                label: "Wait ..."
            }
        }

        // start ajax
        _loadMenuItems();

        return tmp;
    }
}



function _loadMenuItems() {

    // make ajax call

    // in your success function, where serverData is the data you got:
    $('.vakata-context').html('');

    serverData.forEach(function(item) {
        var menuItem = $('<li><a href="#">' + item.label + '</a></li>');
        menuItem.click(item.action);
        $('.vakata-context').append(menuItem);
    });

}
Nikolay Ermakov
  • 5,031
  • 2
  • 11
  • 18
1

I had exactly the same issue and you can find the solution here.

You just have to do:

contextmenu: {
    items: function (node, buildContextMenu) {
        var entries= {};

        $.ajax({
            url: "...",
            data: node.id,
            success: function () {
                // Construct the entries
                ...

                buildContextMenu(entries); // <--- SOLUTION
             }
        });
    }
}
vnea
  • 84
  • 3
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/16993956) – Yodan Tauber Aug 10 '17 at 14:02
  • Okay, that's why my answer got down voted. I'm new in SO and I didn't read the docs yet. – vnea Aug 10 '17 at 14:07
  • @vnea, thank you so much. It has saved me plenty of time! – Sergеу Isupov Mar 23 '20 at 12:07