swisnl / jQuery-contextMenu

jQuery contextMenu plugin & polyfill
https://swisnl.github.io/jQuery-contextMenu/
MIT License
2.24k stars 746 forks source link

Inconsistent/wrong callbacks when passing variable as a menu's keyname #46

Closed okerix closed 12 years ago

okerix commented 12 years ago

Not sure if this is an issue or if I'm missing something. I create submenu items when I loop through an array. I try to create the keynames from a field in the array as well as use a value in the array for something in the callback. I think the keyname is not getting set properly because I get the wrong callbacks. If I hard code a basic string keyname it all works perfect. Problem is I don't know how many will be in the submenu. For now I'll just create a big case statement and plan for larger than what I think will be used. Here is an example of my code:

$.contextMenu({
    selector: '#pwx_frame_content',
    zIndex: '9999',
    className: 'ui-widget',
    build: function ($trigger, e) {
        var options = {
            items: {
                "fold1": {
                    "name": "Chart Forms&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class='pwx-submenu_arrow-icon'></span>",
                    "items": {},
                    disabled: false
                },
                "sep3": "---------",
                "Select All": { "name": "Select All", callback: function (key, opt) { pwx_select_all('pwx_row_selected'); } },
                "Deselect All": { "name": "Deselect All", callback: function (key, opt) { pwx_deselect_all('pwx_row_selected'); } }
            }
        };

        var testForms = new Array(3);
        testForms[0] = new Array(2);
        testForms[0][0] = 'Test Name 1';
        testForms[0][1] = 123456;
        testForms[1] = new Array(2);
        testForms[1][0] = 'Test Name 2';
        testForms[1][1] = 654321;
        testForms[2] = new Array(2);
        testForms[2][0] = 'Test Name 3';
        testForms[2][1] = 22222;
        for (var cc = 0; cc < testForms.length; cc++) {
            options.items["fold1"].items[testForms[cc][0]] = { "name": testForms[cc][0], callback: function (key, opt) { alert(testForms[cc][1]); } }
        }

        // -- this was missing --
        return options;
    }
});
rodneyrehm commented 12 years ago

You have fallen prey to the closure monster.

for (var cc = 0; cc < testForms.length; cc++) {
    options.items["fold1"].items[testForms[cc][0]] = { 
        "name": testForms[cc][0], 
        callback: function (key, opt) { alert(testForms[cc][1]); } 
    }
}

that cc is the cause of all your callbacks alerting 22222. May I suggest something like the following?

var testforms = [
    {'Test Name 1': 123456},
    {'Test Name 2': 654321},
    {'Test Name 3': 22222}
];

for (var cc in testforms) {
    options.items["fold1"].items[cc] = { 
        "name": cc, 
        callback: function (key, opt) { alert(testForms[key]); } 
    }
}
okerix commented 12 years ago

Ugh, first time meeting the closure monster. Did some reading up and thanks to your help it works perfect. Thanks! Also great plugin. Easy to work with and efficient!