Hi all,
I really need your help! I am fairly new to the coding world, especially ArcGIS API for JavaScript. Let me get straight to the point. I am trying to create a web-based map application that contains information of Counties and Cities in California. Ultimately, when I select a particular jurisdiction, the map will automatically zoom into that jurisdiction and highlights its boundary. I also want to develop a popup window that illustrates some information of that selected jurisdiction.
I have been "googling" for a solution online and this is what I came up with so far. I got the list to populate but it doesn't zoom into the jurisdiction when I select it. Please look at my code below:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<title>Populate dropdown list with unique values</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
<style type="text/css">body,html,#main{margin:0;padding:0;height:100%;width:100%;}</style>
<script src="http://js.arcgis.com/3.10/"></script>
<script>
var map;
var resizeTimer;
require([
"esri/map", "esri/tasks/query", "dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane",
"dijit/form/ComboBox", "dojo/data/ItemFileReadStore","dojo/store/Memory", "dojo/on", "dojo/domReady!"],
function(Map, query, parser, BorderContainer, ContentPane, ComboBox, ItemFileReadStore, Memory, on) {
parser.parse();
map = new Map("map", {
basemap: "topo",
//center: [-122.45, 37.75], // longitude, latitude
center : [-120.676665, 37.306837],
zoom: 6
});
var queryTask = new esri.tasks.QueryTask("http://services.arcgis.com/IARhjUVNlIMumZL3/ArcGIS/rest/services/OTS_MAP/FeatureServer/1");
//Define query parameters
var query = new esri.tasks.Query();
query.outFields = ["NAME", "POP", "DVMT", "FATAL_OTS"];
query.returnGeometry = true;
query.where = "NAME <> ''"
queryTask.execute(query,populateList);
//var initialExtent = new esri.geometry.Extent(-85.915,38.105,-85.52,38.33,
// new esri.SpatialReference({wkid:4326}) );
// map = new esri.Map("map", {extent:initialExtent});
//Create tiled and dynamic map services and add to the map - for the dynamic service set the transparency
//and provide an id so we can access it later
map.addLayer(new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"));
map.addLayer(new esri.layers.ArcGISTiledMapServiceLayer("http://services.arcgis.com/IARhjUVNlIMumZL3/ArcGIS/rest/services/CPP4OTS_MAP/MapServer",
{"opacity":.4,"id":"dynamic"}));
function populateList(results) {
//initialize InfoTemplate
infoTemplate = new esri.InfoTemplate("${NAME}", "County : ${NAME}<br/> Population : ${POP}<br/> Daily VMT : ${DVMT} <br/> Fatal OTS : ${FATAL_OTS}");
//create symbol for selected features
symbol = new esri.symbol.SimpleMarkerSymbol();
symbol.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE);
symbol.setSize(10);
symbol.setColor(new dojo.Color([255, 255, 0, 0.5]));
//Populate the dropdown list box with unique values
var county;
var values = [];
var testVals={};
//Add option to display all zoning types to the dropdown list
values.push({name:"ALL"})
var features = results.features;
dojo.forEach (features, function(feature) {
county = feature.attributes.NAME;
if (!testVals[county]) {
testVals[county] = true;
values.push({name:county});
}
});
var dataItems = {
identifier: 'name',
label: 'name',
items: values
};
var store = new dojo.store.Memory({data:dataItems});
dijit.byId("mySelect").store = store;
//remove all graphics on the maps graphics layer
map.graphics.clear();
//Performance enhancer - assign featureSet array to a single variable.
var resultFeatures = results.features;
//Loop through each feature returned
for (var i = 0, il = resultFeatures.length; i < il; i++) {
//Get the current feature from the featureSet.
//Feature is a graphic
var graphic = resultFeatures;
graphic.setSymbol(symbol);
//Set the infoTemplate.
graphic.setInfoTemplate(infoTemplate);
//Add graphic to the map graphics layer.
map.graphics.add(graphic);
// This takes the graphics array you get back from your query and
// gets the overall extent for them. Make sure return geometry is set to
// true in your query.
var extent = esri.graphicsExtent(results.features);
// Use that to set the extent, 1.5 is something I use in my app, but play with
// it to find a setting you like, setting the second parameter to true will get you an extend
// that is at the closest level of your cached service.
map.setExtent(extent.expand(1.7), true);
}
}
// this replaces your applyLayerDef() function
dijit.byId("mySelect").on("change", function () {
//Filter the layer to display only the selected zoning types
var county = dijit.byId("mySelect").value;
if (county !== 'ALL') {
var layerDefs = [];
layerDefs[2] = "NAME = " + "'" + county + "'";
layerDefs.visibleLayers = [2];
map.getLayer("dynamic").setLayerDefinitions(layerDefs);
}
else {
map.getLayer("dynamic").setDefaultLayerDefinitions();
}
});
function resizeMap() {
//Handle browser resize
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
map.resize();
map.reposition();
}, 800);
}
});
</script>
</head>
<body class="claro">
<div id="main"
dojotype="dijit.layout.BorderContainer"
design="headline"
gutters="true">
<div id="header"
dojotype="dijit.layout.ContentPane"
region="top"
style="height:25px;">
<select id="mySelect"
dojotype="dijit.form.ComboBox"
style="width:300px;font-size:18px;"
autoComplete="true"
forceValidOption="false"
value="Select Zoning Type"></select>
</div>
<div id="map"
dojotype="dijit.layout.ContentPane"
region="center"
style="border:1px solid #000;margin:5px">
</div>
</div>
</body>
</html>
Solved! Go to Solution.
Hi Riyas,
Thank you so much for your help! You are such a life-savor. I do really appreciate your help. Yes--I used JQuery to connect with the value from my map. We were trying to connect the dropdownlist to the combo box all this time but we didn't know how (due to our limited coding experience).
Tom
Hi,
Thanks for the code this is exactly what i needed.
Small modification i needed in this. instead of loading initially into the second combo box, how can i add values to the second combo box based on the first combo box input.
For example the city combo box (second one) should have input as the cities existing in the county selected in the first combo box.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<title>Populate dropdown list with unique values</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
<style type="text/css">body,html,#main{margin:0;padding:0;height:100%;width:100%;}</style>
<script src="http://js.arcgis.com/3.10/"></script>
<script>
var map;
var resizeTimer;
require([
"esri/map", "esri/tasks/query", "dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane",
"esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters", "dojo/_base/array","dojo/DeferredList",
"dijit/form/ComboBox", "dojo/data/ItemFileReadStore","dojo/store/Memory", "dojo/on", "dojo/domReady!"],
function(Map, query, parser, BorderContainer, ContentPane,
IdentifyTask, IdentifyParameters,arrayUtils,DeferredList,
ComboBox, ItemFileReadStore, Memory, on, Scalebar) {
parser.parse();
map = new Map("map", {
basemap: "topo",
//center: [-122.45, 37.75], // longitude, latitude
center : [-120.676665, 37.306837],
zoom: 6
});
var polygonQuery = null;
var polygonQueryTask = null;
var polygonQuery1 = null;
var polygonQueryTask1 = null;
// RIYAS: Wait till map is loaded before firing query, needed for getting map spatial reference
map.on("load", function () {
var queryTask = new esri.tasks.QueryTask("http://services.arcgis.com/IARhjUVNlIMumZL3/ArcGIS/rest/services/OTS_MAP/FeatureServer/1");
var queryTask1 = new esri.tasks.QueryTask("http://services.arcgis.com/IARhjUVNlIMumZL3/ArcGIS/rest/services/OTS_MAP/FeatureServer/0");
//Define query parameters
var query = new esri.tasks.Query();
query.outFields = ["NAME", "POP", "DVMT", "FATAL_OTS"];
query.returnGeometry = true;
query.outSpatialReference = map.spatialReference; // RIYAS: Set query to return shape in map's spatial reference
query.where = "NAME <> ''"
queryTask.execute(query,populateList);
//Define query parameters
var query1 = new esri.tasks.Query();
query1.outFields = ["NAME", "POP", "DVMT", "FATAL_OTS"];
query1.returnGeometry = true;
query1.outSpatialReference = map.spatialReference; // RIYAS: Set query to return shape in map's spatial reference
query1.where = "NAME <> ''"
queryTask1.execute(query1,populateList1);
// RIYAS: Setup query to behave as identify
polygonQueryTask = new esri.tasks.QueryTask("http://services.arcgis.com/IARhjUVNlIMumZL3/ArcGIS/rest/services/OTS_MAP/FeatureServer/1");
polygonQuery = new esri.tasks.Query();
polygonQuery.returnGeometry = true;
polygonQuery.outFields = ["NAME", "POP", "DVMT", "FATAL_OTS"];
polygonQuery.spatialRelationship = esri.tasks.Query.SPATIAL_REL_INTERSECTS;
polygonQuery.outSpatialReference = map.spatialReference;
// RIYAS: Setup query to behave as identify
polygonQueryTask1 = new esri.tasks.QueryTask("http://services.arcgis.com/IARhjUVNlIMumZL3/ArcGIS/rest/services/OTS_MAP/FeatureServer/0");
polygonQuery1 = new esri.tasks.Query();
polygonQuery1.returnGeometry = true;
polygonQuery1.outFields = ["NAME", "POP", "DVMT", "FATAL_OTS"];
polygonQuery1.spatialRelationship = esri.tasks.Query.SPATIAL_REL_INTERSECTS;
polygonQuery1.outSpatialReference = map.spatialReference;
});
var infoTemplate = new esri.InfoTemplate("County: ${NAME}", "County : ${NAME}<br/> Population : ${POP}<br/> Daily VMT : ${DVMT} <br/> Fatal OTS : ${FATAL_OTS}");
var infoTemplate1 = new esri.InfoTemplate("City: ${NAME}", "City : ${NAME}<br/> Population : ${POP}<br/> Daily VMT : ${DVMT} <br/> Fatal OTS : ${FATAL_OTS}");
var infoTemplates = [infoTemplate, infoTemplate1];
//map.on("click", executeIdentifyTask);
// RIYAS: Execute query to behave as identify
function executeIdentifyTask (where, pnt) {
//polygonQuery.where = event.mapPoint;
//polygonQuery1.where = event.mapPoint;
polygonQuery.where = where;
polygonQuery1.where = where;
var deferred = polygonQueryTask
.execute(polygonQuery);
var deferred1 = polygonQueryTask1
.execute(polygonQuery1);
// InfoWindow expects an array of features from each deferred
// object that you pass. If the response from the task execution
// above is not an array of features, then you need to add a callback
// like the one above to post-process the response and return an
// array of features.
var defList = new DeferredList([deferred, deferred1]).then(function (results){
var features = [];
arrayUtils.forEach(results,function(result, idx){
if (result[0] === true){
features = features.concat(arrayUtils.map(result[1].features, function (feature) {
feature.setInfoTemplate(infoTemplates[idx]);
return feature;
}));
}
});
map.infoWindow.setFeatures(features);
map.infoWindow.show(pnt);
});
}
//var initialExtent = new esri.geometry.Extent(-85.915,38.105,-85.52,38.33,
// new esri.SpatialReference({wkid:4326}) );
// map = new esri.Map("map", {extent:initialExtent});
//Create tiled and dynamic map services and add to the map - for the dynamic service set the transparency
//and provide an id so we can access it later
map.addLayer(new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"));
map.addLayer(new esri.layers.ArcGISTiledMapServiceLayer("http://services.arcgis.com/IARhjUVNlIMumZL3/ArcGIS/rest/services/CPP4OTS_MAP/MapServer",
{"opacity":0.8,"id":"dynamic"}));
function populateList(results) {
//initialize InfoTemplate
//create symbol for selected features
symbol = new esri.symbol.SimpleMarkerSymbol();
symbol.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE);
symbol.setSize(10);
symbol.setColor(new dojo.Color([255, 255, 0, 0.5]));
//Populate the dropdown list box with unique values
var county;
var values = [];
var testVals={};
//Add option to display all zoning types to the dropdown list
values.push({name:"ALL"})
var features = results.features;
dojo.forEach (features, function(feature) {
county = feature.attributes.NAME;
if (!testVals[county]) {
testVals[county] = true;
values.push({name:county,shape:feature.geometry,centroid: feature.geometry.type === "point" ? feature.geometry : feature.geometry.getCentroid() }); // RIYAS: set shape to list store
}
});
var dataItems = {
identifier: 'name',
label: 'name',
items: values
};
var store = new dojo.store.Memory({data:dataItems});
dijit.byId("mySelect").store = store;
//remove all graphics on the maps graphics layer
map.graphics.clear();
//Performance enhancer - assign featureSet array to a single variable.
var resultFeatures = results.features;
//Loop through each feature returned
for (var i = 0, il = resultFeatures.length; i < il; i++) {
//Get the current feature from the featureSet.
//Feature is a graphic
var graphic = resultFeatures;
graphic.setSymbol(symbol);
//Set the infoTemplate.
graphic.setInfoTemplate(infoTemplate);
//Add graphic to the map graphics layer.
map.graphics.add(graphic);
// This takes the graphics array you get back from your query and
// gets the overall extent for them. Make sure return geometry is set to
// true in your query.
var extent = esri.graphicsExtent(results.features);
// Use that to set the extent, 1.5 is something I use in my app, but play with
// it to find a setting you like, setting the second parameter to true will get you an extend
// that is at the closest level of your cached service.
map.setExtent(extent.expand(1.0), true);
}
}
// this replaces your applyLayerDef() function
dijit.byId("mySelect").on("change", function () {
//Filter the layer to display only the selected zoning types
var county = dijit.byId("mySelect").value;
var centroid = dijit.byId("mySelect").item.centroid;
if (county !== 'ALL') {
var layerDefs = [];
layerDefs[2] = "NAME = " + "'" + county + "'";
layerDefs.visibleLayers = [2];
map.setExtent(dijit.byId("mySelect").item.shape.getExtent(infoTemplate).expand(1.7)); // RIYAS: Get shape from list store and zoom to its extent
executeIdentifyTask("NAME = '" + county + "'", centroid);
// RIYAS: cannot set layer defintion for dynamic map service.
//map.getLayer("dynamic").setLayerDefinitions(layerDefs);
}
else {
// RIYAS: cannot set layer defintion for dynamic map service.
//map.getLayer("dynamic").setDefaultLayerDefinitions();
}
});
function populateList1(results1) {
//initialize InfoTemplate
//create symbol for selected features
symbol1 = new esri.symbol.SimpleMarkerSymbol();
symbol1.setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE);
symbol1.setSize(10);
symbol1.setColor(new dojo.Color([255, 255, 0, 0.5]));
//Populate the dropdown list box with unique values
var city;
var values1 = [];
var testVals1={};
//Add option to display all zoning types to the dropdown list
values1.push({name:"ALL"})
var features1 = results1.features;
dojo.forEach (features1, function(feature1) {
city = feature1.attributes.NAME;
if (!testVals1[city]) {
testVals1[city] = true;
values1.push({name:city,shape:feature1.geometry,centroid: feature1.geometry.type === "point" ? feature1.geometry : feature1.geometry.getCentroid()}); // RIYAS: set shape to list store
}
});
var dataItems1 = {
identifier: 'name',
label: 'name',
items: values1
};
var store1 = new dojo.store.Memory({data:dataItems1});
dijit.byId("mySelect1").store = store1;
//remove all graphics on the maps graphics layer
map.graphics.clear();
//Performance enhancer - assign featureSet array to a single variable.
var resultFeatures1 = results1.features;
//Loop through each feature returned
for (var i = 0, il = resultFeatures1.length; i < il; i++) {
//Get the current feature from the featureSet.
//Feature is a graphic
var graphic1 = resultFeatures1;
graphic1.setSymbol(symbol1);
//Set the infoTemplate.
graphic1.setInfoTemplate(infoTemplate1);
//Add graphic to the map graphics layer.
map.graphics.add(graphic1);
// This takes the graphics array you get back from your query and
// gets the overall extent for them. Make sure return geometry is set to
// true in your query.
var extent1 = esri.graphicsExtent(results1.features);
// Use that to set the extent, 1.5 is something I use in my app, but play with
// it to find a setting you like, setting the second parameter to true will get you an extend
// that is at the closest level of your cached service.
map.setExtent(extent1.expand(1.0), true);
}
}
// this replaces your applyLayerDef() function
dijit.byId("mySelect1").on("change", function () {
//Filter the layer to display only the selected zoning types
var city = dijit.byId("mySelect1").value;
var centroid = dijit.byId("mySelect1").item.centroid;
if (city !== 'ALL') {
var layerDefs1 = [];
layerDefs1[2] = "NAME = " + "'" + city + "'";
layerDefs1.visibleLayers = [2];
map.setExtent(dijit.byId("mySelect1").item.shape.getExtent(infoTemplate1).expand(1.7)); // RIYAS: Get shape from list store and zoom to its extent
executeIdentifyTask("NAME = '" + city + "'", centroid);
// RIYAS: cannot set layer defintion for dynamic map service.
//map.getLayer("dynamic").setLayerDefinitions(layerDefs);
}
else {
// RIYAS: cannot set layer defintion for dynamic map service.
//map.getLayer("dynamic").setDefaultLayerDefinitions();
}
});
function resizeMap() {
//Handle browser resize
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
map.resize();
map.reposition();
}, 800);
}
});
</script>
</head>
<body class="claro">
<div id="main"
dojotype="dijit.layout.BorderContainer"
design="headline"
gutters="true">
<div id="header"
dojotype="dijit.layout.ContentPane"
region="top"
style="height:25px;">
<select id="mySelect"
dojotype="dijit.form.ComboBox"
style="width:300px;font-size:18px;"
autoComplete="true"
forceValidOption="false"
value="Select a County"></select>
<select id="mySelect1"
dojotype="dijit.form.ComboBox"
style="width:300px;font-size:18px;"
autoComplete="true"
forceValidOption="false"
value="Select a City"></select>
</div>
<div id="map"
dojotype="dijit.layout.ContentPane"
region="center"
style="border:1px solid #000;margin:5px">
</div>
</div>
</body>
</html>