Hi there,
I need help with adding multiple custom geocoders to my web map that's based on the Public Information Template.
Problem:
I can get one of my custom geocoders to display on the map. But getting both of them to display as an option for users to select in a drop down has been a struggle.
I have tried creating a variable called "myGeocoders" that lists both geocoders and putting it in the options object below, but the map still only displayed one geocoder. In the code below, I tried listing both geocoders separately along with the ESRI geocoder to see if it will show, and it still only displayed one geocoder. Same if I take out the ESRI geocoder.
Code below:
_createGeocoderOptions: function() {
var hasEsri = false, esriIdx, geocoders = lang.clone(this.config.helperServices.geocode);
// default options
var myGeocoders = [{
url: "http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_CompositeLocator/GeocodeServer",
name: "MD_CompositeLocator",
"singleLineFieldName": "SingleLine"
},{
url: "http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_ParcelAccountNumberLocator/GeocodeServer",
name: "MD_ParcelAccountNumberLocator",
"singleLineFieldName": "Single Line Input"
}];
var options = {
map: this.map,
autoNavigate: true,
autoComplete: true,
arcgisGeocoder: false,
geocoders: null,
};
//only use geocoders with a url defined
geocoders = array.filter(geocoders, function (geocoder) {
if (geocoder.url) {
return true;
}
else{
return false;
}
});
// at least 1 geocoder defined
if(geocoders.length){
// each geocoder
array.forEach(geocoders, lang.hitch(this, function(geocoder) {
// if esri geocoder
if (geocoder.url && geocoder.url.indexOf(".arcgis.com/arcgis/rest/services/World/GeocodeServer") > -1) {
hasEsri = true;
geocoder.name = "Esri World Geocoder";
geocoder.outFields = "Match_addr, stAddr, City";
geocoder.singleLineFieldName = "Single Line";
geocoder.esri = true;
geocoder.placefinding = true;
geocoder.placeholder = this.config.i18n.general.find;
}
//if not esri geocoder
if (geocoder.url && geocoder.url.indexOf("http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_CompositeLocator/GeocodeServer") > -2) {
hasEsri = false;
geocoder.name = "MD_CompositeLocator";
geocoder.outFields = "Street, City, State, ZIP";
geocoder.singleLineFieldName = "SingleLine";
geocoder.esri = false;
geocoder.placefinding = true;
geocoder.placeholder = "Find a Place";
}
//if not esri geocoder
if (geocoder.url && geocoder.url.indexOf("http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_ParcelAccountNumberLocator/GeocodeServer") > -1) {
hasEsri = false;
geocoder.name = "MD_ParcelAccountNumberLocator";
geocoder.outFields = "*";
geocoder.singleLineFieldName = "Single Line Input";
geocoder.esri = false;
geocoder.placefinding = true;
geocoder.placeholder = "Find a Parcel Point Account ID";
}
})) ;
//only use geocoders with a singleLineFieldName that allow placefinding unless its custom
geocoders = array.filter(geocoders, function (geocoder) {
if (geocoder.name && geocoder.name === "Custom") {
return (esriLang.isDefined(geocoder.singleLineFieldName));
} else {
return (esriLang.isDefined(geocoder.singleLineFieldName) && esriLang.isDefined(geocoder.placefinding) && geocoder.placefinding);
}
});
// if we have an esri geocoder
if (hasEsri) {
for (var i = 0; i < geocoders.length; i++) {
if (esriLang.isDefined(geocoders.esri) && geocoders.esri === true) {
esriIdx = i;
break;
}
}
}
// set autoComplete
options.autoComplete = true;
// set esri options
if (hasEsri) {
options.minCharacters = 0;
options.maxLocations = 5;
options.searchDelay = 100;
}
//If the World geocoder is primary enable auto complete
if (hasEsri && esriIdx === 0) {
options.arcgisGeocoder = geocoders.splice(0, 1)[0]; //geocoders[0];
if (geocoders.length > 0) {
options.geocoders = geocoders;
}
} else {
options.arcgisGeocoder = false;
options.geocoders = geocoders;
}
}
return options;
},
// create geocoder widgets
_createGeocoders: function () {
//add geocoder result layer
var resultsLayer = new esri.layers.GraphicsLayer({ id: "resultsLayer" }); //geocoder symbol code
this.map.addLayer(resultsLayer);
// get options
var createdOptions = this._createGeocoderOptions();
// desktop geocoder options
var desktopOptions = lang.mixin({}, createdOptions, {
theme: this.css.desktopGeocoderTheme
});
// mobile geocoder options
var mobileOptions = lang.mixin({}, createdOptions, {
theme: this.css.mobileGeocoderTheme
});
// desktop size geocoder
this._geocoder = new Geocoder(desktopOptions, dom.byId("geocoderSearch"));
;
this._geocoder.startup();
//add feature to map //geocoder symbol
function addFeatureToMap(geometry) {
resultsLayer.clear();
var pictureMarkerSymbol = new PictureMarkerSymbol({ "angle": 0, "xoffset": 2, "yoffset": 8, "type": "esriPMS", "url": "http://static.arcgis.com/images/Symbols/Basic/RedStickpin.png", "contentType": "image/png", "width": 24, "height": 24 });
resultsLayer.add(new Graphic(geometry, pictureMarkerSymbol));
}
//zoom to level 19 after press geocoder - MIO
on(this._geocoder, 'select', lang.hitch(this, function (response) {
console.log("set zoom function");
console.log(this.map);
this.map.setZoom(19);
}));
// geocoder results
on(this._geocoder, 'find-results', lang.hitch(this, function (response) {
if (!response.results || !response.results.results || !response.results.results.length) {
alert(this.config.i18n.general.noSearchResult);
} else { //geocoder symbol results
addFeatureToMap(response.results.results[0].feature.geometry);
if (history.pushState) {
//browser supported.
//refresh the URL with the geocoder result
console.log("Push state is supported. Geocoder result: ");
console.log(this._geocoder.value);
window.history.pushState(null,null,"?address=" + this._geocoder.value);
}
}
}));
// mobile sized geocoder
this._mobileGeocoder = new Geocoder(mobileOptions, dom.byId("geocoderMobile"));
this._mobileGeocoder.startup();
// geocoder results
on(this._mobileGeocoder, 'find-results', lang.hitch(this, function (response) {
if (!response.results || !response.results.results || !response.results.results.length) {
alert(this.config.i18n.general.noSearchResult);
} else { //geocoder symbol results and all below until keep geocoder values in sync
addFeatureToMap(response.results.results[0].feature.geometry);
//refresh the URL with the geocoder result
if (history.pushState) {
//browser supported.
//refresh the URL with the geocoder result
console.log("Push state is supported. Geocoder result: ");
console.log(this._geocoder.value);
window.history.pushState(null,null,"?address=" + this._geocoder.value);
}
}
this._hideMobileGeocoder();
}));
on(this._geocoder, 'clear', lang.hitch(this, function () {
resultsLayer.clear();
})); //rest of geocoder symbol result
on(this._mobileGeocoder, 'clear', lang.hitch(this, function () {
resultsLayer.clear();
})); //rest of geocoder symbol result
// keep geocoder values in sync
this._geocoder.watch("value", lang.hitch(this, function () {
var value = arguments[2];
this._mobileGeocoder.set("value", value);
}));
// keep geocoder values in sync
this._mobileGeocoder.watch("value", lang.hitch(this, function () {
var value = arguments[2];
this._geocoder.set("value", value);
}));
// geocoder nodes
this._mobileGeocoderIconNode = dom.byId("mobileGeocoderIcon");
this._mobileSearchNode = dom.byId("mobileSearch");
this._mobileGeocoderIconContainerNode = dom.byId("mobileGeocoderIconContainer");
// mobile geocoder toggle
if (this._mobileGeocoderIconNode) {
on(this._mobileGeocoderIconNode, "click", lang.hitch(this, function () {
if (domStyle.get(this._mobileSearchNode, "display") === "none") {
this._showMobileGeocoder();
} else {
this._hideMobileGeocoder();
}
}));
}
var closeMobileGeocoderNode = dom.byId("btnCloseGeocoder");
if(closeMobileGeocoderNode){
// cancel mobile geocoder
on(closeMobileGeocoderNode, "click", lang.hitch(this, function () {
this._hideMobileGeocoder();
}));
}
},Background Info:
Level: newbie JS developer.
Using ESRI JavaScript API - ESRI's Public information web map template: Esri/public-information-map-template-js · GitHub
This code was added to the main.js file in the _init: function ().
Any tips?
Thanks.