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.
Solved! Go to Solution.
Instead of defining your geocoders in the main.js file try adding them to defaults. js instead. If you open defaults.js in a text editor you'll see there's a section for helper services and it contains a place where you can define one or more geocode services. Here's an example of customizing it for your services:
"geocode": [{ "url": "http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_CompositeLocator/GeocodeServer", "singleLineFieldName": "SingleLine", "name": "MD_CompositeLocator", "placefinding":true, "placeholder": "Find a place" },{ "url":"http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_ParcelAccountNumberLocator/GeocodeServer", "singleLineFieldName": "SingleLine", "name": "MD_ParcelAccountNumberLocator", "placefinding":true, "placeholder": "Find a Parcel Point Account ID" }]
After defining your services open the templateConfig.js file and set the queryForOrg option to false so that it doesn't query ArcGIS Online for helper services and uses the ones you've defined in default. js.
Instead of defining your geocoders in the main.js file try adding them to defaults. js instead. If you open defaults.js in a text editor you'll see there's a section for helper services and it contains a place where you can define one or more geocode services. Here's an example of customizing it for your services:
"geocode": [{ "url": "http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_CompositeLocator/GeocodeServer", "singleLineFieldName": "SingleLine", "name": "MD_CompositeLocator", "placefinding":true, "placeholder": "Find a place" },{ "url":"http://geodata.md.gov/imap/rest/services/GeocodeServices/MD_ParcelAccountNumberLocator/GeocodeServer", "singleLineFieldName": "SingleLine", "name": "MD_ParcelAccountNumberLocator", "placefinding":true, "placeholder": "Find a Parcel Point Account ID" }]
After defining your services open the templateConfig.js file and set the queryForOrg option to false so that it doesn't query ArcGIS Online for helper services and uses the ones you've defined in default. js.
So simple! Wow. Thanks!