showContextMenu

I am using the following script to show a custom context menu:

dundas.context.getService(“ContextMenuService”).showContextMenu(commands,e.originalEvent);

Per documentation:
(optional) The event arguments to use to configure the menu (eg: position). If this isn’t specified, then the last known position is used.

I want to specify the context menu position based on the bottom left position of the command button calling the script to show the custom menu. I have try multiple things unsuccessfully. Can someone provide a sample code on how to do that?

The problem is that the menu appear on different positions randomly and i want the position to be fix in relation to the command button.

image

Hello,

As per the original sample, if you use this code:

window.dundas.context.getService("ContextMenuService").showContextMenu(commands, e.originalEvent);

It shows up where you left click on the button. If you want to have it show up always at the bottom left of the button, then you could use something like this (inside the button click action) to convert the coordinates and provide a canvas event args:

var coordinate = new dundas.controls.Coordinates(this.left, this.top + this.height, null, this.getService("CanvasService").canvas, null, this);

window.dundas.context.getService("ContextMenuService").showContextMenu(commands, e.originalEvent, {
    "getAdapter": function () {
      return this;
    }.bind(this),
   "coordinate": coordinate.convertCoordinateKind(dundas.controls.CoordinateKind.PAGE, null, this.getService("CanvasService").canvas.getVision().scale)

This code assumes it is not in a template cell.

Hi Terrence

Thanks for your feedback. The button is inside an element cell, so if implemented it will move the menu to the top left corner of the template cell. Can you pass the coordinates by specifying the button control coordinates elements instead?

Hi Terrence

This is what I did to dynamically position the menu context. The button have a relative position, so I use the container clientWidth to position the context in alignment with the client screen size as follow:

var layerAdapters = this.parentView.layerAdapters;
var layer = layerAdapters[2];
var screenWidth = layer.container.clientWidth;
var screenLeft = (screenWidth * this.left);

var coordinate = new dundas.controls.Coordinates(screenLeft,58, null, this.getService("CanvasSe

Hi Reynaldo,

I have provided a sample below that opens the Context Menu exactly on the position that is clicked, regardless of having template grid on the dashboard.

I have added the following script to the Click action of a button and that opens the context menu where it is clicked on the button, and then by choosing ‘PDF’ command, ‘Export To PDF’ panel will be displayed

Here is the JavaScript API that you may find it useful to get the context from an adapter:
https://www.dundas.com/support/api-docs/js/#API%20Reference/dundas/view/controls/ViewContainer/Methods/getContext.html?Highlight=viewContainer.getcontext

-------------------**********************-----------------------
window . saveClick = e . originalEvent ;

var viewContainer = new dundas . view . controls . ViewContainer ();

//Set the position of the context menu

var adapterContext = viewContainer . getContext ({

"position" : {

"e" : window . saveClick ,

"left" : window . saveClick . pageX ,

"top" : window . saveClick . pageY

},

});

var getCommands = this . getContextualCommands ( adapterContext );

//Create a command

var PDF = new dundas . Command (

{

id : dundas . Utility . createGuid (),

caption : ‘PDF’ ,

categoryName : ‘Custom Export’ ,

description : ‘Export to PDF’ ,

editModeOnly : false ,

action : function ()

{

var share = new dundas . controls . ExportDialog ( dundas . constants . STANDARD_PDF_EXPORT_PROVIDER_ID );

var sharePanel = share . show ();

}

})

//Add command to command list

getCommands . push ( PDF );

var contextMenuService = this . getService ( "ContextMenuService" );

//Show context menu including the command on the position defined

contextMenuService . showContextMenu ( getCommands , window . saveClick );

I hope that helps.

-----------------------------***********************----------------------------------

I hope that helps.

Hi Azar

Thanks so much for your feedback. The routine will position the cursor inside the template, however it will always position the contextMenu on different positions depending on where you are clicking inside the button that tigger the process.

My goal is to position the context menu right below the button. To do that I did the following:

var layerAdapters = this.parentView.layerAdapters;
var layer = layerAdapters[2];
var screenWidth = layer.container.clientWidth;
var screenLeft = (screenWidth * this.left);

var coordinate = new dundas.controls.Coordinates(screenLeft,58, null, this.getService(“CanvasService”).canvas, null, this);

The only problem I have is that I don’t know how to make the vertical position work in relation to the screen resolution just the same way I am calculating the horizontal position, relative to the object top, left %.

Hi Reynaldo,

I am sorry for the late reply. Unfortunately, there is no ready sample in this regard and I am working on it to provide you with a sample that works as you expect however, that may take a bit of time.

I will post the solution as soon as I have that ready.
Thank you for your patience.

Thanks so much Azar. I appreciate your help on this!

Rey

Hi Reynaldo,

Please find below two solutions to handle this.

The first solution works without script with all dashboard Re-size modes including Responsive with template grids.

The second solution is the scripts, which works with Template Grids but not in Responsive mode.

I hope you find them useful:

First solution – Using Layer, Rectangle and labels:

  1. You can create a new Layer, and then in the target cell of that layer, create a Rectangle which contains one or more labels, each representing one command, as shown below:

  2. Add the script on Click event of each label, so it does what they are supposed to do.

  3. Add ‘Change Layer’ Interaction to Click event of the labels as well, so it hides the layer containing the context menu after it is clicked:
    2

  4. In the Click action of your button, create a Change Layer Interaction, so it shows the layer once this is clicked,

  5. Hide This layer by default, by clicking on Eye icon as shown below:
    3

  6. Switch to View mode and test it with different screen sizes.

  7. Now, you may change properties of the Rectangle and Labels so it looks closer to a real Context Menu.

Second Solution (which works with Template Grid, but not in Responsive mode):

In the sample below, I have used Terrence’s sample code and some of your scripts to calculate the coordinates that the Context menu should be displayed.

This script is added to the Click action of a button that is placed in Cell 6 of a 3X3 template grid.
------------------------------------*********************************-------------------------------------------
debugger ;

// Calculate Coordinates (top and left)

var layerAdapters = this . parentView . layerAdapters ;

var layer = layerAdapters [ 0 ];

var screenWidth = layer . container . clientWidth ;

// Please change the templateCell index accordingly, (it should be the index of the cell that contains the button)

// Template cell index starts from 0 and is from left to right - top to bottom

var widthOfTemplateCell = this . parentView . templateCells [ 5 ]. width ;

var templateCellLeft = screenWidth ***** this . parentView . templateCells [ 5 ]. left ;

var screenLeft = (( screenWidth ***** widthOfTemplateCell ) ***** this . left ) + templateCellLeft ;

var heightOfTemplateCell = this . parentView . templateCells [ 5 ]. height ;

var screenHeight = layer . container . offsetHeight ;

var templateCellTop = screenHeight ***** this . parentView . templateCells [ 5 ]. top ;

var screenTop = (( screenHeight ***** heightOfTemplateCell ) ***** this . top ) + (( screenHeight ***** heightOfTemplateCell ) ***** this . height ) + templateCellTop ;

var coordinate = new dundas . controls . Coordinates ( screenLeft , screenTop , null , this . getService ( "CanvasService" ). canvas , null , this );

var commands = [];

// define new commands and push to the command

var parentMenuItem = new dundas . Command ({

caption : "Share" ,

categoryName : "Share" ,

action : function () {

// Do cool stuff here

}. bind ( this ),

subCommands : [

new dundas . Command ({

id : dundas . Utility . createGuid (),

caption : "PDF" ,

categoryName : "Export to PDF" ,

description : ‘Export to PDF’ ,

editModeOnly : false ,

action : function () {

var share = new dundas . controls . ExportDialog ( dundas . constants . STANDARD_PDF_EXPORT_PROVIDER_ID );

var sharePanel = share . show ();

}. bind ( this )

}),

]

});

commands . push ( parentMenuItem );

window . dundas . context . getService ( "ContextMenuService" ). showContextMenu ( commands , e . originalEvent , {

"getAdapter" : function () {

return this ;

}. bind ( this ),

"coordinate" : coordinate . convertCoordinateKind ( dundas . controls . CoordinateKind . PAGE , null , this . getService ( "CanvasService" ). canvas . getVision (). scale )});

----------------------------------------***********************----------------------------------------

I hope these help.