Select to view content in your preferred language

How to show/hide spinner feature programmatically?

363
3
Jump to solution
07-12-2024 04:45 AM
D_R_
by
Occasional Contributor

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/) ?

1 Solution

Accepted Solutions
JoelBennett
MVP Regular Contributor

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>

 

View solution in original post

3 Replies
Sage_Wall
Esri Contributor

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.

0 Kudos
D_R_
by
Occasional Contributor

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.

0 Kudos
JoelBennett
MVP Regular Contributor

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>