I am trying to convert History API to track selected feature sample from 3.x into 4.x.
Please share the 4.x code, thanks in advance.
History API to track selected feature | ArcGIS API for JavaScript 3.25
Solved! Go to Solution.
Imtiyaz,
Here is that sample using 4.8 (minus the parcel highlight):
<!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>Parcel Locator</title>
<link rel="stylesheet" href="http://js.arcgis.com/4.8/esri/css/main.css">
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
</style>
<script>
var dojoConfig = {
has: {
"esri-featurelayer-webgl": 1
}
};
</script>
<script src="http://js.arcgis.com/4.8/"></script>
<script>
var map;
var parcels;
require([
"esri/Map", "esri/views/MapView", "esri/layers/FeatureLayer",
"esri/layers/TileLayer", "esri/tasks/support/Query",
"esri/symbols/SimpleFillSymbol", "esri/symbols/SimpleLineSymbol",
"esri/Graphic", "esri/widgets/Popup",
"esri/core/urlUtils",
"esri/Color",
"dojo/on", "dojo/query", "dojo/parser", "dojo/dom-construct",
"dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojo/domReady!"
], function(
Map, MapView, FeatureLayer,
TileLayer, Query,
SimpleFillSymbol, SimpleLineSymbol,
Graphic, Popup,
urlUtils,
Color,
on, query, parser, domConstruct
) {
parser.parse();
var popup = new Popup({
container: domConstruct.create("div")
});
var basemap = new TileLayer({url:"http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/AssessorsBasemap/MapServer"});
map = new Map({
layers: [basemap]
});
var view = new MapView({
container: "viewDiv",
map: map,
popup: popup
});
//apply a popup template to the parcels layer to format popup info
var popupTemplate = {
title: "{PARCELID}",
content: [{
type: "fields",
fieldInfos: [{
fieldName: "SITEADDRESS",
label: "Address:",
visible: true
}, {
fieldName: "OWNERNME1",
label: "Owner:",
visible: true
}]
}],
actions: [{
id: "Email-Map",
className: "esri-icon-contact",
title: "Email Map"
}],
};
//add the parcels layer to the map as a feature layer in selection mode we'll use this layer to query and display the selected parcels
parcels = new FeatureLayer({
url:" http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/AssessorsBasemap/MapServer/1",
outFields: ["*"],
popupTemplate: popupTemplate
});
view.when(function() {
// Watch for when features are selected
view.popup.watch("selectedFeature", function(graphic) {
if (graphic) {
var parcelid = graphic.attributes["PARCELID"];
//Refresh the URL with the currently selected parcel
if (typeof history.pushState !== "undefined") {
window.history.pushState(null, null, "?parcelid=" + graphic.attributes.PARCELID);
}
}
});
});
view.when(function() {
var popup = view.popup;
popup.viewModel.on("trigger-action", function(event) {
if (event.action.id === "Email-Map") {
var attributes = popup.viewModel.selectedFeature.attributes;
// Get the 'PARCELID' field attribute
var info = attributes.PARCELID;
// Make sure the 'PARCELID' field value is not null
if (info) {
var url = window.location;
var emailLink = "mailto:?subject=Parcel Map of :" +
info + "&body=Check out this map: %0D%0A " +
window.location;
window.location.href = emailLink;
}
}
});
});
parcels.when(function(){
// Add a link into the InfoWindow Actions panel
var emailLink = domConstruct.create("a", {
"class": "action",
"innerHTML": "Email Map",
"href": "javascript:void(0);"
}, query(".actionList", view.popup.domNode)[0]);
//When users navigate through the history using the browser back/forward buttons select appropriate parcel
//http://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
window.onpopstate = function (event) {
var parcelid = getParcelFromUrl(document.location.href);
if (parcelid) {
selectParcel(parcelid);
} else {
//parcels.clearSelection();
view.popup.close();
}
};
//if a parcelid is specified in url param select that feature
var parcelid = getParcelFromUrl(document.location.href);
selectParcel(parcelid);
});
map.add(parcels);
//extract the parcel id from the url
function getParcelFromUrl(url) {
var urlObject = urlUtils.urlToObject(url);
if (urlObject.query && urlObject.query.parcelid) {
return urlObject.query.parcelid;
} else {
return null;
}
}
//select parcel from the feature layer by creating a query to look for the input parcel id
function selectParcel(parcelid) {
if (parcelid) {
var query = parcels.createQuery();
query.where = "PARCELID = '" + parcelid + "'";
var deferred = parcels.queryFeatures(query).then(function (selection) {
var center = selection.features[0].geometry.extent.center;
var extHandler = view.watch("stationary", function () {
extHandler.remove();
//zoom to the center then display the popup
view.popup.open({
location: center,
features: selection.features,
updateLocationEnabled: true
});
});
view.goTo({
target: center,
zoom: 8
});
});
}
}
});
</script>
</head>
<body class="claro">
<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline',gutters:false"
style="width: 100%; height: 100%; margin: 0;">
<div id="viewDiv" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
</div>
</body>
</html>
Don't forget to mark this question as answered by clicking on the "Mark Correct" link on the reply that answered your question.
Imtiyaz,
Here is that sample using 4.8 (minus the parcel highlight):
<!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>Parcel Locator</title>
<link rel="stylesheet" href="http://js.arcgis.com/4.8/esri/css/main.css">
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
</style>
<script>
var dojoConfig = {
has: {
"esri-featurelayer-webgl": 1
}
};
</script>
<script src="http://js.arcgis.com/4.8/"></script>
<script>
var map;
var parcels;
require([
"esri/Map", "esri/views/MapView", "esri/layers/FeatureLayer",
"esri/layers/TileLayer", "esri/tasks/support/Query",
"esri/symbols/SimpleFillSymbol", "esri/symbols/SimpleLineSymbol",
"esri/Graphic", "esri/widgets/Popup",
"esri/core/urlUtils",
"esri/Color",
"dojo/on", "dojo/query", "dojo/parser", "dojo/dom-construct",
"dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojo/domReady!"
], function(
Map, MapView, FeatureLayer,
TileLayer, Query,
SimpleFillSymbol, SimpleLineSymbol,
Graphic, Popup,
urlUtils,
Color,
on, query, parser, domConstruct
) {
parser.parse();
var popup = new Popup({
container: domConstruct.create("div")
});
var basemap = new TileLayer({url:"http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/AssessorsBasemap/MapServer"});
map = new Map({
layers: [basemap]
});
var view = new MapView({
container: "viewDiv",
map: map,
popup: popup
});
//apply a popup template to the parcels layer to format popup info
var popupTemplate = {
title: "{PARCELID}",
content: [{
type: "fields",
fieldInfos: [{
fieldName: "SITEADDRESS",
label: "Address:",
visible: true
}, {
fieldName: "OWNERNME1",
label: "Owner:",
visible: true
}]
}],
actions: [{
id: "Email-Map",
className: "esri-icon-contact",
title: "Email Map"
}],
};
//add the parcels layer to the map as a feature layer in selection mode we'll use this layer to query and display the selected parcels
parcels = new FeatureLayer({
url:" http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/AssessorsBasemap/MapServer/1",
outFields: ["*"],
popupTemplate: popupTemplate
});
view.when(function() {
// Watch for when features are selected
view.popup.watch("selectedFeature", function(graphic) {
if (graphic) {
var parcelid = graphic.attributes["PARCELID"];
//Refresh the URL with the currently selected parcel
if (typeof history.pushState !== "undefined") {
window.history.pushState(null, null, "?parcelid=" + graphic.attributes.PARCELID);
}
}
});
});
view.when(function() {
var popup = view.popup;
popup.viewModel.on("trigger-action", function(event) {
if (event.action.id === "Email-Map") {
var attributes = popup.viewModel.selectedFeature.attributes;
// Get the 'PARCELID' field attribute
var info = attributes.PARCELID;
// Make sure the 'PARCELID' field value is not null
if (info) {
var url = window.location;
var emailLink = "mailto:?subject=Parcel Map of :" +
info + "&body=Check out this map: %0D%0A " +
window.location;
window.location.href = emailLink;
}
}
});
});
parcels.when(function(){
// Add a link into the InfoWindow Actions panel
var emailLink = domConstruct.create("a", {
"class": "action",
"innerHTML": "Email Map",
"href": "javascript:void(0);"
}, query(".actionList", view.popup.domNode)[0]);
//When users navigate through the history using the browser back/forward buttons select appropriate parcel
//http://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
window.onpopstate = function (event) {
var parcelid = getParcelFromUrl(document.location.href);
if (parcelid) {
selectParcel(parcelid);
} else {
//parcels.clearSelection();
view.popup.close();
}
};
//if a parcelid is specified in url param select that feature
var parcelid = getParcelFromUrl(document.location.href);
selectParcel(parcelid);
});
map.add(parcels);
//extract the parcel id from the url
function getParcelFromUrl(url) {
var urlObject = urlUtils.urlToObject(url);
if (urlObject.query && urlObject.query.parcelid) {
return urlObject.query.parcelid;
} else {
return null;
}
}
//select parcel from the feature layer by creating a query to look for the input parcel id
function selectParcel(parcelid) {
if (parcelid) {
var query = parcels.createQuery();
query.where = "PARCELID = '" + parcelid + "'";
var deferred = parcels.queryFeatures(query).then(function (selection) {
var center = selection.features[0].geometry.extent.center;
var extHandler = view.watch("stationary", function () {
extHandler.remove();
//zoom to the center then display the popup
view.popup.open({
location: center,
features: selection.features,
updateLocationEnabled: true
});
});
view.goTo({
target: center,
zoom: 8
});
});
}
}
});
</script>
</head>
<body class="claro">
<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline',gutters:false"
style="width: 100%; height: 100%; margin: 0;">
<div id="viewDiv" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
</div>
</body>
</html>
Don't forget to mark this question as answered by clicking on the "Mark Correct" link on the reply that answered your question.
Thanks a lot, exactly what I was looking for.
It will be great if we add x & y and LOD to URL parameter on the zoom of the parcel.
Please extend your sample further, it will be very helpful.
Why XY? I can see adding LOD.
In some cases for new parcels no ID assigned, we can provide the extent of the area using X and Y coordinates in URL.
This is untested since the layer in the same always has a parcelid.
<!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>Parcel Locator</title>
<link rel="stylesheet" href="http://js.arcgis.com/4.8/esri/css/main.css">
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
</style>
<script src="http://js.arcgis.com/4.8/"></script>
<script>
var map;
var parcels;
require([
"esri/Map", "esri/views/MapView", "esri/layers/FeatureLayer",
"esri/layers/TileLayer", "esri/tasks/support/Query",
"esri/symbols/SimpleFillSymbol", "esri/symbols/SimpleLineSymbol",
"esri/Graphic", "esri/widgets/Popup",
"esri/core/urlUtils",
"esri/Color", "esri/geometry/Point",
"dojo/on", "dojo/query", "dojo/parser", "dojo/dom-construct",
"dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojo/domReady!"
], function(
Map, MapView, FeatureLayer,
TileLayer, Query,
SimpleFillSymbol, SimpleLineSymbol,
Graphic, Popup,
urlUtils,
Color, Point,
on, query, parser, domConstruct
) {
parser.parse();
window.progSelection = false;
var popup = new Popup({
container: domConstruct.create("div")
});
var basemap = new TileLayer({url:"http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/AssessorsBasemap/MapServer"});
map = new Map({
layers: [basemap]
});
var view = new MapView({
container: "viewDiv",
map: map,
popup: popup
});
// Create a symbol for rendering the graphic
var fillSymbol = {
type: "simple-fill", // autocasts as new SimpleFillSymbol()
color: [111, 0, 255, 0.3],
outline: { // autocasts as new SimpleLineSymbol()
color: [111, 0, 255],
width: 1
}
};
//apply a popup template to the parcels layer to format popup info
var popupTemplate = {
title: "{PARCELID}",
content: [{
type: "fields",
fieldInfos: [{
fieldName: "SITEADDRESS",
label: "Address:",
visible: true
}, {
fieldName: "OWNERNME1",
label: "Owner:",
visible: true
}]
}],
actions: [{
id: "Email-Map",
className: "esri-icon-contact",
title: "Email Map"
}],
};
//add the parcels layer to the map as a feature layer in selection mode we'll use this layer to query and display the selected parcels
parcels = new FeatureLayer({
url:" http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/TaxParcel/AssessorsBasemap/MapServer/1",
outFields: ["*"],
popupTemplate: popupTemplate
});
view.when(function() {
// Watch for when features are selected
view.popup.watch("selectedFeature", function(graphic) {
if (graphic) {
view.graphics.removeAll();
var parcelid = graphic.attributes["PARCELID"];
if(!window.progSelection){
//Refresh the URL with the currently selected parcel
if (typeof history.pushState !== "undefined") {
if(!graphic.attributes.PARCELID || graphic.attributes.PARCELID === ''){
var cent = graphic.geometry.getCentroid();
window.history.pushState(null, null, "?xy=" + cent.x + "," + cent.y + '&zoom=' + view.zoom);
}else{
window.history.pushState(null, null, "?parcelid=" + graphic.attributes.PARCELID + '&zoom=' + view.zoom);
}
}
}
var polygonGraphic = new Graphic({
geometry:graphic.geometry,
symbol: fillSymbol
});
view.graphics.add(polygonGraphic);
window.progSelection = false;
}
});
view.popup.watch("visible", function(visible) {
if(visible === false){
view.graphics.removeAll();
}
});
});
view.when(function() {
var popup = view.popup;
popup.viewModel.on("trigger-action", function(event) {
if (event.action.id === "Email-Map") {
var attributes = popup.viewModel.selectedFeature.attributes;
// Get the 'PARCELID' field attribute
var info = attributes.PARCELID;
// Make sure the 'PARCELID' field value is not null
if (info) {
var url = window.location;
var emailLink = "mailto:?subject=Parcel Map of :" +
info + "&body=Check out this map: %0D%0A " +
window.location;
window.location.href = emailLink;
}else{
var cent = popup.viewModel.selectedFeature.geometry.getCentroid();
var xy = cent.x + ", " + cent.y;
var url = window.location;
var emailLink = "mailto:?subject=Parcel Map of :" +
xy + "&body=Check out this map: %0D%0A " +
window.location;
window.location.href = emailLink;
}
}
});
});
parcels.when(function(){
// Add a link into the InfoWindow Actions panel
var emailLink = domConstruct.create("a", {
"class": "action",
"innerHTML": "Email Map",
"href": "javascript:void(0);"
}, query(".actionList", view.popup.domNode)[0]);
//When users navigate through the history using the browser back/forward buttons select appropriate parcel
//http://developer.mozilla.org/en/DOM/Manipulating_the_browser_history
window.onpopstate = function (event) {
var parcelid = getParcelFromUrl(document.location.href);
var zoom = getZoomFromUrl(document.location.href);
var xy = getXYFromUrl(document.location.href);
if (parcelid || xy) {
if(parcelid){
selectParcel(parcelid, zoom);
}
if(xy){
selectParcelfromPoint(xy, zoom);
}
} else {
view.graphics.removeAll();
view.popup.close();
}
};
//if a parcelid is specified in url param select that feature
var parcelid = getParcelFromUrl(document.location.href);
var zoom = getZoomFromUrl(document.location.href);
var xy = getXYFromUrl(document.location.href);
if(parcelid){
selectParcel(parcelid, zoom);
}
if(xy){
selectParcelfromPoint(xy, zoom);
}
});
map.add(parcels);
//extract the parcel id from the url
function getParcelFromUrl(url) {
var urlObject = urlUtils.urlToObject(url);
if (urlObject.query && urlObject.query.parcelid) {
return urlObject.query.parcelid;
} else {
return null;
}
}
//extract the zoom from the url
function getZoomFromUrl(url) {
var urlObject = urlUtils.urlToObject(url);
if (urlObject.query && urlObject.query.zoom) {
return urlObject.query.zoom;
} else {
return null;
}
}
//extract the XY from the url
function getXYFromUrl(url) {
var urlObject = urlUtils.urlToObject(url);
if (urlObject.query && urlObject.query.xy) {
var xy = urlObject.query.xy.split(',');
var pnt = new Point({
x: xy[0],
y: xy[1],
spatialReference: view.spatialReference
});
return pnt;
} else {
return null;
}
}
//select parcel from the feature layer by creating a query to look for the input point
function selectParcelfromPoint(point, zoom) {
view.graphics.removeAll();
var query = parcels.createQuery();
query.geometry = point;
var deferred = parcels.queryFeatures(query).then(function (selection) {
var polygonGraphic = new Graphic({
geometry: selection.features[0].geometry,
symbol: fillSymbol
});
view.graphics.add(polygonGraphic);
var center = selection.features[0].geometry.extent.center;
var extHandler = view.watch("stationary", function () {
extHandler.remove();
//zoom to the center then display the popup
window.progSelection = true;
view.popup.open({
location: center,
features: selection.features,
updateLocationEnabled: true
});
});
view.goTo({
target: center,
zoom: parseInt(zoom) || 8
});
});
}
//select parcel from the feature layer by creating a query to look for the input parcel id
function selectParcel(parcelid, zoom) {
if (parcelid) {
view.graphics.removeAll();
var query = parcels.createQuery();
query.where = "PARCELID = '" + parcelid + "'";
var deferred = parcels.queryFeatures(query).then(function (selection) {
var polygonGraphic = new Graphic({
geometry: selection.features[0].geometry,
symbol: fillSymbol
});
view.graphics.add(polygonGraphic);
var center = selection.features[0].geometry.extent.center;
var extHandler = view.watch("stationary", function () {
extHandler.remove();
//zoom to the center then display the popup
window.progSelection = true;
view.popup.open({
location: center,
features: selection.features,
updateLocationEnabled: true
});
});
view.goTo({
target: center,
zoom: parseInt(zoom) || 8
});
});
}
}
});
</script>
</head>
<body class="claro">
<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline',gutters:false"
style="width: 100%; height: 100%; margin: 0;">
<div id="viewDiv" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
</div>
</body>
</html>