turn view click on and off

1064
11
Jump to solution
05-08-2020 01:07 PM
jaykapalczynski
Frequent Contributor

I have a map that I want the user to interface with.  

Right now the below code works great but the map is ALWAYS active.

I need to be able to activate the clicks after a button is clicked.

Until the user clicks a button the viewright.on("click"......  is not enabled.

On page reload the button should have to be clicked again to register the clicks in the map

Any thoughts?

viewright.on("click", function (evt) {
    viewright.hitTest(evt.screenPoint).then(function (response) {
  
         // Do a bunch of stuff
   
    });

}‍‍‍‍‍);
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Esteemed Contributor

Correct. Just a small correction though.

let myBtn = document.getElementById("btn");            

myBtn.addEventListener("click", function(){
   if(mouseEvtHandler){
      mouseEvtHandler.remove();
      mouseEvtHandler = null;
   }else{
      mouseEvtHandler = view.on("click", eventHandler);
   }
});

eventHandler would be the function portion of your original post:

function eventHandler(evt){
  viewright.hitTest(evt.screenPoint).then(function (response) {
    // Do a bunch of stuff
  });‍‍‍
)

View solution in original post

0 Kudos
11 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Jay,

  So you would just add the on event listener in the on click event of a button then.

Here is an example of how to toggle view mouse events with a button:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>Access features with pointer events - 4.15</title>

    <style>
      html,
      body,
      #viewDiv {
        padding: 0;
        margin: 0;
        height: 100%;
        width: 100%;
      }

      #info {
        background-color: black;
        opacity: 0.75;
        color: orange;
        font-size: 18pt;
        padding: 8px;
        visibility: hidden;
      }
    </style>

    <link
      rel="stylesheet"
      href="https://js.arcgis.com/4.15/esri/themes/light/main.css"
    />
    <script src="https://js.arcgis.com/4.15/"></script>

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/FeatureLayer"
      ], function(Map, MapView, FeatureLayer) {
        const hurricanesLayer = new FeatureLayer({
          url:
            "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Hurricanes/MapServer/1",
          outFields: ["*"]
        });

        const map = new Map({
          basemap: "dark-gray",
          layers: [hurricanesLayer]
        });

        const view = new MapView({
          container: "viewDiv",
          map: map,
          center: [-61.125537, 35.863534],
          zoom: 4,
          highlightOptions: {
            color: "orange"
          }
        });
        
        let mouseEvtHandler;

        view.ui.add("info", "top-right");
        view.ui.add("btn", "bottom-right");

        view
          .when()
          .then(function() {
            
            return hurricanesLayer.when();
          })
          .then(function(layer) {
            const renderer = layer.renderer.clone();
            renderer.symbol.width = 4;
            renderer.symbol.color = [128, 128, 128, 0.8];
            layer.renderer = renderer;

            // Set up an event handler for pointer-down (mobile)
            // and pointer-move events (mouse)
            // and retrieve the screen x, y coordinates

            return view.whenLayerView(layer);
          })
          .then(function(layerView) {
            let myBtn = document.getElementById("btn");
            myBtn.addEventListener("click", function(){
              if(mouseEvtHandler){
                mouseEvtHandler.remove();
                mouseEvtHandler = null;
              }else{
                mouseEvtHandler = view.on("pointer-move", eventHandler);
              }
            });
            view.on("pointer-down", eventHandler);

            function eventHandler(event) {
              // the hitTest() checks to see if any graphics in the view
              // intersect the x, y coordinates of the pointer
              view.hitTest(event).then(getGraphics);
            }

            let highlight, currentYear, currentName;

            function getGraphics(response) {
              // the topmost graphic from the hurricanesLayer
              // and display select attribute values from the
              // graphic to the user
              if (response.results.length) {
                const graphic = response.results.filter(function(result) {
                  return result.graphic.layer === hurricanesLayer;
                })[0].graphic;

                const attributes = graphic.attributes;
                const category = attributes.CAT;
                const wind = attributes.WIND_KTS;
                const name = attributes.NAME;
                const year = attributes.YEAR;
                const id = attributes.OBJECTID;

                if (
                  highlight &&
                  (currentName !== name || currentYear !== year)
                ) {
                  highlight.remove();
                  highlight = null;
                  return;
                }

                if (highlight) {
                  return;
                }

                document.getElementById("info").style.visibility = "visible";
                document.getElementById("name").innerHTML = name;
                document.getElementById("category").innerHTML =
                  "Category " + category;
                document.getElementById("wind").innerHTML = wind + " kts";

                // highlight all features belonging to the same hurricane as the feature
                // returned from the hitTest
                const query = layerView.createQuery();
                query.where = "YEAR = " + year + " AND NAME = '" + name + "'";
                layerView.queryObjectIds(query).then(function(ids) {
                  if (highlight) {
                    highlight.remove();
                  }
                  highlight = layerView.highlight(ids);
                  currentYear = year;
                  currentName = name;
                });
              } else {
                // remove the highlight if no features are
                // returned from the hitTest
                if (highlight) {
                  highlight.remove();
                  highlight = null;
                }
                document.getElementById("info").style.visibility = "hidden";
              }
            }
          });
      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
    <div id="info">
      <span id="name"></span> <br />
      <span id="category"></span> <br />
      <span id="wind"></span>
    </div>
    <button id="btn">Toggle Mouse Events</button>
  </body>
</html>
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
jaykapalczynski
Frequent Contributor

It is my assumption that this solution forces the user to click the button and then click in the map.  

That if the user chooses to select a different feature they would have to click the button again and then select a feature in the map?  Or am I wrong?

The workflow I need is:

The map is inactive for selecting

Click a "Start" button to activate map clicks (multiple map clicks)

     The user can click as many times as they choose

After clicking a separate "submit" button (disable the ability to click the map until the "start" button is clicked)

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Jay,

It is my assumption that this solution forces the user to click the button and then click in the map.  

That if the user chooses to select a different feature they would have to click the button again and then select a feature in the map?  Or am I wrong?

In The sample above, yes you would have to click the button before the mouse move would start operating. But no you would not have to click the button again until you wanted to turn off the mouse move functionality.

If you want the app to have the mouse move (in the sample case) from the beginning then you just have to have this line again outside the button click event handler:

mouseEvtHandler = view.on("pointer-move", eventHandler);
0 Kudos
jaykapalczynski
Frequent Contributor

So if I am reading this correct 

Click the button....

If should allow the user to click

Click the button again and it should set the MouseEvtHandler to NOT allow a click.

Click the button again and it should allow the user to click....

let myBtn = document.getElementById("btn");            

myBtn.addEventListener("click", function(){
   if(mouseEvtHandler){
      mouseEvtHandler.remove();
      mouseEvtHandler = null;
   }else{
      mouseEvtHandler = view.on("pointer-down", eventHandler);
   }
});
0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Correct. Just a small correction though.

let myBtn = document.getElementById("btn");            

myBtn.addEventListener("click", function(){
   if(mouseEvtHandler){
      mouseEvtHandler.remove();
      mouseEvtHandler = null;
   }else{
      mouseEvtHandler = view.on("click", eventHandler);
   }
});

eventHandler would be the function portion of your original post:

function eventHandler(evt){
  viewright.hitTest(evt.screenPoint).then(function (response) {
    // Do a bunch of stuff
  });‍‍‍
)
0 Kudos
jaykapalczynski
Frequent Contributor

Yea I got that....just left that out.....THANKS

0 Kudos
jaykapalczynski
Frequent Contributor

Looking at it closer I think that is what I am after .... instead of converting to a mouse over or pointer-move I would need someway to cancel the map click ability...that is the part I am not sure of

This example seems to be active in both cases....click or hover...I need click not active at all.  I want to disable the ability to click after clicking a submit button ... Is there a specific code that disables a the view onClick?

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor
mouseEvtHandler = viewright.on("click", function (evt) {
...

and just like the sample.

if(mouseEvtHandler){
  mouseEvtHandler.remove();
  mouseEvtHandler = null;
}

To remove the click event handler

0 Kudos
jaykapalczynski
Frequent Contributor

I am doing this and never getting the alert "1" 

I get the "start" alert everytime which I should

I then get the "2" alert EVERY time....never the "1" alert

So that tells me its not setting the mouseEvtHandler to null....

Do I have something wrong?

<div id="select-by-Testing" style="height: 20px; width: 100%; padding: 10px 10px 10px 10px;" class="esri-widget esri-widget--button esri-widget esri-interactive" title="identify features">
       <span>Click Testing</span>
</div> 

        var mapright = new Map({
            basemap: "dark-gray",
            //: [countyLayerWebMercator]
            layers: [countyLayerWebMercator, resultsLayer3, resultsLayer2, resultsLayer4]   
        });
        var viewright = new MapView({
            container: "viewDivright",
            map: mapright,
            center: [-77.05, 37.53308],
            zoom: 7
        }); 


        let mouseEvtHandler;
        var selectButton2 = document.getElementById("select-by-Testing");
        selectButton2.addEventListener("click", function() {

            alert("start");

            if (mouseEvtHandler) {
                alert("1");
                mouseEvtHandler.remove();
                mouseEvtHandler = null;
            } else {
                alert("2");
                // mouseEvtHandler = viewright.on("click", eventHandler);
            }
        });
0 Kudos