Select to view content in your preferred language

How to toggle/change selectability of a Feature layer?

5631
28
Jump to solution
11-02-2017 07:51 AM
JohnAdams
Occasional Contributor

Hello,

I'm creating a web map in which I will need to change/toggle the selectability of a Feature layer. Is there any way to do this? I've looked through the API for the FeatureLayer class but don't see anything like what I'm looking for:

FeatureLayer | API Reference | ArcGIS API for JavaScript 3.22 

I would expect to see something like "IsSelectable" or "Seletable" but don't see anything like it. In Server Manager there is also nothing to change the selectability of my service. Is it not possible to do this at all, or am I missing something?

Thanks

0 Kudos
28 Replies
JohnAdams
Occasional Contributor

I don't know how to insert code, stuff I tried here before was a mess

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

John,

   Here is a full sample showing how to handle this:

<!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>Measure Tool</title>
    <link rel="stylesheet" href="https://js.arcgis.com/3.22/esri/themes/calcite/dijit/calcite.css">
    <link rel="stylesheet" href="https://js.arcgis.com/3.22/esri/themes/calcite/esri/esri.css">
    <style>
      html,body {
        height:100%;
        width:100%;
        margin:0;
      }
      body {
        background-color:#FFF;
        overflow:hidden;
        font-family:"Trebuchet MS";
      }
      #map {
        border:solid 2px #808775;
        -moz-border-radius:4px;
        -webkit-border-radius:4px;
        border-radius:4px;
        margin:5px;
        padding:0px;
      }
      #titlePane{
        width:280px;
      }
      </style>
      <script src="https://js.arcgis.com/3.22/"></script>
    <script>
    var map, mapClickEvt;
    require([
        "dojo/dom",
        "esri/Color",
        "dojo/keys",
        "dojo/parser",
        "dojo/on",
        "dojo/aspect",
        "dojo/_base/lang",

        "esri/config",
        "esri/sniff",
        "esri/map",
        "esri/SnappingManager",
        "esri/dijit/Measurement",
        "esri/layers/FeatureLayer",
        "esri/renderers/SimpleRenderer",
        "esri/tasks/GeometryService",
        "esri/symbols/SimpleLineSymbol",
        "esri/symbols/SimpleFillSymbol",

        "esri/dijit/Scalebar",
        "dijit/layout/BorderContainer",
        "dijit/layout/ContentPane",
        "dijit/TitlePane",
        "dijit/form/CheckBox",
        "dojo/domReady!"
      ], function(
        dom, Color, keys, parser, on, aspect, lang,
        esriConfig, has, Map, SnappingManager, Measurement, FeatureLayer, SimpleRenderer, GeometryService, SimpleLineSymbol, SimpleFillSymbol
      ) {
        parser.parse();
        //This sample may require a proxy page to handle communications with the ArcGIS Server services. You will need to
        //replace the url below with the location of a proxy on your machine. See the 'Using the proxy page' help topic
        //for details on setting up a proxy page.
        esriConfig.defaults.io.proxyUrl = "/proxy/";
        esriConfig.defaults.io.alwaysUseProxy = false;

        //This service is for development and testing purposes only. We recommend that you create your own geometry service for use within your applications
        esriConfig.defaults.geometryService = new GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");

        map = new Map("map", {
          basemap: "satellite",
          center: [-85.743, 38.256],
          zoom: 17
        });

        var sfs = new SimpleFillSymbol(
          "solid",
          new SimpleLineSymbol("solid", new Color([195, 176, 23]), 2),
          null
        );

        var parcelsLayer = new FeatureLayer("https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Louisville/LOJIC_LandRecords_Louisville/...", {
          mode: FeatureLayer.MODE_ONDEMAND,
          outFields: ["*"]
        });
        parcelsLayer.setRenderer(new SimpleRenderer(sfs));
        map.addLayers([parcelsLayer]);
        mapClickEvt = on.pausable(map, "click", mapClickEvtHandler);
        
        function mapClickEvtHandler(evt){
          console.info("map click");
        }

        //dojo.keys.copyKey maps to CTRL on windows and Cmd on Mac., but has wrong code for Chrome on Mac
        var snapManager = map.enableSnapping({
          snapKey: has("mac") ? keys.META : keys.CTRL
        });
        var layerInfos = [{
          layer: parcelsLayer
        }];
        snapManager.setLayerInfos(layerInfos);

        var measurement = new Measurement({
          map: map
        }, dom.byId("measurementDiv"));
        measurement.startup();
        
        aspect.after(measurement, 'setTool', lang.hitch(this, function() {
          if (measurement.activeTool) {
            mapClickEvt.pause();
          } else {
            mapClickEvt.resume();
          }
        }));
      });
    </script>
  </head>

  <body class="calcite">
    <div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline',gutters:false"
    style="width:100%; height:100%;">
      <div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'">
        <div style="position:absolute; right:20px; top:10px; z-Index:999;">
          <div id="titlePane" data-dojo-type="dijit/TitlePane" data-dojo-props="title:'Measurement', closable:false">
            <div id="measurementDiv"></div>
            <span style="font-size:smaller;padding:5px 5px;">Press <b>CTRL</b> to enable snapping.</span>
          </div>
        </div>
      </div>
    </div>
  </body>
