Select to view content in your preferred language

Click a point feature that opens a URL in a browser

2752
7
Jump to solution
07-16-2019 07:36 AM
MarquesMunson1
Regular Contributor

I am creating an application using JP 4.12 and I would like for the application to point to an URL within the attribute table of a feature layer when a user clicks on a point feature. I came across the following post and I tried the following code but it does not seem to work.

  1. //Code for the specific URL to open in a new window  
  2.   featureLayer.on('click',function(e){   
  3.     var specific = e.graphic.attributes['SpecificAttribute']   
  4.     window.open("http://YourUrl.com/"+specific);  
  5.   });  

In the SpecificAttribute, I have placed the name of the field that contains the URLs. 

  1. //Code for the specific URL to open in a new window  
  2.   featureLayer.on('click',function(e){   
  3.     var specific = e.graphic.attributes['Link']   
  4.     window.open(specific);  
  5.   });  

Any help would be greatly appreciated!

0 Kudos
1 Solution

Accepted Solutions
LizEidsness
Regular Contributor

It is your lucky day - I needed a break from what I was doing, and I learned some things along the way.

If you use this version (combination of the esri sample and your code), you'll notice there's a console.log output of the passport office name on map click. Line 205.  You can handle the rest I think.

A couple problems with your original.  I disabled popups on fLayer.  Consolidated the event handling because you have 3 views.  Complicated!  Also created a click handler!

