Adding a context menu to aurelia

I have the need to add a custom context menu to a section of my aurelia project, and I can’t seem to get the right-click part to work properly and bring up the contextmenu.

here’s the context menu added to customer.js:

<div style="display: none;">
	<ul class="custom-menu">
		<li data-action="highlight">
			<input type="radio" id="blue" name="highlight">
			<label for="blue">Blue</label>
			<input type="radio" id="green" name="highlight">
			<label for="green">Green</label>
			<input type="radio" id="orange" name="highlight">
			<label for="orange">Orange</label>
			<input type="radio" id="red" name="highlight">
			<label for="red">Red</label>
			<input type="radio" id="none" name="highlight">
			<label for="none">None</label>
		</li>
		<li>
		&nbsp;&nbsp; 
		<input type="button" name="cancel" value="Cancel" 
			onclick.call="contextmenu_cancel()"> 
		&nbsp;&nbsp;&nbsp; 
		<input type="button" name="save" value="Save" 
			onclick.call="contextmenu_save(this)">
		</li>  
	</ul>
</div>

here’s the css code for the custom-menu:

style.css:

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

/* custom menu items */

.custom-menu li
{
  padding: 8px 12px;
  cursor: pointer;
  list-style-type: none;
  transition: all .3s ease;
  user-select: none;
}

.custom-menu li:hover
{
  background-color: #DEF;
}

here’s where I add the custom-menu contextmenu event to notesRow (the class that I’m right clicking on to get the contextmenu).

this.consolEvent = this.ea.subscribe('router:navigation:complete', async event => {

var isSearch = document.location.href;
if (isSearch.match('customer'))
 {
    await this.setHighlightActions();
  }

the code that sets the contextmenu actions itself:

  async setHighlightActions()
  {
    if (this.notesInfo.user_can_delete == -1 && this.notesInfo.can_highlight)
    {
/* I have tried .notesRow as well */
           $('#notesRow').contextmenu( (event) => {
          event.preventDefault();
          $("custom-menu").finish().toggle(100)
            .css({top: event.pageY + "px",
                  left: event.pageX + "px"});
          });
    }
  }

I have all this working in a javascript and perl environment, and am trying to transfer it to Aurelia, so any help would be appreciated.

I’ve would have thrown out any jquery and made it in plain aurelia.

If you want to capture the contextmenu click you can do this:
View:

<button contextmenu.delegate="contextClicked()">SomeButton</button>

Viewmodel:

export class CustomerPage{
     contextClicked(){
            console.log('Someone right-clicked SomeButton');
     }
}

Also, you might want to change to click.delegate from onclick.call.

From

<input type="button" onclick.call="contextmenu_cancel()" />

To

<input type="button" click.delegate="contextmenu_cancel()" />

Oh, I will try this!

Thank you!

But how would I attach this to the class notesRow, so that when I click on the div row, it comes up?

That’s the part that confuses me still?

Try to remove the div wrapper you have around the <ul class="custom-menu">
There is nothing in your current code which toggles the style attribute display:none; on this element.

Also the current query selection seems to be wrong. Change

 $("custom-menu").finish().toggle(100)
            .css({top: event.pageY + "px",
                  left: event.pageX + "px"});
          });

to

 $(".custom-menu").finish().toggle(100)
            .css({top: event.pageY + "px",
                  left: event.pageX + "px"});
          });

you`re missing a dot (.) before custom-menu.


If you want to clean it up a bit, and you use 1 custom-menu for all items, you can set a ref attribute on the list instead of using a query selector:

<ul class="custom-menu" ref="customMenuRef">
</ul>
export class CustomerPage{
     customMenuRef;

     contextClicked(event){
             $(this.customMenuRef).finish().toggle(100)
            .css({top: event.pageY + "px",
                  left: event.pageX + "px"});
          });
     }
}

if you use contextmenu.delegate you also need to pass the event:

<button id="notesRow" contextmenu.delegate="contextClicked($event)">
showContextMenu
</button> 
2 Likes