Modify NearMe Widget to Intercept map click

1022
4
Jump to solution
06-27-2019 07:14 AM
MichaelKohler
Occasional Contributor II

I am using the NearMe widget to allow user to search for an address, owner name or parcel id to select a parcel and buffer 1000'. The widget then shows the community residential homes within the buffer. No problem.

When the widget is active, the user can click on the map and a circular buffer will be created and used. Currently, I just disabled the on clicks stuff in the widget so the user doesn't have a chance to click on the map.

Most of the time, the user doesn't know the address, owner or parcel id right away. I wan't them to be able to click a parcel on the map and use that feature. We have to use the parcel polygon because the shape of the parcel is what the 1000' city ordinance is based upon, so the point isn't going to work.

I've identified the location in the widget code where there is an if:then to return the selectedFeature if the user clicked the map or if the user entered an address, name or parcel id. I'm trying to intercept the portion where the user clicked the map and select the feature from the parcel layer and return that instead. However, the deferred, promise deal is causing some headaches for me. No matter what, the _getSelectedFeatureFromResult returns nothing to the _initWorkflow function when the user clicks the map.

Any ideas would be helpful

  /**
  * Set the selected feature from results
  * @memberOf widgets/NearMe/Widget
  **/
  _getSelectedFeatureFromResult:  function (evt) {
    var selectedFeature;
    if (evt) {
      if (evt.feature) {
        //selectedFeature = evt.feature;
        deferred = new Deferred();
        var pfl = this.map.getLayer("ParcelWeb_2552");
        var query = new Query();
        query.geometry = evt.feature.geometry;

        pfl.selectFeatures(query,FeatureLayer.SELECTION_NEW).then(lang.hitch(this, function (results) {
          if (results && results.length > 0) {
            deferred.resolve(results);
          } else {
            deferred.resolve([]);
          }
        }), lang.hitch(this, function () {
          deferred.resolve([]);
        }));
        return deferred.promise;

      } else if (evt.result && evt.result.feature) {
        selectedFeature = evt.result.feature;
        return evt.result.feature;
      }
    }
    //return selectedFeature;
  },‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

.

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Michael,

  Sorry for steering you wrong earlier. Here is what you need.

    _initWorkflow: function (evt, attribteSearchResult) {
      var selectedFeature, horzontalSliderNode;
      //clear previous results
      //If showing results of attributeSearch pass false to hide infowindow else pass true
      this._clearResults(!attribteSearchResult);
      this._doAttributeSearchOn = [];
      //get selected feature
      this._getSelectedFeatureFromResult(evt).then(lang.hitch(this, function (selectedFeature) {
        //store the current params which can be used if filters are applied later on
        this._prevAttributeSearchResult = lang.clone(attribteSearchResult);
        this._prevFeature = {
          "feature": selectedFeature,
          "isFeatureFromMapClick": selectedFeature ? evt.isFeatureFromMapClick : false
        };
        this._searchedLocation = selectedFeature;
        if (evt && evt.source && evt.source.zoomScale) {
          this._prevFeature.zoomScale = evt.source.zoomScale;
        }
        //if feature is form map click show the reverse geocoded address
        if (evt && this._locatorInstance && evt.isFeatureFromMapClick && this._searchedLocation &&
          this._searchedLocation.geometry) {
          this.showReverseGeocodedAddress();
        }
        //If selected feature is valid then init workflow to search
        //else if have valid attributeSearchList then display layers list accordingly
        if (selectedFeature && selectedFeature.geometry) {
          //show error message if no popup's are configured for any layers
          if (this._itemListObject.hasValidLayers()) {
            //show selected location on map
            this._highlightSelectedLocation(selectedFeature);
            //Check if horizontal slider is visible or not and display buffer only if slider is visible
            horzontalSliderNode = query(".esriCTSliderDiv", this.widgetMainNode);
            if (horzontalSliderNode && domClass.contains(horzontalSliderNode[0], "esriCTHidden")) {
              this.zoomToFeature();
              this._itemListObject.displayLayerList(this._searchedLocation, null);
            } else {
              // create buffer based on specified geometry
              this._createBuffer(selectedFeature.geometry);
            }
          } else {
            this._showMessage(this.nls.allPopupsDisabledMsg);
          }
        } else if (attribteSearchResult) {
          //show error message if no popup's are configured for any layers
          if (this._itemListObject.hasValidLayers()) {
            this._itemListObject.displayLayerList(null, null, attribteSearchResult);
          } else {
            this._showMessage(this.nls.allPopupsDisabledMsg);
          }
        }
      }));
    },
    _getSelectedFeatureFromResult: function (evt) {
      var selectedFeature = new Deferred();
      if (evt) {
        if (evt.feature) {
          if (evt.isFeatureFromMapClick) {
            var pfl = this.map.getLayer("ParcelWeb_2552");
            var query = new Query();
            query.geometry = evt.feature.geometry;
            pfl.selectFeatures(query, FeatureLayer.SELECTION_NEW).then(lang.hitch(this, function (results) {
              if (results && results.length > 0) {
                selectedFeature.resolve(results[0]);
              } else {
                selectedFeature.resolve(null);
              }
            }), lang.hitch(this, function () {
              selectedFeature.resolve(null);
            }));
          } else {
            selectedFeature.resolve(evt.feature);
          }
        } else if (evt.result && evt.result.feature) {
          selectedFeature.resolve(evt.result.feature);
        }
      }
      return selectedFeature;
    },‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

