DevEdition Wab - Search Widget JS Highlight Symbol: Changes from 2.7 through 2.11

4753
24
Jump to solution
11-29-2017 02:00 PM
DavidColey
Frequent Contributor

Hi all - this is in reference to the earlier post dealing with the same issue at 1.3 and 2.3:

Web AppBuilder 1.2 Search/Geocoder widget color/style question 

but thought I'd start a new thread because the changes in the Search widget's Widget.js code at 2.6 have rendered the earlier fix (that worked up through 2.5) when starting a new app in the 2.6 Developer edition

As in earlier 2.x versions, to change the default highlight symbol I add in the jsonUtils to the define function and alias:

define([
 'dojo/_base/declare',
 'dojo/_base/lang',
 'dojo/_base/array',
 'dojo/_base/html',
 'dojo/when',
 'dojo/on',
 'dojo/aspect',
 'dojo/query',
 'dojo/keys',
 'dojo/Deferred',
 'dojo/promise/all',
 'jimu/BaseWidget',
 'jimu/LayerInfos/LayerInfos',
 'jimu/utils',
 'esri/dijit/Search',
 'esri/tasks/locator',
 'esri/layers/FeatureLayer',
 'esri/InfoTemplate',
 'esri/lang',
 './utils',
 'esri/symbols/jsonUtils', //for highlight change
 'dojo/NodeList-dom'
 ],
 function(declare, lang, array, html, when, on, aspect, query, keys, Deferred, all,
 BaseWidget, LayerInfos, jimuUtils, Search, Locator,
 FeatureLayer, InfoTemplate, esriLang, utils, jsonUtils)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

On about line 330 in the code, I add the highlight symbol property to the convertedSource var inside the _convertConfig function:

var convertedSource = {
 featureLayer: flayer,
 outFields: ["*"],
 searchFields: fNames,
 displayField: source.displayField || "",
 exactMatch: !!source.exactMatch,
 name: jimuUtils.stripHTML(source.name || ""),
 placeholder: jimuUtils.stripHTML(source.placeholder || ""),
 maxSuggestions: source.maxSuggestions || 6,
 maxResults: source.maxResults || 6,
 zoomScale: source.zoomScale || 50000,
 infoTemplate: template,
 useMapExtent: !!source.searchInCurrentMapExtent,
 _featureLayerId: source.layerId,
 highlightSymbol: jsonUtils.fromJson(source.highlightSymbol) //to add highlight symbol from json
 };‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

the highlightSymbol is set for each of the layers in the config.json:

"highlightSymbol": {
 "color": [100,100,100,25],
    "outline": {
       "color": [102,0,204],
          "width": 5,"type": "esriSLS" , "style", "esriSLSSolid"
    },"type": "esriSFS" ,"style": "esriSFSSolid"}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

and returns my settings to me in the console.log, but still reverts to the default highlight color and thickness, regardless:

So what should be a thick purple outline comes back in the default setting.  I've gone through the code to try to find what would be preventing the earlier method from working but have not had success.  Here are the changes, the comments here are the esri developer's comments:

On about line 137, a new promise(?) and handler for the infoWindow is added, not present in earlier 2.x:

// attatch original feature layer's id.
 this.own(
 aspect.before(this.map.infoWindow, 'setFeatures', lang.hitch(this, '_attatchOriLayerId'))
 );
 // this.map.infoWindow has two different implementations (esri/dijit/Popup and esri/dijit/PopupMobile)
 // after screen size changed. map switch it automatically.
 // here make sure fun:setFeatures be binded
 this._mapInfoWindow_ = this.map.infoWindow;
 var _winResizeHandler = on(window, 'resize', lang.hitch(this, function() {
 if (this._mapInfoWindow_ !== this.map.infoWindow) {
 this.own(
 aspect.before(this.map.infoWindow, 'setFeatures', lang.hitch(this, '_attatchOriLayerId'))
 );
 _winResizeHandler.remove();
 }
 }));‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

at about line 182, a 'show,hide' on event that I previously used to persist a graphic on-screen after the infoWindow closes has been commented out (a separate behavior):

// this.own(
 // on(this.map.infoWindow, 'show,hide', lang.hitch(this, function() {
 // if (this.searchDijit &&
 // this.map.infoWindow.getSelectedFeature() ===
 // this.searchDijit.highlightGraphic) {
 // this.searchDijit.clearGraphics();
 // query('li', this.searchResultsNode).removeClass('result-item-selected');
 // }
 // }))
 // );‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The next changes begin on about line 677 as part of the _onSelectedSeachResult function:

// clear before select.
 this.searchDijit.clearGraphics();‍‍‍‍‍‍‍‍

Then more commented code as part of the _onSelectResult function at line 683:

_onSelectResult: function(e) {
 var result = e.result;
 if (!(result && result.name)) {
 return;
 }
 var dataSourceIndex = e.sourceIndex;
 var sourceResults = this.searchResults[dataSourceIndex];
 var dataIndex = 0;
 // var that = this;
// var getGraphics = function(layer, fid) {
 // var graphics = layer.graphics;
 // var gs = array.filter(graphics, function(g) {
 // return g.attributes[layer.objectIdField] === fid;
 // });
 // return gs;
 // };
 // var showPopupByFeatures = function(features) {
 // var location = null;
 // that.map.infoWindow.setFeatures(features);
 // if (features[0].geometry.type === "point") {
 // location = features[0].geometry;
 // } else {
 // location = features[0].geometry.getExtent().getCenter();
 // }
 // that.map.infoWindow.show(location, {
 // closetFirst: true
 // });
 // };‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

and again beginning at line 733:

// var layer = this.map.getLayer(e.source._featureLayerId);
// if (layer && this.config.showInfoWindowOnSelect) {
 // var gs = getGraphics(layer, e.result.feature.__attributes[layer.objectIdField]);
 // if (gs.length > 0) {
 // showPopupByFeatures(gs);
 // } else {
 // var handle = on(layer, 'update-end', lang.hitch(this, function() {
 // if (this.domNode) {
 // var gs = getGraphics(layer, e.result.feature.__attributes[layer.objectIdField]);
 // if (gs.length > 0) {
 // showPopupByFeatures(gs);
 // }
 // }
// if (handle && handle.remove) {
 // handle.remove();
 // }
 // }));
 // this.own(handle);
 // }
 // }
 // publish select result to other widgets‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Finally, I believe this new code at line 760 may be where the highlightSymbol graphic may be NOT drawing, but I can't be certain:

// hide the graphic in map's default graphiclayer.
 var _searchGL = this.searchDijit.graphicsLayer || this.map.graphics;
 _searchGL.graphics.forEach(lang.hitch(this,function(item) {
 if (item && lang.getObject("_wabProperties.referToFeatureLayerId", false, item)) {
 // this.searchDijit.clearGraphics();
 _searchGL.remove(item);
 }
 }));
 },
_attatchOriLayerId: function(fs) {
 // Summary: attatchOriLayerId _attatch original featureLayer's ID.
 // Condition:
 // 1. Search dijit of JSAPI create new graphic and add it to map's default graphicslayer
 // if no graphicslayer configured, map contains two same graphic at the same time.
 // 2. Attach original flayer's id as a property to graphic(map's default featurelayer),
 // WAB can create related records with .
// fs is an array, it's item could be 'esri.Graphic' or 'dojo.deferred'
if (fs && fs.length && fs[0].declaredClass === "esri.Graphic" &&
 esriLang.isDefined(this._currentSelectSourceIdx)) {
 // iterator every item
 fs.forEach(lang.hitch(this, function(item) {
 // only type 'esri.Graphic'
 if (item.declaredClass === "esri.Graphic") {
 // original featurelayer id
 var _featureLayerId = this.searchDijit.sources[this._currentSelectSourceIdx]._featureLayerId;
 // get original featurelayer if exists.
 var layer = _featureLayerId && this.layerInfosObj.getLayerInfoById(_featureLayerId);
 // if original featurelayer added to map
 if (layer && this.config.showInfoWindowOnSelect) {
 // attatch original featurelayer's ID to this feature
 lang.setObject("_wabProperties.referToFeatureLayerId", _featureLayerId, item);
 }
 }
 }));
 }
 },‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

So if anyone has any suggestions as to where I can add/remove or otherwise comment code in order to be able to draw a custom highlight upon a result selection that would certainly help, because I just can't see it. 

As an fyi I did not see any other changes to any other js or json files contained with the Search.  The only changes appear to be in the Widget.js

Thanks,

David

Tags (1)
0 Kudos
24 Replies
KyleSchwizer
New Contributor III

Great! Thanks for updating this post David! 

0 Kudos
DavidColey
Frequent Contributor

Certainly,  If you can figure out what not to comment out so the popup highlight is not affected (from just a regular click) please let me know.  Of course I'll still keep at it myself . . . 

0 Kudos
DavidColey
Frequent Contributor

Ok so I figured it out.  If you want the standard popup highlight behavior, just make sure you comment out this section as before at 2.10:

//Insert below lines
              if (source.highlightSymbol) {
                convertedSource.highlightSymbol = jsonUtils.fromJson(source.highlightSymbol);
                //this.map.infoWindow.fillSymbol = jsonUtils.fromJson(source.highlightSymbol);
              }

along with the section I noted earlier.

0 Kudos
AdamGebhart
Occasional Contributor III

I am working in WAB 2.12 and thought I would put in one post all of the steps needed to accomplish the symbology update (or what works for me) based on the previous posts.  Thank you to everybody who has helped.

First though, click and vote up this ArcGIS Idea that Greg Bazhaw‌ posted to ask ESRI staff to "Change selection color in Search Widget in Web AppBuilder."  It would be great if we could do this in the configuration window or just have an easier way of doing it.

Change the Search widget symbology in WAB 2.12

1)  Add 'esri/symbols/jsonUtils', to define and add jsonUtils in function according to Robert Scheitlin, GISP post on July 7, 2016 (see here).  Changes are on lines 38 and 54.

2) Added lines 324-329 per Kyle Schwizer‌'s post on October 31, 2018, from within this thread.

    Commented line 327 per David Coley‌'s post on April 10, 2019, also from within this thread.

3) Comment lines 351-386 per David Coley's post on April 9, 2019, also from within this thread.

4) Note - this is NOT a change but I want to point out that Kyle's post from October 31, 2018 also states to comment "this.searchDijit.clearGraphics" (line 492 below).  That was already a comment in 2.12.

5) Added "highlightSymbol" settings to the Search config json.  See lines 42-57 and remember to add the comma after "query" on line 42 per Robert S.  My settings create a red circle around an address point.

One tip to pass along is in reference to item 2 above.  I have two or three searches configured in all of my apps, some search on a point layer and others on a polygon layer.  What I noticed was if I didn't comment line 327 (see item 2) then my polygon searches returned the symbology for the points and polygons.  That's illustrated below.  I should only be seeing the red parcel border for a parcel search.  Commenting line 327 stopped that.  (I did not notice any instances where a point search returned both the point and polygon symbology).

                                                         

ValerieKearny
New Contributor

Updates for 2.23 anybody?

0 Kudos