AnsweredAssumed Answered

Search Widget Results - Not Cleared from infoWindow

Question asked by dcoley on Sep 3, 2015
Latest reply on Sep 4, 2015 by dcoley

So for the past 2 years or so we've been using our local point locator in the geocoder widget as a way to fire a query function that returns geometry and atttibute results from the task.  For example, when using a geocoder we tell the on select event to to fire a 'showLocation' function that takes the sr and geometry from the geocoded point, creates and sets a graphic point to the event, adds it to the map.   We then assign that geometry to a query that performs a select with whatever feature layer or layers we choose then pass the query results into the maps' infowindow (we use a modified side-panel popup instead of the defualt):

 

var locatorUrl = "https://ags2.scgov.net/arcgis/rest/services/WebPointLocator/GeocodeServer";
var scgGeocoder = [{
     url: locatorUrl,
     name: "WebPointLocator",
     singleLneFieldName: "Single Line Input",
     placeholder: "Find an Address"
}];
var geocoder = new Geocoder({
     map : mapMain,
     autoComplete : true,
     autoNavigate : false,
     arcgisGeocoder : false,
     geocoders : scgGeocoder

}, dom.byId("divSearch"));

function showLocation(event) {
     mapMain.graphics.clear();
     qPoint = event.result.feature.geometry;

     var ptSymbol = new SimpleMarkerSymbol().setStyle(
          SimpleMarkerSymbol.STYLE_SQUARE).setColor(
          new Color([255,0,0,0.5])
     );
     var graphicPoint = new Graphic(qPoint, ptSymbol);
     mapMain.graphics.add(graphicPoint);

     var queryParcels = new Query;
     queryParcels.geometry =  qPoint;

     var parQuery = lyrParcels.selectFeatures(queryParcels,FeatureLayer.SELECTION_NEW); //is a deferred
          mapMain.infoWindow.setFeatures([parQuery]); //comment out if passing query result to next function
          mapMain.infoWindow.show(qPoint); //comment out if passing query result to next function
//center
     if (qPoint !== undefined) {
          mapMain.centerAndZoom(qPoint, 13); //7 for sph
          mapMain.graphics.redraw();
     }
     lyrParcels.on("selection-complete", showZones);
}

 

Suppose we want to return not only the parcels geometery and attributes, but also the geometry and atributes from whatever

layers that parcel intersects. We simply comment out the infowindow and add an on selection-complete event for our parcels layer

and pass the reuslts into a second query function that uses the extent of the selected poly.  In this case we are using the parcel extent to return whatever floodzone(s) intersect:

 

function showZones(results) {
     qPoly = results.features[0].geometry;
     // results of first layer returned by point intersect query above
     console.log(qPoly);
     var queryNewZones = new Query;
     queryNewZones.geometry = qPoly.getExtent();
     //.getCenter(); if returning a grid poly
     var newFloodQuery = lyrNewZones.selectFeatures(queryNewZones, FeatureLayer.SELECTION_NEW);

     var queryNewFirm = new Query;
     queryNewFirm.geometry = qPoly.getExtent();
     //evt.result.feature.geometry;
     var newFirmQuery = lyrNewFirm.selectFeatures(queryNewFirm, FeatureLayer.SELECTION_NEW);
     //deferred evacQuery

     mapMain.infoWindow.setFeatures([parQuery, newFloodQuery, newFirmQuery]); //parQuery
     mapMain.infoWindow.show(qPoint);
     //show the parcel
     mapMain.infoWindow.show(qPoly);
     //show the zones - complete the loop
     lyrNewZones.on("selection-complete", returnNull);

}


function returnNull() {
     var retVal = null;
}

 

Pretty straightfoward (now - not initally!).  Here is a fully working app if you want to see it:

 

https://ags2.scgov.net/SarcoFlood/

you can use 1660 Ringling Blvd as the address.

 

Here is our problem:

We want to update this workflow to take advantage of the new search widget so that users can search not only by address but say also by a PID. Of course the search has different on events, but the main problem is that when using the feature layer source as the searchs' activeSource, the result from the first query is not cleared from our info window even though the first query's geometry and attributes are removed. Console logs do show that a new parcel has been selected.  The problem does not occur when the activeSource comes from our locator.

 

This is what @Michael Stranovsky and I have come up with so far:

 

/*Search */
var s = new Search({
     enableButtonMode: true, //this enables the search widget to display as a single button
     enableLabel: false,
     enableInfoWindow: true,
     showInfoWindowOnSelect: true,
     map: mapMain,
     sources: []
}, "divSearch"); 

var sources = s.get("sources");

sources.push({
     locator: new Locator("https://ags2.scgov.net/arcgis/rest/services/WebPointLocator/GeocodeServer"),
     singleLineFieldName: "Single Line Input", 
     name: "Search by Address",
     localSearchOptions: {
     minScale: 300000,
     distance: 10
     },
     placeholder: "Search by Address",
     maxResults: 3,
     maxSuggestions: 8,
     enableSuggestions: true,
     minCharacters: 0,
         
});

