jQuery-contextMenu icon indicating copy to clipboard operation
jQuery-contextMenu copied to clipboard

Option selectableSubMenu does not work

Open milosbielik opened this issue 5 years ago • 4 comments

(source: jQuery contextMenu v2.8.0) for { selectableSubMenu: true }...

my comments (FIXME) in code...

  // contextMenu item click
  itemClick: function (e) {
      var $this = $(this),
          data = $this.data(),
          opt = data.contextMenu,
          root = data.contextMenuRoot,
          key = data.contextMenuKey,
          callback;

      /* ----- FIXME: opt (for every submenu) is incorrect, items does not contain key, so first part of condition stops eval and returns */ 
      // abort if the key is unknown or disabled or is a menu
      if (!opt.items[key] || $this.is('.' + root.classNames.disabled + ', .context-menu-separator, .' + root.classNames.notSelectable) || ($this.is('.context-menu-submenu') && root.selectableSubMenu === false )) {
          return;
      }

milosbielik avatar Apr 19 '19 14:04 milosbielik

Maybe this should help to fix the issue...

 // FIXED/REPLACED (on line 1289): $t.data('contextMenu', item).addClass('context-menu-submenu');
 $t.addClass('context-menu-submenu');

milosbielik avatar Apr 23 '19 14:04 milosbielik

Also noticed this issue. Any ETA on a fix? Have a menu with a tree like structure and want all items to be clickable. my workaround is to put add the parent item within the child but its not a great user experience.

for instance A has children and I cant click it due to the bug so I add A in the submenu: A ->A ->B -->B -->C

Edit: I actually found a strange thing. If I add a clickable A in the submenu then I actually can click the parent A. So I am adding it in both places and setting the child A item visible:false. I can now have a more user friendly menu tree and still click on the parent item. Here is a workaround sample below until the bug gets fixed. Top menu has A and B. B has submenu C. I can click on any of A/B/C with this trick.

$.contextMenu({
    selector: '#menu1', 
selectableSubMenu: true,
    build: function(trigger, e) {
		return {
			selectableSubMenu: true,
			callback:function(key,options){alert(key);},
			items: {
				"A":{name:"A"},
				"B":{name:"B", items:{
					"B":{name:"B",visible:false},
					"C":{name:"C"}
					}}},
			selectableSubMenu: true
		}
	}
});

ThaGeege avatar Apr 25 '19 01:04 ThaGeege

https://github.com/swisnl/jQuery-contextMenu/issues/687#issuecomment-485832996 worked for me to solve this issue. Thanks!

Ashwinning avatar Oct 13 '19 15:10 Ashwinning

Hopefully this would be fixed in the next release:)

To add to the hacky workarounds.

Step 1: Make the sub menu creation similar to the default case of a menu item by attaching the callbacks.

 case 'sub':
                                $.each([opt, root], function (i, k) {
                                    k.commands[key] = item;
                                    // Overwrite only if undefined or the item is appended to the root. This so it
                                    // doesn't overwrite callbacks of root elements if the name is the same.
                                    if ($.isFunction(item.callback) && (typeof k.callbacks[key] === 'undefined' || typeof opt.type === 'undefined')) {
                                        k.callbacks[key] = item.callback;
                                    }
                                });     

Step 2: When processing a click event for a clickable submenu, switch the item context to its parent.

itemClick: function (e) {
                
                var $this = $(this),
                    data = $this.data(),
                    opt = data.contextMenu,
                    root = data.contextMenuRoot,
                    key = data.contextMenuKey,
                    callback;

                //if, clickable submenu, switch the item context to its parent
              	if(($this.is('.context-menu-submenu') && root.selectableSubMenu))
                {
     				$this = $(this).parent(),
                    data = $this.data(),
                    opt = data.contextMenu,
                    root = data.contextMenuRoot;
                }

This appears to be a robust workaround.

CipherTrustee avatar Dec 12 '19 03:12 CipherTrustee