Select to view content in your preferred language

toggle button to turn on/off feature layer selection

5887
10
Jump to solution
04-14-2014 03:45 AM
deleted-user-yA_w_FC9FKe5
Deactivated User
I'm using a buffer to summarize some data but it is currently linked to the map and I cannot turn it off or on.  I would like to be able to put this in a button but I am not sure how to clear out the selection.  I was going to try and use a toggle button to turn it on and off. 




    <script src="http://js.arcgis.com/3.8/"></script>
    <script>
      var map;
      require([
        "esri/map", "esri/layers/FeatureLayer",
        "esri/tasks/query", "esri/geometry/Circle",
        "esri/graphic", "esri/InfoTemplate", "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/renderers/SimpleRenderer",
        "esri/config", "dojo/_base/Color", "dojo/dom", "dojo/domReady!", "esri/dijit/LocateButton", "dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/TabContainer", "dijit/layout/AccordionContainer", "dijit/layout/ContentPane", "dijit/layout/AccordionPane"
      ], function(
        Map, FeatureLayer,
        Query, Circle,
        Graphic, InfoTemplate, SimpleMarkerSymbol,
        SimpleLineSymbol, SimpleFillSymbol, SimpleRenderer,
        esriConfig, Color, dom, LocateButton
      ) {

        map = new Map("mapDiv", {
          basemap: "streets",
          center: [-81.4004,28.5269],
          zoom: 12,
          slider: false
        });
       

         var featureLayer = new FeatureLayer("MyServiceLinkHere",{
          mode: FeatureLayer.MODE_SELECTION,
          //infoTemplate: new InfoTemplate("Tract: ${ID}", "${*}"),
          outFields: ["ID","SALES","MKTSHR","CUSTOMERS"]
        });

        // selection symbol used to draw the selected census block points within the buffer polygon
        var symbol = new SimpleMarkerSymbol(
          SimpleMarkerSymbol.STYLE_CIRCLE,
          12,
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_NULL,
            new Color([0, 0, 0, 0.9]),
            1
          ),
          new Color([0, 0, 0, 0.5])
        );
        featureLayer.setSelectionSymbol(symbol);
       
        //make unselected features invisible
        var nullSymbol = new SimpleMarkerSymbol().setSize(0);
        featureLayer.setRenderer(new SimpleRenderer(nullSymbol));
       
        map.addLayer(featureLayer);
       
        var circleSymb = new SimpleFillSymbol(
          SimpleFillSymbol.STYLE_NULL,
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_SHORTDASHDOTDOT,
            new Color([105, 105, 105]),
            2
          ), new Color([255, 255, 0, 0.25])
        );
        var circle;

        //when the map is clicked create a buffer around the click point of the specified distance.
        map.on("click", function(evt){
          circle = new Circle({
            center: evt.mapPoint,
            geodesic: true,
            radius: 5,
            radiusUnit: "esriMiles"

          });
          map.graphics.clear();
    

   var pointSymbol = new SimpleMarkerSymbol();       
  pointSymbol.setOutline = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([255, 0, 0]), 1);        pointSymbol.setSize(14);       
  pointSymbol.setColor(new Color([255, 0, 0, 0.80]));       
  var graphic2 = new Graphic(evt.mapPoint,pointSymbol);       
  map.graphics.add(graphic2);


          //map.infoWindow.hide();
          var graphic = new Graphic(circle, circleSymb);
          map.graphics.add(graphic);

          var query = new Query();
          query.geometry = circle.getExtent();
          //use a fast bounding box query. will only go to the server if bounding box is outside of the visible map
          featureLayer.queryFeatures(query, selectInBuffer);
        });