sources.push({
     featureLayer: lyrParcels,
     searchFields: ["ACCOUNT"],
     displayField: "ACCOUNT",
     exactMatch: false,
     outFields: ["ACCOUNT", "Shape_Area"],
     name: "Search by PID",
     placeholder: "ex: 2027070041",
     maxResults: 6,
     maxSuggestions: 6,
        
     //Create an InfoTemplate and include three fields
     infoTemplate: plyParcels, //defined previously
     enableSuggestions: false,
     minCharacters: 0
});
   
//Set the sources above to the search widget
s.set("sources", sources);
s.startup();

console.log(sources);
s.on("select-result", showZones);

 

In this case we use the searches' on select-result event to pass in the gemoetry but things get really complicated because we first havet to account for the activeSource - whether from a locator or a featureLayer - and the fact that the search widget is (1) already creating a point graphic if a locator source and (2) that the search is already performing a find and query tasks (I think).

 

Here, when the source is our parcel feature layer, we are essentially performing the query twice as the search is already performing it once.  When we tried setting the evt geometry to the extent of the return itself, the querys' default intersects method returned several parcels, so we set the return to get the center of the extent, and then perform both the parcel and intersecting layer query and display the results:

 

function showZones(evt) {
     //lyrParcels.clearSelection();   
     mapMain.infoWindow.clearFeatures();
     //mapMain.infoWindow.setFeatures([]);  
     //qPoint = null;  
     //qPoly = null;   
     //lyrParcels.clearSelection();
   
     if (s.activeSource.name == "Search by PID") {
          //console.log(evt);               
          qPoly = evt.result.feature.geometry;      
       ///qPoint = evt.result.extent.getCenter();
          //console.log("qPoint Parcel: ");            
          //console.log(qPoint);
   
          var queryParcels = new Query;
               queryParcels.geometry = qPoint;
          var parQuery = lyrParcels.selectFeatures(queryParcels, FeatureLayer.SELECTION_NEW);
               console.log(parQuery); 
           
         var queryNewZones = new Query;
              queryNewZones.geometry = qPoly.getExtent();
         var newFloodQuery = lyrNewZones.selectFeatures(queryNewZones, FeatureLayer.SELECTION_NEW);
               mapMain.infoWindow.setFeatures([parQuery, newFloodQuery]);
               mapMain.infoWindow.show(qPoly);  
               //console.log(lyrParcels.getSelectedFeatures());
               //console.log(results);
     } else if (s.activeSource.name == "Search by Address") {
          //console.log(evt);
          qPoint = evt.result.feature.geometry;
           //console.log("qPoint Address: ");
           //console.log(qPoint);
          var queryParcels = new Query;
                queryParcels.geometry = qPoint;
          var addQuery = lyrParcels.selectFeatures(queryParcels, FeatureLayer.SELECTION_NEW);
               console.log(addQuery);            
          /*parQuery.then(function(features){
               console.log("select features result: ", features);
               qPoly = features[0].geometry;
               console.log(qPoly);
          });*/
     //var qPoly = lyrParcels.on("selection-complete", getParcelExtent);
     //console.log(qPoly):                    
    lyrParcels.on("selection-complete", function (result){
        qPoly = result.features[0].geometry;
        var queryNewZones = new Query;
        queryNewZones.geometry = qPoly;     
         var newFloodQuery = lyrNewZones.selectFeatures(queryNewZones, FeatureLayer.SELECTION_NEW);
         
     mapMain.infoWindow.setFeatures([addQuery, newFloodQuery]);
     mapMain.infoWindow.show(qPoly); //previous addQuery
     });

     //var queryNewZones = new Query;        
     //queryNewZones.geometry = pPoly    
     //var newFloodQuery = lyrNewZones.selectFeatures(queryNewZones, FeatureLayer.SELECTION_NEW);          
     //var addQ = [parQuery, newFloodQuery];
     //console.log(lyrParcels.getSelectedFeatures());
     //mapMain.infoWindow.setFeatures([parQuery, newFloodQuery]); 
     //newFloodQuery   
     //mapMain.infoWindow.show(qPoint);
     } else {
          console.log("In else");
     }     
}     

 

Again, the result from the first query is not cleared from our info window dispaly even though the first query's geometry and attributes are removed. Console logs do show that a new parcel has been selected.  The first-result of the parcel query and does clear from the infoWindow display when we enter an address and then enter a subsequent address.  The first-result does

This post is related to:

How can I use a variable that is set in a function on an on event outside of the event?

posted by @Michael Stranovsky just the other day in that he is trying to figure out if it is a scope issue that is preventing the infoWindow from clearing the displayed result-

 

Thanks-

David

Outcomes