There is a syntax highlighter in "More... "

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta name="viewport"
    content="initial-scale=1, maximum-scale=1,user-scalable=no" />
  <title>{PROTOTYPE} Passport Agency Map - JavaScript 4.12</title>

  <!--reference the JavaScript 4.12-->
  <link rel="stylesheet"
    href="https://js.arcgis.com/4.12/esri/themes/light/main.css" />
  <script src="https://js.arcgis.com/4.12/"></script>

  <style>
    html,
    body,
    #mainviewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }

    #hiViewDiv {
      padding: 0;
      margin: 0;
      height: 135px;
      width: 200px;
      background-color: rgba(255, 255, 255, 0.9);
      border-style: solid;
    }

    #prViewDiv {
      padding: 0;
      margin: 0;
      height: 135px;
      width: 200px;
      background-color: rgba(255, 255, 255, 0.9);
      border-style: solid;

    }

    /*Style for feature hover */

    .esri-feature {
      letter-spacing: 0em;
      line-height: 1.55rem;
      font-feature-settings: "liga"1, "calt"0;
      background: #fff;
      padding: 1em;
    }
  </style>

  <script>
    require([
      "esri/Map",
      "esri/widgets/Home",
      "esri/widgets/BasemapToggle",
      "esri/layers/FeatureLayer",
      "esri/views/MapView",
      "esri/widgets/Feature",
      "esri/widgets/Track",
      "esri/Graphic"
    ], function (Map, Home, BasemapToggle, FeatureLayer, MapView, Feature, Track, Graphic) {
      var fLayer = new FeatureLayer({
        portalItem: {
          id: "5710089ef1374c6d939ebee954c8b15c" //Portal ID number
        },
        popupEnabled: false,
        outFields: ["*"]
      });
      var map = new Map({
        basemap: "streets-navigation-vector",
        layers: [fLayer]
      });
      //Contiguous USA Main Map
      var mainView = new MapView({
        container: "mainviewDiv",
        map: map,
        extent: {
          spatialReference: {
            latestWkid: 3857,
            wkid: 102100
          },
          xmin: -14513000, //bounding box for the inital load of the application
          ymin: 2887000,
          xmax: -7390000,
          ymax: 6326000
        },
        constraints: {
          minScale: 39911104 //user cannot zoom out past this scale
        }
      });
      // Hawaii inset map
      var hiView = new MapView({
        container: "hiViewDiv",
        map: map,
        extent: {
          xmin: -17834000,
          ymin: 2111000,
          xmax: -17173000,
          ymax: 2573000,
          spatialReference: {
            wkid: 102100
          }
        },
        spatialReference: {
          wkid: 102100
        },
        ui: {
          components: []
        }
      });
      mainView.ui.add("hiViewDiv", "bottom-left");
      // Puerto Rico inset map
      var prView = new MapView({
        container: "prViewDiv",
        map: map,
        extent: {
          xmin: -7887000,
          ymin: 1924000,
          xmax: -6957000,
          ymax: 2257000,
          spatialReference: {
            wkid: 102100
          }
        },
        spatialReference: {
          wkid: 102100
        },
        ui: {
          components: []
        }
      });
      mainView.ui.add("prViewDiv", "bottom-right");
      //adding a home button
      var homeBtn = new Home({
        view: mainView
      }); // end of Home Button
      mainView.ui.add(homeBtn, "top-left"); //adding a home button to the top left under the zoom in/out
      var toggle = new BasemapToggle({
        view: mainView,
        nextBasemap: "satellite"
      }); //end of BasemapToggle
      mainView.ui.add(toggle, "top-left"); //adding basemap toggle to the top right

      var graphic = {
        popupTemplate: {
          content: "Mouse over passport icons to show details..."
        }
      };
      // Provide graphic to a new instance of a Feature widget
      var feature = new Feature({
        graphic: graphic,
        map: mainView.map,
        spatialReference: mainView.spatialReference
      });
      mainView.ui.add(feature, "top-right"); //adding feature hover widget to top right

      mainView.when().then(function () {
        // Create a default graphic for when the application starts
        return fLayer.when();

      }).then(function (layer) {
        return mainView.whenLayerView(layer);
      }).then(setupLayerEvent);


      prView
        .when()
        .then(function () {
          return fLayer.when();
        })
        .then(function (layer) {
          return prView.whenLayerView(layer);
        })
        .then(setupLayerEvent);
      hiView
        .when()
        .then(function () {
          return fLayer.when();
        })
        .then(function (layer) {
          return hiView.whenLayerView(layer);
        })
        .then(setupLayerEvent);

      function setupLayerEvent(layerView) {
        layerView.view.on("pointer-move", eventHandler);
        layerView.view.on("pointer-down", eventHandler);
        layerView.view.on("click", clickHandler);

        function eventHandler(event) {
          layerView.view.hitTest(event).then(getGraphics);
        }
        function clickHandler(event) {
          layerView.view.hitTest(event).then(function (response) {
            if (response.results.length) {
              const graphic = response.results.filter(function (result) {
                return result.graphic.layer === fLayer;
              })[0].graphic;

              const attributes = graphic.attributes;
              console.log(attributes.Name);  //continue here.
            } else {

            }

          });

        }

        let highlight, currentId;

        function getGraphics(response) {


          if (response.results.length) {
            const graphic = response.results.filter(function (result) {
              return result.graphic.layer === fLayer;
            })[0].graphic;

            const attributes = graphic.attributes;

            const URL = attributes.Link;
            const id = attributes.FID;
            if (
              highlight && currentId !== id
            ) {
              highlight.remove();
              highlight = null;
              return;
            }

            // highlight all features belonging to the same hurricane as the feature
            // returned from the hitTest
            const query = layerView.layer.createQuery();
            query.where = "FID = " + id;
            layerView.queryObjectIds(query).then(function (ids) {
              highlight = layerView.highlight(ids);
              feature.graphic = graphic;
              currentId = id;
            });

          } else {
            // remove the highlight if no features are
            // returned from the hitTest
            highlight.remove();
            highlight = null;
          }
        }
      }


    }); // end of Main function
  </script>
</head>

<body>
  <div id="mainviewDiv" class="esri-widget"></div>
  <div id="hiViewDiv" class="esri-widget"></div>
  <div id="prViewDiv" class="esri-widget"></div>
</body>

</html>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

0 Kudos
7 Replies
LizEidsness
Regular Contributor

Does the event fire? (add console.log entry) or is it the popup itself not working?

0 Kudos
MarquesMunson1
Regular Contributor

The pop-up works and I can access the external website if I click on the icon and then click on the link within the pop-up. I would like to skip the pop-up altogether and when I click on the icon, it goes straight to the external website. I have a feature hover for accessing the info in the pop-up. Hope that helps.

0 Kudos
LizEidsness
Regular Contributor

There's a couple things going on.  Popups need to be disabled on view/layer, or manually handled.  Also FeatureLayer doesn't have a click event.

This sample might help: https://developers.arcgis.com/javascript/latest/sample-code/view-hittest/index.html

In this sample, the view events are handled manually.  It has a lot more going on, but hopefully the event flow can help.

In codepen, after line 139 - I added window.open("http://google.ca");

and on feature click (not mouse over) it opens a window to google.

0 Kudos
MarquesMunson1
Regular Contributor

