Select to view content in your preferred language

context menu

5851
16
Jump to solution
07-20-2015 08:22 PM
LefterisKoumis
Frequent Contributor

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.

0 Kudos
16 Replies
LefterisKoumis
Frequent Contributor

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.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Lefteris,

  I actually set all my mouse event that deal with graphics on the GraphicsLayer.

on(gLayer, 'mouse-over', lang.hitch(this, this.onMouseOverGraphic));

LefterisKoumis
Frequent Contributor

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.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

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.

0 Kudos
LefterisKoumis
Frequent Contributor

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>

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

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>
LefterisKoumis
Frequent Contributor

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.

0 Kudos