//---- start of message box information ------
        function selectInBuffer(response){
          var feature;
          var features = response.features;
          var inBuffer = [];
          //filter out features that are not actually in buffer, since we got all points in the buffer's bounding box
          for (var i = 0; i < features.length; i++) {
            feature = features;
            if(circle.contains(feature.geometry)){
              inBuffer.push(feature.attributes[featureLayer.objectIdField]);
            }
          }
          var query = new Query();
          query.objectIds = inBuffer;
          //use a fast objectIds selection query (should not need to go to the server)
          featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){
            var r = "";
            r = "<b><u>5 Mile Tract Summary:</u></b> <br><br> Sales:      " + sumSales(results) + "<br> Market Share:  " + sumMKTSHR(results) + "<br> Customers:  " + sumCustomers(results);
            dom.byId("messages").innerHTML = r;
          });
        }

       function sumCustomers(features) {
          var CustomersTotal = 0;
          for (var x = 0; x < features.length; x++) {
            CustomersTotal = CustomersTotal + features.attributes['CUSTOMERS'];
          }
          return CustomersTotal;
  }

       function sumMKTSHR(features) {
          var MKTSHRTotal = 0;
          for (var x = 0; x < features.length; x++) {
            MKTSHRTotal = MKTSHRTotal + features.attributes['MKTSHR'];
          }
          return MKTSHRTotal.toFixed(2);
  }

        function sumSales(features) {
          var salesTotal = 0;
          for (var x = 0; x < features.length; x++) {
            salesTotal = salesTotal + features.attributes['SALES'];
          }
          return salesTotal.toFixed(2);
        //});

//---- End of message box information ------    
  
  };
//}

      });
  
  
require(["dijit/form/ToggleButton", "dojo/domReady!"], function(ToggleButton){
    new ToggleButton({
        showLabel: true,
        onChange: function(val) {
            if (val) {
                this.function1();
            } else {
                this.function2();
            }
        },
        function1: function() {
            this.set('label', 'Stop Buffer Tool');  
            //alert("Start Function");
   document.getElementById("messages").style.display = 'block';
   selectInBuffer.activate();

        },
        function2: function() {
            this.set('label', 'Start Buffer Tool');
   document.getElementById("messages").style.display = 'none';
   map.graphics.clear();
   featureLayer.clearSelection();
   selectInBuffer.deactivate(); 
   //alert("Stop Function");

        },
        label: "Start Buffer Tool"
    }, "btnBuffer");
}); 
  
    </script>
  </head>

  <body>
  <div id="messages" display="none">
    5 Mile Buffer Report
</div>
    <button dojoType="dijit.form.Button" id="btnBuffer" onClick="featureLayer.clearSelection();">Testing</button>     
<button dojoType="dijit.form.Button" onClick="selectionToolbar.activate(esri.toolbars.Draw.EXTENT);">Select Fields</button>
   <button dojoType="dijit.form.Button" onClick="featureLayer.clearSelection();">Clear Points</button>

   <button dojoType="dijit.form.Button" onClick="map.graphics.clear();">Clear Buffer Circle</button>
         <div id="mapDiv"></div>
  

  
        
  </body>
</html>
0 Kudos
1 Solution

Accepted Solutions
JakeSkinner
Esri Esteemed Contributor
You may be missing some of the external resources.  Try copying the following:

<!DOCTYPE html> <html>   <head>     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">     <!--The viewport meta tag is used to improve the presentation and behavior of the samples        on iOS devices-->     <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">     <title>Select with feature layer</title>     <link rel="stylesheet" href="http://js.arcgis.com/3.9/js/dojo/dijit/themes/tundra/tundra.css">     <link rel="stylesheet" href="http://js.arcgis.com/3.9/js/esri/css/esri.css">     <style>       html, body, #mapDiv {         padding: 0;         margin: 0;         height: 100%;       }       #messages{         background-color: #fff;         box-shadow: 0 0 5px #888;         font-size: 1.1em;         max-width: 15em;         padding: 0.5em;         position: absolute;         right: 20px;         top: 20px;         z-index: 40;       }     </style>     <script src="http://js.arcgis.com/3.9/"></script>     <script>       var map;       require([         "esri/map", "esri/layers/FeatureLayer",          "dijit/form/ToggleButton",         "esri/tasks/query", "esri/geometry/Circle",         "esri/graphic", "esri/InfoTemplate", "esri/symbols/SimpleMarkerSymbol",         "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/renderers/SimpleRenderer",         "esri/config", "esri/Color", "dojo/parser", "dojo/dom", "dojo/on", "dojo/domReady!"       ], function(         Map, FeatureLayer,         ToggleButton,         Query, Circle,         Graphic, InfoTemplate, SimpleMarkerSymbol,         SimpleLineSymbol, SimpleFillSymbol, SimpleRenderer,         esriConfig, Color, parser, dom, on       ) {          esriConfig.defaults.io.proxyUrl = "/proxy";                  parser.parse();          map = new Map("mapDiv", {            basemap: "streets",           center: [-95.249, 38.954],           zoom: 14,           slider: false         });                  //add the census block points in on demand mode. Note that an info template has been defined so when          //selected features are clicked a popup window will appear displaying the content defined in the info template.         var featureLayer = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/0",{           infoTemplate: new InfoTemplate("Block: ${BLOCK}", "${*}"),           outFields: ["POP2000","HOUSEHOLDS","HSE_UNITS", "TRACT", "BLOCK"]         });          // selection symbol used to draw the selected census block points within the buffer polygon         var symbol = new SimpleMarkerSymbol(           SimpleMarkerSymbol.STYLE_CIRCLE,            12,            new SimpleLineSymbol(             SimpleLineSymbol.STYLE_NULL,              new Color([247, 34, 101, 0.9]),              1           ),           new Color([207, 34, 171, 0.5])         );         featureLayer.setSelectionSymbol(symbol);                   //make unselected features invisible         var nullSymbol = new SimpleMarkerSymbol().setSize(0);         featureLayer.setRenderer(new SimpleRenderer(nullSymbol));                  map.addLayer(featureLayer);                  var circleSymb = new SimpleFillSymbol(           SimpleFillSymbol.STYLE_NULL,           new SimpleLineSymbol(             SimpleLineSymbol.STYLE_SHORTDASHDOTDOT,             new Color([105, 105, 105]),             2           ), new Color([255, 255, 0, 0.25])         );         var circle;                           new ToggleButton({           showLabel: true,           onChange: function(val){                         if(val == true){               buffer = map.on("click", function(evt){                 circle = new Circle({                 center: evt.mapPoint,                 geodesic: true,                 radius: 1,                 radiusUnit: "esriMiles"               });               map.graphics.clear();               map.infoWindow.hide();               var graphic = new Graphic(circle, circleSymb);               map.graphics.add(graphic);                var query = new Query();               query.geometry = circle.getExtent();               //use a fast bounding box query. will only go to the server if bounding box is outside of the visible map               featureLayer.queryFeatures(query, selectInBuffer);             });             this.set('label', 'Clear Buffer');            }            else{             map.graphics.clear();             featureLayer.clearSelection();             buffer.remove();                          this.set('label', 'Create Buffer');            }           },           label: "Create Buffer"         }, "buffer");                           function selectInBuffer(response){           var feature;           var features = response.features;           var inBuffer = [];           //filter out features that are not actually in buffer, since we got all points in the buffer's bounding box           for (var i = 0; i < features.length; i++) {             feature = features;             if(circle.contains(feature.geometry)){               inBuffer.push(feature.attributes[featureLayer.objectIdField]);             }           }           var query = new Query();           query.objectIds = inBuffer;           //use a fast objectIds selection query (should not need to go to the server)           featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){             var totalPopulation = sumPopulation(results);             var r = "";             r = "<b>The total Census Block population within the buffer is <i>" + totalPopulation + "</i>.</b>";             dom.byId("messages").innerHTML = r;           });         }                  function sumPopulation(features) {           var popTotal = 0;           for (var x = 0; x < features.length; x++) {             popTotal = popTotal + features.attributes["POP2000"];           }           return popTotal;         }       });     </script>   </head>    <body>     <span id="messages">Click on the map to select census block points within 1 mile.</span>     <div id="mapDiv">       <button id="buffer"></button>     </div>   </body> </html>

View solution in original post

0 Kudos
10 Replies
TracySchloss
Honored Contributor
What are you trying to turn on/off, the buffer graphic?  Every map has one graphicLayer by default, but you can create and populate as many as you want.  https://developers.arcgis.com/javascript/jsapi/graphicslayer-amd.html  I think if you put the buffer graphic into a graphic layer you create, you'll have more control over the visibility.