Here is the code below in full. I am not sure how to copy/paste with the line numbers on the side like in other posts, so sorry if it looks confusing. Would the click event go in the mainView.WhenLayerView function?

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1, maximum-scale=1,user-scalable=no"
/>
<title>{PROTOTYPE} Passport Agency Map - JavaScript 4.12</title>

<!--reference the JavaScript 4.12-->
<link rel="stylesheet" href="https://js.arcgis.com/4.12/esri/themes/light/main.css"/>
<script src="https://js.arcgis.com/4.12/"></script>

<style>
html,
body,
#mainviewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}

#hiViewDiv {
padding: 0;
margin: 0;
height: 135px;
width: 200px;
background-color: rgba(255, 255, 255, 0.9);
border-style: solid;
}

#prViewDiv{
padding: 0;
margin: 0;
height: 135px;
width: 200px;
background-color: rgba(255, 255, 255, 0.9);
border-style: solid;

}

/*Style for feature hover */
.esri-feature {
letter-spacing: 0em;
line-height: 1.55rem;
font-feature-settings: "liga" 1, "calt" 0;
background: #fff;
padding: 1em;
}
</style>

<script>
require([
"esri/Map",
"esri/widgets/Home",
"esri/widgets/BasemapToggle",
"esri/layers/FeatureLayer",
"esri/views/MapView",
"esri/widgets/Feature",
"esri/widgets/Track",
"esri/Graphic"
], function(Map, Home, BasemapToggle, FeatureLayer, MapView, Feature, Track, Graphic) {


var fLayer = new FeatureLayer({
portalItem: {
id: "5710089ef1374c6d939ebee954c8b15c" //Portal ID number
},
popupTemplate: {
title: "{Name}",
content: [
{
type: "fields",
fieldInfos: [
{
fieldName: "Status"
},
{
fieldName: "Address2",
label: "Address"
},
{
fieldName: "Link",
label: "Visit Main Page"
},
{
fieldName: "Directions",
label: "Get Directions"
}
]
}
]
}
});

var map = new Map({
basemap: "streets-navigation-vector",
layers: [fLayer]
});

//Contiguous USA Main Map
var mainView = new MapView({
container: "mainviewDiv",
map: map,
extent: {
spatialReference: {
latestWkid: 3857,
wkid: 102100
},
xmin: -14513000, //bounding box for the inital load of the application
ymin: 2887000,
xmax: -7390000,
ymax: 6326000
},

constraints: {
minScale: 39911104 //user cannot zoom out past this scale
}
});

// Hawaii inset map
var hiView = new MapView({
container: "hiViewDiv",
map: map,
extent: {
xmin: -17834000,
ymin: 2111000,
xmax: -17173000,
ymax: 2573000,
spatialReference: {
wkid: 102100
}
},
spatialReference: {
wkid: 102100
},
ui: {
components: []
}
});

mainView.ui.add("hiViewDiv", "bottom-left");

// Puerto Rico inset map
var prView = new MapView({
container: "prViewDiv",
map: map,
extent: {
xmin: -7887000,
ymin: 1924000,
xmax: -6957000,
ymax: 2257000,
spatialReference: {
wkid: 102100
}
},
spatialReference: {
wkid: 102100
},
ui: {
components: []
}
});

mainView.ui.add("prViewDiv", "bottom-right");

//adding a home button
var homeBtn = new Home({
view: mainView
}); // end of Home Button

mainView.ui.add(homeBtn, "top-left"); //adding a home button to the top left under the zoom in/out
var toggle = new BasemapToggle ({
view: mainView,
nextBasemap: "satellite"
}); //end of BasemapToggle
mainView.ui.add(toggle, "top-left"); //adding basemap toggle to the top right
mainView.when().then(function() {

// Create a default graphic for when the application starts
var graphic = {
popupTemplate: {
content: "Mouse over passport icons to show details..."
}
};

// Provide graphic to a new instance of a Feature widget
var feature = new Feature({
graphic: graphic,
map: mainView.map,
spatialReference: mainView.spatialReference
});

mainView.ui.add(feature, "top-right"); //adding feature hover widget to top right

mainView.whenLayerView(fLayer).then(function(layerView) {
let highlight;
// listen for the pointer-move event on the View
mainView.on("pointer-move", function(event) {
// Perform a hitTest on the View
mainView.hitTest(event).then(function(event) {
// Make sure graphic has a popupTemplate
let results = event.results.filter(function(result) {
return result.graphic.layer.popupTemplate;
});
let result = results[0];
highlight && highlight.remove();
// Update the graphic of the Feature widget
// on pointer-move with the result
if (result) {
feature.graphic = result.graphic;
highlight = layerView.highlight(result.graphic);
} else {
feature.graphic = graphic;
}
});
});
///enabling feature hover for Hawaii inset map
hiView.on("pointer-move", function(event) {
// Perform a hitTest on the View
hiView.hitTest(event).then(function(event) {
// Make sure graphic has a popupTemplate
let results = event.results.filter(function(result) {
return result.graphic.layer.popupTemplate;
});
let result = results[0];
highlight && highlight.remove();
// Update the graphic of the Feature widget
// on pointer-move with the result
if (result) {
feature.graphic = result.graphic;
highlight = layerView.highlight(result.graphic);
} else {
feature.graphic = graphic;
}
});
}); // end hawaii feature hover

///enabling feature hover for puerto rico inset map
prView.on("pointer-move", function(event) {
// Perform a hitTest on the View
prView.hitTest(event).then(function(event) {
// Make sure graphic has a popupTemplate
let results = event.results.filter(function(result) {
return result.graphic.layer.popupTemplate;
});
let result = results[0];
highlight && highlight.remove();
// Update the graphic of the Feature widget
// on pointer-move with the result
if (result) {
feature.graphic = result.graphic;
highlight = layerView.highlight(result.graphic);
} else {
feature.graphic = graphic;
}
});
}); // end puerto rico feature hover

});

}); // end of view.when function

}); // end of Main function
</script>
</head>

