AnsweredAssumed Answered

WAB2.8 Search Widget JS Highlight Symbol: Changes from 2.7

Question asked by dcoley on Nov 29, 2017
Latest reply on Aug 9, 2018 by rscheitlin

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

Outcomes