Select to view content in your preferred language

How can I get the search widget to work again once I have destroyed and recreated a map?

2312
2
Jump to solution
05-06-2016 06:41 AM
SergioBoggio
Deactivated User

I am a GIS Specialist but a relative noob when it comes to JavaScript, so bear with me...

I am writing a script that allows users to choose between two different maps, using two different projections, by choosing between two radio buttons. When the user clicks on a radio button, the previous map is destroyed and a new one is created. I can get an on-click event to work on the new map, and I can get the scalebar to work on the new map. However, even though I can see the Search widget, and it does list addresses correctly, when I click on an address, nothing happens.

The refresh of the map is done like this:

map.destroy();

map = new Map("map", {extent: mapextent});

map.addLayer(baseMapLayer);

The scalebar code, which works, is

scalebar.destroy()

scalebar = new Scalebar({map: map, scalebarUnit: "dual"});

If I try the same with the Search widget...

search.destroy();

search = new Search({map: map}, "search");

search.startup();

...then the search isn't displayed at all. If I declare search as a new variable...

search.destroy();

var search = new Search({map: map}, "search");

search.startup();

...then I can see the search widget, and it will list results, but when I click on a result, nothing happens (i.e. no marker is placed on the map and the map doesn't zoom to the location. I would guess it is something to do with the search widget not recognising the new map object, but then why does the scalebar work?

Any help much appreciated.

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Sergio,

Here is a sample that shows how. The issue is that search.destroy() removed the whole search div from the dom.

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Home Extent</title>
  <link rel="stylesheet" href="https://js.arcgis.com/3.16/esri/themes/calcite/dijit/calcite.css">
  <link rel="stylesheet" href="https://js.arcgis.com/3.16/esri/themes/calcite/esri/esri.css">
  <style>
    html, body, #map {
      padding:0;
      margin:0;
      height:100%;
    }
    #search {
     display: block;
     position: absolute;
     z-index: 4;
     top: 20px;
     left: 74px;
    }
    h3 {
         margin: 0 0 5px 0;
         border-bottom: 1px solid #444;
      }
      .shadow {
         box-shadow: 0 0 5px #888;
      }
      #feedback {
         background: #fff;
         color: #444;
         position: absolute;
         font-family: arial;
         height: 300px;
         right: 30px;
         margin: 5px;
         padding: 10px;
         top: 30px;
         width: 300px;
         z-index: 40;
      }
  </style>
  <script src="//js.arcgis.com/3.16/"></script>
  <script>
    var map, search, scalebar;
    require([
      "esri/map",
      "esri/dijit/Search",
      "esri/dijit/Scalebar",
      "dojo/parser",
      "dijit/registry",
      "esri/layers/ArcGISDynamicMapServiceLayer",
      "esri/geometry/Extent",
      "dojo/_base/lang",
      "dojo/on",
      "dojo/dom-construct",
      "dijit/layout/BorderContainer",
      "dijit/layout/ContentPane",
      "dijit/form/RadioButton",
      "dojo/domReady!"
    ], function(
      Map, Search, Scalebar, parser, registry, ArcGISDynamicMapServiceLayer, Extent, lang, on, domConstruct
    )  {
      parser.parse();
      map = new Map("map", {
        center: [-56.049, 38.485],
        zoom: 3,
        basemap: "streets"
      });

      search = new Search({
        map: map
      }, "search");
      search.startup();

      scalebar = new Scalebar({
        map: map,
        // "dual" displays both miles and kilometers
        // "english" is the default, which displays miles
        // use "metric" for kilometers
        scalebarUnit: "dual"
      });

      registry.byId("radioOne").on("change", function(isChecked){
  if(isChecked){
          search.destroy();
          scalebar.destroy();
          map.destroy();
          map = new Map("map", {
            center: [-56.049, 38.485],
            zoom: 3,
            basemap: "streets"
          });
          on(map, "load", lang.hitch(this, function(){
            scalebar = new Scalebar({map: map, scalebarUnit: "dual"});


            domConstruct.create("div", {id: 'search'}, "map", "first");
            search = new Search({map: map}, "search");
            search.startup();
          }));
  }
  }, true);

      registry.byId("radioTwo").on("change", lang.hitch(this, function(isChecked){
  if(isChecked){
          search.destroy();
          scalebar.destroy();
          map.destroy();
          map = new Map("map", {
            extent: new Extent({xmin:-179.6191629086413,ymin:17.881242000418013,xmax:-65.2442340001989,ymax:71.40623536706858,spatialReference:{wkid:4269}})
          });
          var CensusLayer = new ArcGISDynamicMapServiceLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer", {
            "id": "Census data",
            "opacity": 0.75
          });
          map.addLayers([CensusLayer]);
          var loadEvt = on(map, "layers-add-result", lang.hitch(this, function(){
            scalebar = new Scalebar({map: map, scalebarUnit: "dual"});
            domConstruct.create("div", {id: 'search'}, "map", "first");
            search = new Search({map: map}, "search");
            search.startup();
            loadEvt.remove();
          }));
  }
  }, true));

    });
  </script>