<body>
<div id="mainviewDiv" class="esri-widget"></div>
<div id="hiViewDiv" class="esri-widget"></div>
<div id="prViewDiv" class="esri-widget"></div>
</body>
</html>
0 Kudos
LizEidsness
Regular Contributor

It is your lucky day - I needed a break from what I was doing, and I learned some things along the way.

If you use this version (combination of the esri sample and your code), you'll notice there's a console.log output of the passport office name on map click. Line 205.  You can handle the rest I think.

A couple problems with your original.  I disabled popups on fLayer.  Consolidated the event handling because you have 3 views.  Complicated!  Also created a click handler!

There is a syntax highlighter in "More... "

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta name="viewport"
    content="initial-scale=1, maximum-scale=1,user-scalable=no" />
  <title>{PROTOTYPE} Passport Agency Map - JavaScript 4.12</title>

  <!--reference the JavaScript 4.12-->
  <link rel="stylesheet"
    href="https://js.arcgis.com/4.12/esri/themes/light/main.css" />
  <script src="https://js.arcgis.com/4.12/"></script>

  <style>
    html,
    body,
    #mainviewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }

    #hiViewDiv {
      padding: 0;
      margin: 0;
      height: 135px;
      width: 200px;
      background-color: rgba(255, 255, 255, 0.9);
      border-style: solid;
    }

    #prViewDiv {
      padding: 0;
      margin: 0;
      height: 135px;
      width: 200px;
      background-color: rgba(255, 255, 255, 0.9);
      border-style: solid;

    }

    /*Style for feature hover */

    .esri-feature {
      letter-spacing: 0em;
      line-height: 1.55rem;
      font-feature-settings: "liga"1, "calt"0;
      background: #fff;
      padding: 1em;
    }
  </style>

  <script>
    require([
      "esri/Map",
      "esri/widgets/Home",
      "esri/widgets/BasemapToggle",
      "esri/layers/FeatureLayer",
      "esri/views/MapView",
      "esri/widgets/Feature",
      "esri/widgets/Track",
      "esri/Graphic"
    ], function (Map, Home, BasemapToggle, FeatureLayer, MapView, Feature, Track, Graphic) {
      var fLayer = new FeatureLayer({
        portalItem: {
          id: "5710089ef1374c6d939ebee954c8b15c" //Portal ID number
        },
        popupEnabled: false,
        outFields: ["*"]
      });
      var map = new Map({
        basemap: "streets-navigation-vector",
        layers: [fLayer]
      });
      //Contiguous USA Main Map
      var mainView = new MapView({
        container: "mainviewDiv",
        map: map,
        extent: {
          spatialReference: {
            latestWkid: 3857,
            wkid: 102100
          },
          xmin: -14513000, //bounding box for the inital load of the application
          ymin: 2887000,
          xmax: -7390000,
          ymax: 6326000
        },
        constraints: {
          minScale: 39911104 //user cannot zoom out past this scale
        }
      });
      // Hawaii inset map
      var hiView = new MapView({
        container: "hiViewDiv",
        map: map,
        extent: {
          xmin: -17834000,
          ymin: 2111000,
          xmax: -17173000,
          ymax: 2573000,
          spatialReference: {
            wkid: 102100
          }
        },
        spatialReference: {
          wkid: 102100
        },
        ui: {
          components: []
        }
      });
      mainView.ui.add("hiViewDiv", "bottom-left");
      // Puerto Rico inset map
      var prView = new MapView({
        container: "prViewDiv",
        map: map,
        extent: {
          xmin: -7887000,
          ymin: 1924000,
          xmax: -6957000,
          ymax: 2257000,
          spatialReference: {
            wkid: 102100
          }
        },
        spatialReference: {
          wkid: 102100
        },
        ui: {
          components: []
        }
      });
      mainView.ui.add("prViewDiv", "bottom-right");
      //adding a home button
      var homeBtn = new Home({
        view: mainView
      }); // end of Home Button
      mainView.ui.add(homeBtn, "top-left"); //adding a home button to the top left under the zoom in/out
      var toggle = new BasemapToggle({
        view: mainView,
        nextBasemap: "satellite"
      }); //end of BasemapToggle
      mainView.ui.add(toggle, "top-left"); //adding basemap toggle to the top right

      var graphic = {
        popupTemplate: {
          content: "Mouse over passport icons to show details..."
        }
      };
      // Provide graphic to a new instance of a Feature widget
      var feature = new Feature({
        graphic: graphic,
        map: mainView.map,
        spatialReference: mainView.spatialReference
      });
      mainView.ui.add(feature, "top-right"); //adding feature hover widget to top right

      mainView.when().then(function () {
        // Create a default graphic for when the application starts
        return fLayer.when();

      }).then(function (layer) {
        return mainView.whenLayerView(layer);
      }).then(setupLayerEvent);


      prView
        .when()
        .then(function () {
          return fLayer.when();
        })
        .then(function (layer) {
          return prView.whenLayerView(layer);
        })
        .then(setupLayerEvent);
      hiView
        .when()
        .then(function () {
          return fLayer.when();
        })
        .then(function (layer) {
          return hiView.whenLayerView(layer);
        })
        .then(setupLayerEvent);

      function setupLayerEvent(layerView) {
        layerView.view.on("pointer-move", eventHandler);
        layerView.view.on("pointer-down", eventHandler);
        layerView.view.on("click", clickHandler);

        function eventHandler(event) {
          layerView.view.hitTest(event).then(getGraphics);
        }
        function clickHandler(event) {
          layerView.view.hitTest(event).then(function (response) {
            if (response.results.length) {
              const graphic = response.results.filter(function (result) {
                return result.graphic.layer === fLayer;
              })[0].graphic;

              const attributes = graphic.attributes;
              console.log(attributes.Name);  //continue here.
            } else {

            }

          });

        }

        let highlight, currentId;

        function getGraphics(response) {


          if (response.results.length) {
            const graphic = response.results.filter(function (result) {
              return result.graphic.layer === fLayer;
            })[0].graphic;

            const attributes = graphic.attributes;

            const URL = attributes.Link;
            const id = attributes.FID;
            if (
              highlight && currentId !== id
            ) {
              highlight.remove();
              highlight = null;
              return;
            }

            // highlight all features belonging to the same hurricane as the feature
            // returned from the hitTest
            const query = layerView.layer.createQuery();
            query.where = "FID = " + id;
            layerView.queryObjectIds(query).then(function (ids) {
              highlight = layerView.highlight(ids);
              feature.graphic = graphic;
              currentId = id;
            });

          } else {
            // remove the highlight if no features are
            // returned from the hitTest
            highlight.remove();
            highlight = null;
          }
        }
      }


    }); // end of Main function
  </script>
</head>

<body>
  <div id="mainviewDiv" class="esri-widget"></div>
  <div id="hiViewDiv" class="esri-widget"></div>
  <div id="prViewDiv" class="esri-widget"></div>
</body>

</html>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
MarquesMunson1
Regular Contributor

Thank you for helping! I am still trying to figure out the rest. However, now the feature pop-up on the top right does not disappear and is covering up some of the points to  the northeast.

0 Kudos
LizEidsness
Regular Contributor

Glad I could help!

It will always be hard to keep things on top of the map without covering something.  It's also depends on the browser size, or container if this will be in an iframe.  

Have fun!

0 Kudos