</html>
0 Kudos
JohnAdams
Occasional Contributor

Here is my code. I'll have to get back to you tomorrow.

0 Kudos
JohnAdams
Occasional Contributor

Just running your code quickly, I noticed you don't have the parcel layer selectable. That's what's creating my problem, is the interaction between the clicking on a parcel and the clicking on the map to draw a measurement.

Anyway I'll be back tomorrow. Run my code and you'll see my issue.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

John,

   Here is your code with lots of corrections, removal of mixed coding styles (AMD mixed with Legacy), fixes to remove scrollbars due to map being to big with header height, function outside of main code block have been moved inside, draggable panel will not drag (now) when trying to click measure widget, proper functioning of measure and identify.

0 Kudos
JohnAdams
Occasional Contributor

Thanks ... except that I can barely get it to run. Most of it doesn't even show up, let alone work. In IE it just hangs there and never even shows up at all.

One thing I noticed you did was change the Javascript API from 3.14 to 3.22. Unfortunately, that's a big no-no for me. Some of the things I'm using I can't get to work on anything above 3.14. Trust me, I've tried. Don't know why. It might have something to do with the security settings on my network, but I'm not sure.

I plugged your "aspect.after..." function into my code. Didn't work. When I click on my map it still selects an underlying parcel.

Your cleargraphics implementation was nice, but it only worked when I placed it outside the require function into a standard function like thus:

function cleargraphics()
{

measurement.setTool(measurement.activeTool, false);
measurement.clearResult();
handler.resume();

}

It does a nice job of re-setting the tool, which is one of the things I was looking for. Thanks!

All the other stuff that I put outside the require function I've put there because it doesn't work inside the require function. Trust me, I've been through all that.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

John,

  Well you have to trust me that I have decades of development experience and I have it working fine on my end.

Here is a link with your site hosted on my side with all my code changes working fine in IE11, Chrome and Firefox.

Jackson County Parcel Viewer 

I will take it down as soon as you test it.

What version of IE are you using?

As far as functions inside or outside the main code block all depends on how the function is declared. You will see in my code change that they are globally declared and then the function signature looks like:

xyz = function(){

  //do something

};

vs

function xyz(){

  //do something

}

That makes all the difference.

What portion of the code is not working with the API 3.15 or above?..

0 Kudos
JohnAdams
Occasional Contributor

Thanks. I seem to have come across a solution that does what I want it to do. I have:

measurement.on("tool-change", disablepopup);
function disablepopup()
{
     handler.pause();
}

And ...

measurement.on("measure-end", enablepopup);
function enablepopup()
{
     measurement.setTool(measurement.activeTool, false);
     handler.resume();
}

This makes it so that when the user clicks on one of the tools, the handler is paused. Then - and this is important - once they're done drawing the measurement, the tool is re-set and the handler is resumed. The reason I want this is because I'm assuming the typical user might want to immediately start selecting parcels again after they've made a measurement without having to press any other buttons. So the flow would be:

1. Click measure tool

2. Make measurment

3. OK to click on parcel

If they want to make another measurement right after they made the first one, *then* they'll have to press one of the measure buttons again, but I don't consider that to be a big deal. Once the user sees the measure tool button not depressed anymore, they'll automatically go and re-press it if they want to. So the flow would be:

1. Click measure tool

2. Make measurement

3. Click measure tool

4. Make measurement

5. Etc., or OK to click on parcel, too

The Clear Graphics button is basically the same thing as the "measure-end" handler, except that it also clears the graphics. I figured out you need to put ClearResult() before you re-set the tool, otherwise the ClearResult() doesn't work:

function cleargraphics()
{
    measurement.clearResult();
    measurement.setTool(measurement.activeTool, false);
    handler.resume();
}

I'm using IE 11.

Your implementation worked on your host there, I don't know why it doesn't work on my computer, but I've been dealing with that sort of thing ever since I started this job, so I'm used to it. As I said, I think it might be a network security issue. This would explain why it worked when you hosted it but not when I tried to run your code on my local machine. I think our network folks have things set up in everybody's localhost pretty restrictively, or something.

One thing that doesn't work with anything above 3.15 are my navigation tools and bookmarks. However, I like them the way I've got them there so I don't mind. There have been other things that don't work but I forget which ones off the top of my head.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Hmm.. Strange that your side is having those issues. But as you said it could be your network. Best of luck.

0 Kudos