</head>
<body class="calcite">
    <div data-dojo-type="dijit/layout/BorderContainer"
         data-dojo-props="design:'headline', gutters:false"
         style="width: 100%; height: 100%; margin: 0;">

      <div id="map"
           data-dojo-type="dijit/layout/ContentPane"
           data-dojo-props="region:'center'"
           style="overflow:hidden;">
         <div id="search"></div>
         <div id="feedback" class="shadow">
            <h3>Change Map</h3>
            <div id="info">
              <input type="radio" data-dojo-type="dijit/form/RadioButton" name="maps" id="radioOne" checked value="Streets"/> <label for="radioOne">Streets</label> <br />
              <input type="radio" data-dojo-type="dijit/form/RadioButton" name="maps" id="radioTwo" value="Census"/> <label for="radioTwo">Census Data</label> <br />
            </div>
         </div>
      </div>
    </div>
  </body>
</html>
</html>

View solution in original post

2 Replies
RobertScheitlin__GISP
MVP Emeritus

Sergio,

Here is a sample that shows how. The issue is that search.destroy() removed the whole search div from the dom.

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Home Extent</title>
  <link rel="stylesheet" href="https://js.arcgis.com/3.16/esri/themes/calcite/dijit/calcite.css">
  <link rel="stylesheet" href="https://js.arcgis.com/3.16/esri/themes/calcite/esri/esri.css">
  <style>
    html, body, #map {
      padding:0;
      margin:0;
      height:100%;
    }
    #search {
     display: block;
     position: absolute;
     z-index: 4;
     top: 20px;
     left: 74px;
    }
    h3 {
         margin: 0 0 5px 0;
         border-bottom: 1px solid #444;
      }
      .shadow {
         box-shadow: 0 0 5px #888;
      }
      #feedback {
         background: #fff;
         color: #444;
         position: absolute;
         font-family: arial;
         height: 300px;
         right: 30px;
         margin: 5px;
         padding: 10px;
         top: 30px;
         width: 300px;
         z-index: 40;
      }
  </style>
  <script src="//js.arcgis.com/3.16/"></script>
  <script>
    var map, search, scalebar;
    require([
      "esri/map",
      "esri/dijit/Search",
      "esri/dijit/Scalebar",
      "dojo/parser",
      "dijit/registry",
      "esri/layers/ArcGISDynamicMapServiceLayer",
      "esri/geometry/Extent",
      "dojo/_base/lang",
      "dojo/on",
      "dojo/dom-construct",
      "dijit/layout/BorderContainer",
      "dijit/layout/ContentPane",
      "dijit/form/RadioButton",
      "dojo/domReady!"
    ], function(
      Map, Search, Scalebar, parser, registry, ArcGISDynamicMapServiceLayer, Extent, lang, on, domConstruct
    )  {
      parser.parse();
      map = new Map("map", {
        center: [-56.049, 38.485],
        zoom: 3,
        basemap: "streets"
      });

      search = new Search({
        map: map
      }, "search");
      search.startup();

      scalebar = new Scalebar({
        map: map,
        // "dual" displays both miles and kilometers
        // "english" is the default, which displays miles
        // use "metric" for kilometers
        scalebarUnit: "dual"
      });

      registry.byId("radioOne").on("change", function(isChecked){
  if(isChecked){
          search.destroy();
          scalebar.destroy();
          map.destroy();
          map = new Map("map", {
            center: [-56.049, 38.485],
            zoom: 3,
            basemap: "streets"
          });
          on(map, "load", lang.hitch(this, function(){
            scalebar = new Scalebar({map: map, scalebarUnit: "dual"});


            domConstruct.create("div", {id: 'search'}, "map", "first");
            search = new Search({map: map}, "search");
            search.startup();
          }));
  }
  }, true);

      registry.byId("radioTwo").on("change", lang.hitch(this, function(isChecked){
  if(isChecked){
          search.destroy();
          scalebar.destroy();
          map.destroy();
          map = new Map("map", {
            extent: new Extent({xmin:-179.6191629086413,ymin:17.881242000418013,xmax:-65.2442340001989,ymax:71.40623536706858,spatialReference:{wkid:4269}})
          });
          var CensusLayer = new ArcGISDynamicMapServiceLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer", {
            "id": "Census data",
            "opacity": 0.75
          });
          map.addLayers([CensusLayer]);
          var loadEvt = on(map, "layers-add-result", lang.hitch(this, function(){
            scalebar = new Scalebar({map: map, scalebarUnit: "dual"});
            domConstruct.create("div", {id: 'search'}, "map", "first");
            search = new Search({map: map}, "search");
            search.startup();
            loadEvt.remove();
          }));
  }
  }, true));

    });
  </script>
</head>
<body class="calcite">
    <div data-dojo-type="dijit/layout/BorderContainer"
         data-dojo-props="design:'headline', gutters:false"
         style="width: 100%; height: 100%; margin: 0;">

      <div id="map"
           data-dojo-type="dijit/layout/ContentPane"
           data-dojo-props="region:'center'"
           style="overflow:hidden;">
         <div id="search"></div>
         <div id="feedback" class="shadow">
            <h3>Change Map</h3>
            <div id="info">
              <input type="radio" data-dojo-type="dijit/form/RadioButton" name="maps" id="radioOne" checked value="Streets"/> <label for="radioOne">Streets</label> <br />
              <input type="radio" data-dojo-type="dijit/form/RadioButton" name="maps" id="radioTwo" value="Census"/> <label for="radioTwo">Census Data</label> <br />
            </div>
         </div>
      </div>
    </div>
  </body>
</html>
</html>
SergioBoggio
Deactivated User

Hi Robert,

This is exactly what I needed. Thanks very much for your help!

Sergio

0 Kudos