Good afternoon,
Take a look at this sample: https://developers.arcgis.com/javascript/latest/sample-code/sandbox/?sample=popup-custom-action
When you click o the map, spinner feature is shown before popup appears.
Is there a method to show or hide it programmatically when I need it? I am implementing my custom identify widget so ESRI's popup widget is out of question.
If no, what is the magic behind it? Is it just a simple feature with SVG symbol? Or is it drawn through custom WebGL layer? (something like that: https://developers.arcgis.com/javascript/latest/sample-code/custom-gl-visuals/) ?
Solved! Go to Solution.
The spinner you're talking about is a useful but undocumented widget with the path esri/widgets/Spinner. I've updated the sample's code below to show how it can be used. If you click somewhere on the map, the spinner will show. If you then click somewhere else, it will be hidden. You can repeat the process as many times as you like. In short, I added or updated lines 35, 36, 48-64, and 125.
Since this is an undocumented feature, it may be removed or altered in a future release without notice, so using it is at your own risk.
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>Custom popup actions per feature attribute | Sample | ArcGIS Maps SDK for JavaScript 4.30</title>
<style>
body {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
#viewDiv {
position: absolute;
right: 0;
left: 0;
top: 0;
bottom: 0;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.30/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.30/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/core/reactiveUtils",
"esri/popup/content/TextContent",
"esri/widgets/Spinner"
], (Map, MapView, FeatureLayer, reactiveUtils, TextContent, Spinner) => {
const map = new Map({
basemap: "streets-navigation-vector"
});
const view = new MapView({
container: "viewDiv",
map: map,
center: [-101.94981250000075, 41.20977753557709],
zoom: 5
});
const spinner = new Spinner({view:view});
view.ui.add(spinner, {key:"a-unique-key-you-make-up", position:"manual"});
view.on("click", function(evt) {
if (spinner.location)
hideSpinner();
else
showSpinner(evt.mapPoint);
});
function hideSpinner() {
spinner.location = null;
spinner.hide();
}
function showSpinner(point) {
spinner.show({location:point});
}
/********************
* Add feature layer
********************/
// sampling of breweries
const featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/OpenBeerDB/FeatureServer/0",
popupTemplate: {
title: "{name}",
outFields: ["*"],
lastEditInfoEnabled: false,
fieldInfos: [
{
fieldName: "name"
},
{
fieldName: "address1",
label: "address"
},
{
fieldName: "city"
},
{
fieldName: "state"
},
{
fieldName: "phone"
},
{
fieldName: "website"
}
],
actions: [
{
id: "find-brewery",
image: "https://developers.arcgis.com/javascript/latest/sample-code/popup-custom-action/live/beer.png",
title: "Brewery Info"
}
],
content: formatContent
}
});
// Use a function to format the content of the popup
function formatContent(event) {
const attributes = event.graphic.attributes;
let text = "";
// Only display the attributes if they exist
text += attributes.website
? `Brewery: <a href="${attributes.website}">${attributes.name}</a><br>`
: `Brewery: ${attributes.name}<br>`;
text += attributes.address1 ? `Address:<br>${attributes.address1}<br>` : `Located in: `;
text += attributes.city && attributes.state ? `${attributes.city},${attributes.state}<br>` : ``;
text += attributes.phone !== null ? `Phone:${attributes.phone}` : ``;
let textElement = new TextContent({
text: text
});
return [textElement];
}
// map.add(featureLayer);
view.when(() => {
// Watch for when features are selected
reactiveUtils.watch(
() => view.popup.selectedFeature,
(graphic) => {
if (graphic) {
// Set the action's visible property to true if the 'website' field value is not null, otherwise set it to false
const graphicTemplate = graphic.getEffectivePopupTemplate();
graphicTemplate.actions.items[0].visible = graphic.attributes.website ? true : false;
}
}
);
// Watch for the trigger-action event on the popup
reactiveUtils.on(
() => view.popup,
"trigger-action",
(event) => {
if (event.action.id === "find-brewery") {
const attributes = view.popup.selectedFeature.attributes;
// Get the 'website' field attribute
const info = attributes.website;
// Make sure the 'website' field value is not null
if (info) {
// Open up a new browser using the URL value in the 'website' field
window.open(info.trim());
}
}
}
);
});
});
</script>
</head>
<body class="light">
<div id="viewDiv" class="esri-widget"></div>
</body>
</html>
Hi @D_R_ ,
That loading spinner is actually part of the Sandbox code and that's the reason your not seeing anything in the sample code for it. It's just a Calcite Loader component:
https://developers.arcgis.com/calcite-design-system/components/loader/
This is a really basic usage example where it's shown by default and then hidden after a web map finishes loading.
https://codepen.io/sagewall/pen/bGPdByW
Hope this helps 😀
Edit. There are actually two loaders there one when the sample is loading and one for the pop-up. The pop-up loading spinner is part of the API code, but works similarly but using a temporary spinning graphic at the clicked location while creating the popup.
Thank you for reply 🙂
Ah, my bad: I guess I didn't explain myself properly. I was referring to small loading icon in "click point", not the one big initial loading icon, which is placed in the middle of the screen.
The spinner you're talking about is a useful but undocumented widget with the path esri/widgets/Spinner. I've updated the sample's code below to show how it can be used. If you click somewhere on the map, the spinner will show. If you then click somewhere else, it will be hidden. You can repeat the process as many times as you like. In short, I added or updated lines 35, 36, 48-64, and 125.
Since this is an undocumented feature, it may be removed or altered in a future release without notice, so using it is at your own risk.
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>Custom popup actions per feature attribute | Sample | ArcGIS Maps SDK for JavaScript 4.30</title>
<style>
body {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
overflow: hidden;
}
#viewDiv {
position: absolute;
right: 0;
left: 0;
top: 0;
bottom: 0;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.30/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.30/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/core/reactiveUtils",
"esri/popup/content/TextContent",
"esri/widgets/Spinner"
], (Map, MapView, FeatureLayer, reactiveUtils, TextContent, Spinner) => {
const map = new Map({
basemap: "streets-navigation-vector"
});
const view = new MapView({
container: "viewDiv",
map: map,
center: [-101.94981250000075, 41.20977753557709],
zoom: 5
});
const spinner = new Spinner({view:view});
view.ui.add(spinner, {key:"a-unique-key-you-make-up", position:"manual"});
view.on("click", function(evt) {
if (spinner.location)
hideSpinner();
else
showSpinner(evt.mapPoint);
});
function hideSpinner() {
spinner.location = null;
spinner.hide();
}
function showSpinner(point) {
spinner.show({location:point});
}
/********************
* Add feature layer
********************/
// sampling of breweries
const featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/OpenBeerDB/FeatureServer/0",
popupTemplate: {
title: "{name}",
outFields: ["*"],
lastEditInfoEnabled: false,
fieldInfos: [
{
fieldName: "name"
},
{
fieldName: "address1",
label: "address"
},
{
fieldName: "city"
},
{
fieldName: "state"
},
{
fieldName: "phone"
},
{
fieldName: "website"
}
],
actions: [
{
id: "find-brewery",
image: "https://developers.arcgis.com/javascript/latest/sample-code/popup-custom-action/live/beer.png",
title: "Brewery Info"
}
],
content: formatContent
}
});
// Use a function to format the content of the popup
function formatContent(event) {
const attributes = event.graphic.attributes;
let text = "";
// Only display the attributes if they exist
text += attributes.website
? `Brewery: <a href="${attributes.website}">${attributes.name}</a><br>`
: `Brewery: ${attributes.name}<br>`;
text += attributes.address1 ? `Address:<br>${attributes.address1}<br>` : `Located in: `;
text += attributes.city && attributes.state ? `${attributes.city},${attributes.state}<br>` : ``;
text += attributes.phone !== null ? `Phone:${attributes.phone}` : ``;
let textElement = new TextContent({
text: text
});
return [textElement];
}
// map.add(featureLayer);
view.when(() => {
// Watch for when features are selected
reactiveUtils.watch(
() => view.popup.selectedFeature,
(graphic) => {
if (graphic) {
// Set the action's visible property to true if the 'website' field value is not null, otherwise set it to false
const graphicTemplate = graphic.getEffectivePopupTemplate();
graphicTemplate.actions.items[0].visible = graphic.attributes.website ? true : false;
}
}
);
// Watch for the trigger-action event on the popup
reactiveUtils.on(
() => view.popup,
"trigger-action",
(event) => {
if (event.action.id === "find-brewery") {
const attributes = view.popup.selectedFeature.attributes;
// Get the 'website' field attribute
const info = attributes.website;
// Make sure the 'website' field value is not null
if (info) {
// Open up a new browser using the URL value in the 'website' field
window.open(info.trim());
}
}
}
);
});
});
</script>
</head>
<body class="light">
<div id="viewDiv" class="esri-widget"></div>
</body>
</html>