Once your graphics are in a layer, rather than part of the map, you should be able to control them as layers, not graphics.  I use a this simple function that takes a layer name as an argument whenever I want to do something like this.  Then I put a click event on a button that passes the layer name to it. 

function toggleLayer (layerId) {
var layer = map.getLayer(layerId);
    if (layer.visible){
        layer.setVisibility(false);           
    }else{
        layer.setVisibility(true);
    }       
}
0 Kudos
deleted-user-yA_w_FC9FKe5
Deactivated User
Well what I am trying to do is the following:

On click of a toggle button turn on my buffer selection so when a user clicks the map they get the buffer and results.
On the next click of the toggle button clear out all results and turn off the buffer selection so that the onmap clicking is as normal. 

Basically I am trying to do is take this sample and put it in a button so that i can turn it on and off when needed so I can create other functionality that uses the onmap click event. 

https://developers.arcgis.com/javascript/jssamples/query_buffer.html
0 Kudos
TracySchloss
Honored Contributor
I think it would be helpful for you to read through this thread:
http://forums.arcgis.com/threads/105742-Combine-two-Examples-with-Buttons-to-activate-code?highlight...

You will probably end up need to set some sort of Boolean variable that you alternate between true/false to determine the status of whether you just clicked the buffer button or not.  You'll also have to manage your map click events.  This is discussed on this other thread.
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Here is an example you can build off of:

http://jsfiddle.net/UjK29/
0 Kudos
deleted-user-yA_w_FC9FKe5
Deactivated User
Here is an example you can build off of:

http://jsfiddle.net/UjK29/


Uh Yeah.  That is AWESOME! 

I'm going to play around with that but I noticed it is in three different pieces.  I'm pretty new to working with this.  I like that it is broken up like that as I would like to have my code set up where I call things from the main page to functions or widgets elsewhere kind of like the Flex API does.   How can I turn those pieces into a widget?  Is that difficult to do and call?
0 Kudos
JakeSkinner
Esri Esteemed Contributor
0 Kudos
deleted-user-yA_w_FC9FKe5
Deactivated User
Here is a helpful link about creating a widget:

https://developers.arcgis.com/javascript/jstutorials/intro_custom_dijit.html


thanks for all of the help.  I copied the source code and tried to run it and then tried copying the individual pieces but I am getting a wide variety of errors.  Works great in fiddle but not when I paste the code and try to use it.  Any ideas what might be the problem?  Does it work when you copy the view source code and paste it into an html page and try to use it?
0 Kudos
JakeSkinner
Esri Esteemed Contributor
You may be missing some of the external resources.  Try copying the following:

<!DOCTYPE html> <html>   <head>     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">     <!--The viewport meta tag is used to improve the presentation and behavior of the samples        on iOS devices-->     <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">     <title>Select with feature layer</title>     <link rel="stylesheet" href="http://js.arcgis.com/3.9/js/dojo/dijit/themes/tundra/tundra.css">     <link rel="stylesheet" href="http://js.arcgis.com/3.9/js/esri/css/esri.css">     <style>       html, body, #mapDiv {         padding: 0;         margin: 0;         height: 100%;       }       #messages{         background-color: #fff;         box-shadow: 0 0 5px #888;         font-size: 1.1em;         max-width: 15em;         padding: 0.5em;         position: absolute;         right: 20px;         top: 20px;         z-index: 40;       }     </style>     <script src="http://js.arcgis.com/3.9/"></script>     <script>       var map;       require([         "esri/map", "esri/layers/FeatureLayer",          "dijit/form/ToggleButton",         "esri/tasks/query", "esri/geometry/Circle",         "esri/graphic", "esri/InfoTemplate", "esri/symbols/SimpleMarkerSymbol",         "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/renderers/SimpleRenderer",         "esri/config", "esri/Color", "dojo/parser", "dojo/dom", "dojo/on", "dojo/domReady!"       ], function(         Map, FeatureLayer,         ToggleButton,         Query, Circle,         Graphic, InfoTemplate, SimpleMarkerSymbol,         SimpleLineSymbol, SimpleFillSymbol, SimpleRenderer,         esriConfig, Color, parser, dom, on       ) {          esriConfig.defaults.io.proxyUrl = "/proxy";                  parser.parse();          map = new Map("mapDiv", {            basemap: "streets",           center: [-95.249, 38.954],           zoom: 14,           slider: false         });                  //add the census block points in on demand mode. Note that an info template has been defined so when          //selected features are clicked a popup window will appear displaying the content defined in the info template.         var featureLayer = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/0",{           infoTemplate: new InfoTemplate("Block: ${BLOCK}", "${*}"),           outFields: ["POP2000","HOUSEHOLDS","HSE_UNITS", "TRACT", "BLOCK"]         });          // selection symbol used to draw the selected census block points within the buffer polygon         var symbol = new SimpleMarkerSymbol(           SimpleMarkerSymbol.STYLE_CIRCLE,            12,            new SimpleLineSymbol(             SimpleLineSymbol.STYLE_NULL,              new Color([247, 34, 101, 0.9]),              1           ),           new Color([207, 34, 171, 0.5])         );         featureLayer.setSelectionSymbol(symbol);                   //make unselected features invisible         var nullSymbol = new SimpleMarkerSymbol().setSize(0);         featureLayer.setRenderer(new SimpleRenderer(nullSymbol));                  map.addLayer(featureLayer);                  var circleSymb = new SimpleFillSymbol(           SimpleFillSymbol.STYLE_NULL,           new SimpleLineSymbol(             SimpleLineSymbol.STYLE_SHORTDASHDOTDOT,             new Color([105, 105, 105]),             2           ), new Color([255, 255, 0, 0.25])         );         var circle;                           new ToggleButton({           showLabel: true,           onChange: function(val){                         if(val == true){               buffer = map.on("click", function(evt){                 circle = new Circle({                 center: evt.mapPoint,                 geodesic: true,                 radius: 1,                 radiusUnit: "esriMiles"               });               map.graphics.clear();               map.infoWindow.hide();               var graphic = new Graphic(circle, circleSymb);               map.graphics.add(graphic);                var query = new Query();               query.geometry = circle.getExtent();               //use a fast bounding box query. will only go to the server if bounding box is outside of the visible map               featureLayer.queryFeatures(query, selectInBuffer);             });             this.set('label', 'Clear Buffer');            }            else{             map.graphics.clear();             featureLayer.clearSelection();             buffer.remove();                          this.set('label', 'Create Buffer');            }           },           label: "Create Buffer"         }, "buffer");                           function selectInBuffer(response){           var feature;           var features = response.features;           var inBuffer = [];           //filter out features that are not actually in buffer, since we got all points in the buffer's bounding box           for (var i = 0; i < features.length; i++) {             feature = features;             if(circle.contains(feature.geometry)){               inBuffer.push(feature.attributes[featureLayer.objectIdField]);             }           }           var query = new Query();           query.objectIds = inBuffer;           //use a fast objectIds selection query (should not need to go to the server)           featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){             var totalPopulation = sumPopulation(results);             var r = "";             r = "<b>The total Census Block population within the buffer is <i>" + totalPopulation + "</i>.</b>";             dom.byId("messages").innerHTML = r;           });         }                  function sumPopulation(features) {           var popTotal = 0;           for (var x = 0; x < features.length; x++) {             popTotal = popTotal + features.attributes["POP2000"];           }           return popTotal;         }       });     </script>   </head>    <body>     <span id="messages">Click on the map to select census block points within 1 mile.</span>     <div id="mapDiv">       <button id="buffer"></button>     </div>   </body> </html>
0 Kudos
deleted-user-yA_w_FC9FKe5
Deactivated User
I had a little bit of an issue because the Toggle Buton you created was called "buffer" and we had a string called "buffer" as well so it was getting confused.  Once I changed that booyah it worked.  Thank-you sooo much.  Now I need to read up on the link you sent me because I would really like to have these buttons in chuncks rather than all in one html file. 

I'm sure I will have issues with that.  Thanks for your help.  Will you be going to UC in July?
0 Kudos