0 Kudos
4 Replies
RobertScheitlin__GISP
MVP Emeritus

Michael,

   Here is a way.

  _getSelectedFeatureFromResult:  function (evt) {
    if (evt) {
      if (evt.feature) {
        if(evt.isFeatureFromMapClick){
          var pfl = this.map.getLayer("ParcelWeb_2552");
          var query = new Query();
          query.geometry = evt.feature.geometry;
          pfl.selectFeatures(query, FeatureLayer.SELECTION_NEW).then(lang.hitch(this, function (results) {
            if (results && results.length > 0) {
              return results[0];
            } else {
              return null;
            }
          }), lang.hitch(this, function () {
            return null;
          }));
        } else {
          return evt.feature;
        }
      } else if (evt.result && evt.result.feature) {
        return evt.result.feature;
      }
    }
  },‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
MichaelKohler
Occasional Contributor II

No luck. It still returns nothing to the _initWorkflow function. I put a breakpoint on line 16 below after the function is called selectedFeature is always nothing when I click the map.

  /**
    * This function initialize the search widget
    * @memberOf widgets/NearMe/Widget
    */
    _initWorkflow:  function (evt, attribteSearchResult) {
      console.log('_initWorkflow');
      var selectedFeature, horzontalSliderNode;
      //clear previous results
      //If showing results of attributeSearch pass false to hide infowindow else pass true
      this._clearResults(!attribteSearchResult);
      this._doAttributeSearchOn = [];
      //get selected feature
      selectedFeature = this._getSelectedFeatureFromResult(evt);

      //store the current params which can be used if filters are applied later on
      this._prevAttributeSearchResult = lang.clone(attribteSearchResult);
      this._prevFeature = {
        "feature": selectedFeature,
        "isFeatureFromMapClick": selectedFeature ? evt.isFeatureFromMapClick : false
      };
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Michael,

  Sorry for steering you wrong earlier. Here is what you need.

    _initWorkflow: function (evt, attribteSearchResult) {
      var selectedFeature, horzontalSliderNode;
      //clear previous results
      //If showing results of attributeSearch pass false to hide infowindow else pass true
      this._clearResults(!attribteSearchResult);
      this._doAttributeSearchOn = [];
      //get selected feature
      this._getSelectedFeatureFromResult(evt).then(lang.hitch(this, function (selectedFeature) {
        //store the current params which can be used if filters are applied later on
        this._prevAttributeSearchResult = lang.clone(attribteSearchResult);
        this._prevFeature = {
          "feature": selectedFeature,
          "isFeatureFromMapClick": selectedFeature ? evt.isFeatureFromMapClick : false
        };
        this._searchedLocation = selectedFeature;
        if (evt && evt.source && evt.source.zoomScale) {
          this._prevFeature.zoomScale = evt.source.zoomScale;
        }
        //if feature is form map click show the reverse geocoded address
        if (evt && this._locatorInstance && evt.isFeatureFromMapClick && this._searchedLocation &&
          this._searchedLocation.geometry) {
          this.showReverseGeocodedAddress();
        }
        //If selected feature is valid then init workflow to search
        //else if have valid attributeSearchList then display layers list accordingly
        if (selectedFeature && selectedFeature.geometry) {
          //show error message if no popup's are configured for any layers
          if (this._itemListObject.hasValidLayers()) {
            //show selected location on map
            this._highlightSelectedLocation(selectedFeature);
            //Check if horizontal slider is visible or not and display buffer only if slider is visible
            horzontalSliderNode = query(".esriCTSliderDiv", this.widgetMainNode);
            if (horzontalSliderNode && domClass.contains(horzontalSliderNode[0], "esriCTHidden")) {
              this.zoomToFeature();
              this._itemListObject.displayLayerList(this._searchedLocation, null);
            } else {
              // create buffer based on specified geometry
              this._createBuffer(selectedFeature.geometry);
            }
          } else {
            this._showMessage(this.nls.allPopupsDisabledMsg);
          }
        } else if (attribteSearchResult) {
          //show error message if no popup's are configured for any layers
          if (this._itemListObject.hasValidLayers()) {
            this._itemListObject.displayLayerList(null, null, attribteSearchResult);
          } else {
            this._showMessage(this.nls.allPopupsDisabledMsg);
          }
        }
      }));
    },
    _getSelectedFeatureFromResult: function (evt) {
      var selectedFeature = new Deferred();
      if (evt) {
        if (evt.feature) {
          if (evt.isFeatureFromMapClick) {
            var pfl = this.map.getLayer("ParcelWeb_2552");
            var query = new Query();
            query.geometry = evt.feature.geometry;
            pfl.selectFeatures(query, FeatureLayer.SELECTION_NEW).then(lang.hitch(this, function (results) {
              if (results && results.length > 0) {
                selectedFeature.resolve(results[0]);
              } else {
                selectedFeature.resolve(null);
              }
            }), lang.hitch(this, function () {
              selectedFeature.resolve(null);
            }));
          } else {
            selectedFeature.resolve(evt.feature);
          }
        } else if (evt.result && evt.result.feature) {
          selectedFeature.resolve(evt.result.feature);
        }
      }
      return selectedFeature;
    },‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
MichaelKohler
Occasional Contributor II

Works great!

I was in chaining nightmare yesterday and couldn't see the forest through the trees. I've never seemed to have these problems when working with regular basic javascript apps.

Thank you so much for your presence here. There have been countless times where your answers to others have set me off in the right direction.

0 Kudos