J-Query Context Menu updating via Knockout call

401 views Asked by At

We are implementing a rather complex single page application and decided to use the "Jquery-context-menu" toolbox. However, we have a fundamental question, and after two days of searching, and reading stuff on the web we are somewhat out of ideas.

The basic question is: If and if yes, how, it will be possible to access the update function (i.e the disable function) from outsite the menu, while the menu is still upon?

The scenario: We are implementing a game. We use the "jquery context menu" as a context menu for an icon that can be activated by the user (think of a rpg type of icon). After activating it via a click it will be deactvitated automatically (after a few seconds) and then be ready for reactivation again after a while. What we what is that the menu is capturing this state of the icon, by enabling or disabling the menu, while the menu is held open.

There is one example of how to change the visibility of a menu item, via a button press in the same menu, as can be found here:

http://medialize.github.io/jQuery-contextMenu/demo/disabled-changing.html

However, we aim to update the menu from outsite (via a knockout subscribe call). So we would like to do something like:

myknockoutobservable.subscribe(function(newValue){
correctRefernceToThis.data('disableItem1', newvalue)});      

while the disabled function looks somehitng like:

disabled: function(key, opt) {
return !this.data('cutDisabled')};       

OR, if this does not work we maybe could directly call the update fucntion

 myKnockoutobservable.subscribe(function(newValue){
$.contextMenu.op.update(correctRefernceToOpt,correctRefernceToroot)});  

and then querying the knockout observable in the callback

if (!myKnockoutobservable) {
return true;}
else {
return false;   

The main problem seems to be that we don't reference the context correctly, so we don't have a handle on the correct this, opt, to root, variables, from outside of the Jquery context menu (At least that is our current opinion). We would be very happy if someone could help us finding a solution, or even some good ideas what to try (what we haven't yet).

2

There are 2 answers

0
Roy J On

You won't subscribe, you'll just have an observable in your viewmodel that you set to true or false, and the menu item will toggle in response. The disabled member of your menu item will look like this:

disabled: function() { 
    return myobservable();
}

As James Thorpe commented, you'll want to create a custom binding handler to set up your context menu.

It sounds like you're working with several unfamiliar tools. Here is a Fiddle with a minimal example: http://jsfiddle.net/sv3m7ok8/

Update It occurred to me that since the context menu doesn't bind to a single element, but uses a selector, it makes more sense to do the binding on the body tag. So an updated example: http://jsfiddle.net/sv3m7ok8/1/

Updated again I now understand that you are specifically trying to get the menu item to enable/disable while the menu is open (and that it doesn't do that normally). I had to go under the covers to get at the menu item node, and hook up a subscription to set the disabled class on it.

init: function (element, data, allbindings, data) {
    var dynamicDisable = false;
    $.contextMenu({
        selector: '.context-menu-one',
        callback: function (key, options) {
            var m = "clicked: " + key;
            window.console && console.log(m) || alert(m);
        },
        items: {
            "edit": {
                name: "Clickable",
                icon: "edit",
                disabled: function (opt, key) {
                    if (!dynamicDisable) {
                        var node = key.items.edit.$node[0];
                        data.disableMenu.subscribe(function (dis) {
                            $(node)[dis ? 'addClass' : 'removeClass']('disabled')
                        });
                        dynamicDisable = true;
                    }
                    return data.disableMenu();
                }
            }
        }
    });
}

My fiddle sets an interval to toggle disableMenu. You can watch the menu item become active and gray.

http://jsfiddle.net/sv3m7ok8/3/

1
Caspar Goeke On

Thanks you for your help! I understand your approach and it is indeed exactly what we have done:-) I might have not been so clear on this issue but this is the current code od the disabled callback.

disabled: function(key, opt) {
                        if (!self.item._blocks.Feature._processedStack().canBeActivated()) {
                            return true;
                        }
                        else {
                            return false;
                        }
                    }

This works such that when the menu in closed and reopned again the state is updated. However the update is NOT working while the menu is still open because nothing is triggering the menu to update to the new value.

At the moment we are trying to solve the issue with a different library, will keep you updated.

best, Caspar