I need to create a right click context menu for one of my graphics. I am using the example found at:
Display context menu | ArcGIS API for JavaScript
as an example.
In the code I am already using the GraphicsLayer.on("mouse-over", function(evt)) to set the infowindow for other graphics (not for the one that I need to set the context menu).
Can the GraphicsLayer listen to multiple triggers? Or do they need to be combined under a single instance of GL.on?
Thanks.
Solved! Go to Solution.
That was my first thought to follow the same logic as I set the infowindow after the graphic was created. However, I run into problems. I could not bind the context menu to the graphic that is in the GL.
When I read the On binding dijit/Menu to a graphic
I knew that it would not be as simple as it seems. That's why I am using the move out to bind the graphic.
Lefteris,
I actually set all my mouse event that deal with graphics on the GraphicsLayer.
on(gLayer, 'mouse-over', lang.hitch(this, this.onMouseOverGraphic));
Robert,
correct me if I am wrong. Based of what I am reading to have a right click menu, you have to bind the graphic to the menu. I tried doing in different ways (when you mouse over or when you create graphic) but nothing works.
For example, the code I posted in a previous post is quite simple, so I don't know why the bind is not working.
Thank you.
Lefteris,
You are correct the context menu has to be attached to the graphics node. So from the code snippet you shared I can not tell if you just made a mistake when where pasting the code to share here or if you actually have the mouse out event inside the mouse over event. Maybe you should post more of your code.
I am posting a simpler code that has the same components as the original file. The problem is to bind the menu to the polyline when I use a graphics layer. Here is the code and thank you!
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>My Map</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.13/esri/css/esri.css">
<style>
html, body, #map {
padding:0;
margin:0;
height:100%;
}
</style>
<script src="//js.arcgis.com/3.13/"></script>
<script>
require([
"esri/map",
"esri/geometry/Point",
"esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol",
"esri/graphic",
"esri/layers/GraphicsLayer",
"esri/geometry/Polyline",
"esri/SpatialReference",
"dojo/dom",
"dojo/on",
"dijit/Menu", "dijit/MenuItem",
"dijit/form/Button", "dijit/layout/BorderContainer", "dijit/layout/ContentPane",
"dojo/domReady!"
], function(
Map,
Point,
SimpleMarkerSymbol,
SimpleLineSymbol,
Graphic,
GraphicsLayer,
Polyline,
SpatialReference,
dom,
on,
Menu, MenuItem
)
{
myMap = new Map("map", {
basemap: "streets",
center: [-122.16,37.7238],
zoom: 15,
SpatialReference: 102100
});
myMap.on("load", init);
function init()
{
var point1 = new Point(-122.159, 37.724, myMap.SpatialReference);
var point2 = new Point(-122.169, 37.721, myMap.SpatialReference);
var line = new Polyline(myMap.SpatialReference);
var gL = new GraphicsLayer();
line.addPath([point1, point2]);
var lineSymbol = new SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255,0,0,0.5]),4);
var pointSymbol = new SimpleMarkerSymbol().setColor(new dojo.Color([255,0,0, 0.5]));
myGraphicMarker = new Graphic(point1, pointSymbol);
myGraphicMarker2 = new Graphic(point2, pointSymbol);
myGraphicMarker.setAttributes({"name":"Begin"});
myGraphicMarker2.setAttributes({"name":"End"});
gra = new Graphic(line, lineSymbol);
gra.setAttributes({"name":"Project"});
gra.menu = new Menu({});
gra.menu.addChild(new MenuItem({
label: "Test",
onClick: function() {
alert("Testing menu");
}
}));
gL.add(myGraphicMarker);
gL.add(myGraphicMarker2);
gL.add(gra);
myMap.addLayer(gL);
on(gL, 'mouse-over', function(evt) {
if (evt.graphic.attributes.name === "Project") {
evt.graphic.menu.bindDomNode(evt.graphic.getDojoShape().getNode());
};
});
on(gL, 'mouse-out', function(evt) {
if (evt.graphic.attributes.name === "Project") {
evt.graphic.menu.unBindDomNode(evt.graphic.getDojoShape().getNode());
}
});
}
});
</script>
</head>
<body>
<div id="map" class="map">
</div>
</body>
</html>
Lefteris,
OK, Here is your sample code corrected:
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"> <title>My Map</title> <link rel="stylesheet" href= "http://js.arcgis.com/3.14/dijit/themes/claro/claro.css"> <link rel="stylesheet" href="http://js.arcgis.com/3.14/esri/css/esri.css"> <style> html, body, html, body, #map { height:100%; margin: 0; padding: 0; width:100%; overflow:hidden; } </style> <script src="http://js.arcgis.com/3.14/"></script> <script> var myMap, ctxMenuForGraphics; require([ "esri/map", "esri/geometry/Point", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/graphic", "esri/layers/GraphicsLayer", "esri/geometry/Polyline", "esri/SpatialReference", "dojo/dom", "dojo/on", "dijit/Menu", "dijit/MenuItem", "dojo/domReady!" ], function ( Map, Point, SimpleMarkerSymbol, SimpleLineSymbol, Graphic, GraphicsLayer, Polyline, SpatialReference, dom, on, Menu, MenuItem ) { myMap = new Map("map", { basemap: "streets", center: [-122.16, 37.7238], zoom: 15, SpatialReference: 102100 }); myMap.on("load", init); function init() { var point1 = new Point(-122.159, 37.724, myMap.SpatialReference); var point2 = new Point(-122.169, 37.721, myMap.SpatialReference); var line = new Polyline(myMap.SpatialReference); var gL = new GraphicsLayer(); line.addPath([point1, point2]); var lineSymbol = new SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0, 0.5]), 4); var pointSymbol = new SimpleMarkerSymbol().setColor(new dojo.Color([255, 0, 0, 0.5])); myGraphicMarker = new Graphic(point1, pointSymbol,{ "name": "Begin"}); myGraphicMarker2 = new Graphic(point2, pointSymbol, {"name": "End"}); gra = new Graphic(line, lineSymbol, {"name": "Project"}); ctxMenuForGraphics = new Menu({}); ctxMenuForGraphics.addChild(new MenuItem({ label: "Test", onClick: function () { alert("Testing menu"); } })); ctxMenuForGraphics.addChild(new MenuItem({ label: "Test 2", onClick: function () { alert("Testing menu 2"); } })); ctxMenuForGraphics.startup(); gL.add(myGraphicMarker); gL.add(myGraphicMarker2); gL.add(gra); myMap.addLayer(gL); on(gL, 'mouse-over', function (evt) { if (evt.graphic.attributes.name === "Project") { ctxMenuForGraphics.bindDomNode(evt.graphic.getDojoShape().getNode()); }; }); on(gL, 'mouse-out', function (evt) { if (evt.graphic.attributes.name === "Project") { ctxMenuForGraphics.unBindDomNode(evt.graphic.getDojoShape().getNode()); } }); } }); </script> </head> <body class="claro" style="font-size: 0.75em;"> <div id="map" class="map"></div> </body> </html>
Thank you. I can't believe that I spent so much time only to realize that the stylesheet was missing. This is why I mentioned in my previous post that the map "jerks" when you right click. I didn't notice that the menu was actually showing up using the original version of code, but at the bottom left of the screen right under the map!!
A simple fix but a valuable lesson.