[FIXED] JS custom context menu

What I’m trying to do:
Custom Context-menu that shows with right click on specific element only.

What I’ve tried and what’s not working:
It is working, however the custom menu disappear immediately!

Code Sample:

# code snippet
<center>
  <div>                     
    <br>
  </div>
  <div id = "to"> Click here to show the custom context-menu </div> 
</center>

<ul class='custom-menu'>
  <li data-action = "first">First thing</li>
  <li data-action = "second">Second thing</li>
  <li data-action = "third">Third thing</li>
</ul>

<style>
.custom-menu {
    display: none;
    z-index: 1000;
    position: absolute;
    overflow: hidden;
    border: 1px solid #CCC;
    white-space: nowrap;
    font-family: sans-serif;
    background: #FFF;
    color: #333;
    border-radius: 5px;
}

.custom-menu li {
    padding: 8px 12px;
    cursor: pointer;
}

.custom-menu li:hover {
    background-color: #DEF;
}
</style>

<script>
  $("#to").on("contextmenu", function (event) {
    
    // Avoid the real one
    event.preventDefault();
    
    // Show contextmenu
    $(".custom-menu").finish().toggle(100).
    
    // In the right position (the mouse)
    css({
        top: event.pageY + "px",
        left: event.pageX + "px"
    });
});


// If the document is clicked somewhere
$(document).on("mousedown", function (e) {
    
    // If the clicked element is not the menu
    if (!$(e.target).parents(".custom-menu").length > 0) {
        
        // Hide it
        $(".custom-menu").hide(100);
    }
});


// If the menu element is clicked
$(".custom-menu li").click(function(){
    
    // This is the triggered action name
    switch($(this).attr("data-action")) {
        
        // A case for each action. Your actions here
        case "first": alert("first"); break;
        case "second": alert("second"); break;
        case "third": alert("third"); break;
    }
  
    // Hide it AFTER the action was triggered
    $(".custom-menu").hide(100);
  });
   </script>


Clone link:
https://anvil.works/build#clone:AK3MFZG23DHS2LMK=MN7WKBO35OCYHLHONHKLCD62

Looks like you’ve stumbled across a bug.

Sorry about that. For now if you wrap your script inside a function and call this in the form show event then in should behave as expected.

https://anvil.works/build#clone:NWHG55JJ5PRA5Y6A=FUEH7GU2TERT6F2VOG7WMFPG

1 Like

Update - that bug is fixed and should go live soon.
In the meantime the suggested workaround above will work just fine.

Thanks for reporting.

1 Like

That should now be fixed.
As an alternative to what you did you could also use AnvilAugment and Popovers to achieve it with python code

Both available with the anvil-extras library

Example below
https://anvil.works/build#clone:JMLU4Y6OQJDZXMOE=H64BLRZZWPPKJYFVCV766J2D

1 Like

Thank you so much for fixing the bug!
I thought about using popovers, but it doesn’t utilize the right click. I am not sure if I can do that with AnvilAugment, I will give it a try when I have a chance.

Thank you again!

Now, I have another issue (Sorry for being annoying :sweat_smile:) , when I use the form as a custom component, the context-menu doesn’t overlap/overlay other components in the parent form, I tried to play with "
position: relative;" however it missed it up more, sorry I have limited CSS knowledge!

https://anvil.works/build#clone:AK3MFZG23DHS2LMK=MN7WKBO35OCYHLHONHKLCD62

this will be the overflow properties in css.
in the parent container (html template) component try setting overflow: visible

Hopefully you can see in the example above

set the popover trigger to manual
add a contextmenu eventhandler using the augment library
in the event handler show the popover
in the click event handler(s) hide the popover :slightly_smiling_face: