pop-ups not displaying correctly on mobile device

2806
10
Jump to solution
10-17-2018 07:52 AM
JaredPilbeam2
MVP Regular Contributor

I think the header is causing this. Viewing an app without a header the popups display fine on all mobile devices I've tested on. But, when I have a header the popups are way off the screen on phones and fine on a PC or I-Pad. I'm thinking there's a mobile friendly solution here, which is what my question is about. 

I've tested on both actual phones and through Chrome and Firefox's mobile device developer tools. Here's how the popup displays on an I-Phone 4, or any other mobile device, with a header: 

I Phone 4

Here's the whole pop-up viewed from my PC:

whole_popup

I need a header, so getting rid of it is out of the question. I've put this question to Esri last week, but haven't heard back yet. Our server doesn't yet have a security certificate for https, only http. This may be part of the problem. We're getting one soon. 

One other weird thing is that when I close the pop-up the entire header disappears. It comes back when I refresh.

Here is my entire app:

<!DOCTYPE html>
<html>

<head>
    <link rel="icon" href="http://www.willcogis.org/website2014/gis/images/gisseal_thumbnail.png">
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
    <title>Will County Attractions</title>

    <link rel="stylesheet" href="https://js.arcgis.com/4.9/esri/css/main.css">


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

        /*search*/
        #searchParentDiv {
            height: 100%;
        }

        /*search*/
        .esri-search {
            border: solid 3px red;
        }

        div.a {
            /* center the header*/
            text-align: center;

        }

        /* Style the header */
        header {
            background-color: whitesmoke;
            padding: 1px;
            font-size: 12px;
            font-family: 'Sans Serif';
            color: black;
        }

        .esri-legend__layer-caption {
            display: none;
        }

        /*query dropdown*/
        #infoDiv {
            background-color: black;
            color: white;
            font-family: 'Sans Serif';
            padding: 2px;
            width: 2000px;
        }

        /*query*/
        #results {
            font-weight: bolder;
        }
    </style>

    <script src="https://js.arcgis.com/4.9/"></script>

    <script>
        require([
            "esri/Map",
            "esri/views/MapView",
            "esri/layers/FeatureLayer",
            "esri/layers/GraphicsLayer",
            "esri/widgets/Search",
            "esri/widgets/Home",
            "esri/widgets/Legend",
            "esri/widgets/Expand",
            "dojo/domReady!"
        ],
            function (
                Map, MapView, FeatureLayer, GraphicsLayer, Search, Home, Legend, Expand
            ) {

                //set basemap
                var map = new Map({
                    basemap: "topo",
                });

                //set map view
                var view = new MapView({
                    container: "viewDiv",
                    map: map,
                    scale: 500000,
                    center: [-87.95, 41.4],
                    //popup settings for attractions layer
                    popup: {
                        dockEnabled: true,
                        dockOptions: {
                            //set dock/undock button from on pop-up
                            buttonEnabled: false,
                            //ignore the default sizes that trigger responsive docking
                            breakpoint: false,
                        }
                    }
                });
                //***widgets***
                //home widget
                var homeBtn = new Home({
                    view: view,
                });
                view.ui.add(homeBtn, "top-left");

                //search widget
                var searchWidget = new Search({
                    view: view,
                    container: "searchDiv"
                });

                //legend widget
                var legend = new Expand({
                    content: new Legend({
                        view: view,
                        //style: "card"
                    }),
                    view: view,
                    expanded: false
                });
                view.ui.add(legend, "top-left");

                //***popups***
                //popup template
                var template = { //autocasts the new template
                    title: "<img src= {logo}><font color= '#008000'>{Name}",
                    content: [{ //set content elements in the order to display
                        type: "fields",
                        fieldInfos: [{
                            fieldName: "Type",
                            label: "Type",
                            visible: true,
                        }, {
                            fieldName: "Address",
                            label: "Address",
                            visible: true,
                        }, {
                            fieldName: "Website",
                            label: "Website",
                            visible: true,
                        }, {
                            fieldName: "Photo",
                            label: "Photo",
                            visible: false,
                        }
                        ]
                    }, {
                        // You can set a media element within the popup as well. This
                        // can be either an image or a chart. You specify this within
                        // the mediaInfos. Similar to text elements, media can only be set within the content.
                        type: "media",
                        mediaInfos: [{
                            type: "image",
                            value: { sourceURL: "{Photo}" }
                        }]
                    }]
                };
                var template2 = { //autocasts the new template
                    title: "<font color= '#008000'>Route 66",
                    content: [{ //set content elements in the order to display
                        type: "fields",
                        fieldInfos: [{
                            fieldName: "Photo",
                            label: "Photo",
                            visible: false,
                        }
                        ]
                    }, {
                        type: "media",
                        mediaInfos: [{
                            type: "image",
                            value: { sourceURL: "{Photo}" }
                        }]
                    }]
                };
                var template3 = { //autocasts the new template
                    title: "<font color= '#008000'>Illinois & Michigan Canal",
                    content: [{ //set content elements in the order to display
                        type: "fields",
                        fieldInfos: [{
                            fieldName: "Photo",
                            label: "Photo",
                            visible: true,
                        }
                        ]
                    }, {
                        type: "media",
                        mediaInfos: [{
                            type: "image",
                            value: { sourceURL: "{Photo}" }
                        }]
                    }]
                };

                //***feature layers***
                //add will county boundary
                var boundary = new FeatureLayer({
                    url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/County_Limits/FeatureServer/0?toke...",
                    //id: "boundary",
                });
                map.add(boundary);

                //add Rt 66    
                var rt66 = new FeatureLayer({
                    url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Rte_66/FeatureServer/0?token=xWHh8...",
                    // id: "rt66",
                    popupTemplate: template2,
                    outFields: ["*"]
                });
                map.add(rt66);

                //add canal
                var canal = new FeatureLayer({
                    url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Illinois_and_Michigan_Canal/Featur...",
                    popupTemplate: template3,
                    //id: "canal",
                });
                map.add(canal);

                //add preserves
                var preserves = new FeatureLayer({
                    url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Will_County_Forest_Preserves/Featu...",
                    //id: "preserves",
                    //zoom: 1,
                });
                map.add(preserves);

                //add attraction feature layer
                //reference the popup template instance in the popuptmeplate property of featurelayer
                var attractions = new FeatureLayer({
                    url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Attractions/FeatureServer/0?token=...",
                    id: "attractions",
                    visible: true,
                    popupTemplate: template,
                    outFields: ["*"]
                });
                map.add(attractions);



                //***From here down deals with the query by type dropdown menu***
                var attTypeSelect = document.getElementById("attractions");
                view.ui.add("infoDiv", "left");
                //query all features from the attractions layer
                view.when(function () {
                    return attractions.when(function () {
                        var query = attractions.createQuery();
                        return attractions.queryFeatures(query);
                    });
                })
                    .then(getValues)
                    .then(getUniqueValues)
                    .then(addToSelect);

                // return an array of all the values in the
                // Type field of the attractions layer
                function getValues(response) {
                    var features = response.features;
                    var values = features.map(function (feature) {
                        return feature.attributes.Type;
                    });
                    return values;
                }

                // return an array of unique values in
                // the Type field of the attractions layer
                function getUniqueValues(values) {
                    var uniqueValues = [];

                    values.forEach(function (item, i) {
                        if ((uniqueValues.length < 1 || uniqueValues.indexOf(item) === -1) &&
                            (item !== "")) {
                            uniqueValues.push(item);
                        }
                    });
                    return uniqueValues;
                }

                // Add the unique values to the attractions type
                // select element. This will allow the user
                // to filter attractions by type.
                function addToSelect(values) {
                    values.sort();
                    values.forEach(function (value) {
                        var option = document.createElement("option");
                        option.text = value;
                        attTypeSelect.add(option);
                    });

                    return setattractionsDefinitionExpression(attTypeSelect.value);
                }

                // set the definition expression on the attractions
                // layer to reflect the selection of the user
                function setattractionsDefinitionExpression(newValue) {
                    attractions.definitionExpression = "Type = '" + newValue + "'";
                    if (!attractions.visible) {
                        attractions.visible = true;
                    }

                    return queryForAttractionGeometries();
                }
                // set a new definitionExpression on the attractions layer
                attTypeSelect.addEventListener("change", function () {
                    var type = event.target.value;
                    setattractionsDefinitionExpression(type);
                });
                // Get all the geometries of the attractions layer
                // the createQuery() method creates a query
                // object that respects the definitionExpression
                // of the layer
                function queryForAttractionGeometries() {
                    var attractionsQuery = attractions.createQuery();

                    return attractions.queryFeatures(attractionsQuery)
                        .then(function (response) {
                            attractionsGeometries = response.features.map(function (feature) {
                                return feature.geometry;
                            });

                            return attractionsGeometries;
                        });
                }

            }
        )
    </script>

</head>

<body>
    <header>
        <p><img src="http://www.willcogis.org/website2014/gis/images/gisseal_thumbnail.png" alt="GIS Seal" style="float:left;width:48px;height:46px;">
            <div id="searchParentDiv" style="float:right;width:250px;height:46px;">
                <div id="searchDiv"></div>
            </div>
            <div class="a">
                <h1 class="local">Will County Attractions</h1>
            </div>
    </header>
    <div id="infoDiv">
        Select attractions type:
        <select id="attractions"></select>
    </div>
    <div id="viewDiv"></div>
</body>

</html>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Who in the world still has an iPhone 4? lol.

Try this then.

<!DOCTYPE html>
<html>

<head>
  <link rel="icon" href="http://www.willcogis.org/website2014/gis/images/gisseal_thumbnail.png">
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Will County Attractions</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.9/esri/css/main.css">

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

    #viewDiv {
      height: calc(100% - 75px);
    }

    /*search*/
    #searchParentDiv {
      height: 100%;
    }

    /*search*/
    .esri-search {
      border: solid 3px red;
      margin-top: 7px;
      margin-right: 7px;
    }

    div.a {
      /* center the header*/
      text-align: center;
    }

    /* Style the header */
    header.app_header {
      background-color: whitesmoke;
      padding: 1px;
      font-size: 12px;
      font-family: 'Sans Serif';
      color: black;
      max-height: 50px;
    }

    .esri-legend__layer-caption {
      display: none;
    }

    /*query dropdown*/
    #infoDiv {
      background-color: black;
      color: white;
      font-family: 'Sans Serif';
      padding: 2px;
      width: 100%;
    }

    /*query*/
    #results {
      font-weight: bolder;
    }

    @media (max-width: 480px) {
      h1 {
        visibility: hidden;
      }
      #infoDiv {
        font-size: 10px;
      }
    }

  </style>

  <script src="https://js.arcgis.com/4.9/"></script>

  <script>
    require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/FeatureLayer",
        "esri/layers/GraphicsLayer",
        "esri/widgets/Search",
        "esri/widgets/Home",
        "esri/widgets/Legend",
        "esri/widgets/Expand",
        "dojo/domReady!"
      ],
      function(
        Map, MapView, FeatureLayer, GraphicsLayer, Search, Home, Legend, Expand
      ) {

        //set basemap
        var map = new Map({
          basemap: "topo",
        });

        //set map view
        var view = new MapView({
          container: "viewDiv",
          map: map,
          scale: 500000,
          center: [-87.95, 41.4],
          //popup settings for attractions layer
          popup: {
            dockEnabled: true,
            dockOptions: {
              //set dock/undock button from on pop-up
              buttonEnabled: false,
              //ignore the default sizes that trigger responsive docking
              breakpoint: false,
            }
          }
        });
        //***widgets***
        //home widget
        var homeBtn = new Home({
          view: view,
        });
        view.ui.add(homeBtn, "top-left");

        //search widget
        var searchWidget = new Search({
          view: view,
          container: "searchDiv"
        });

        //legend widget
        var legend = new Expand({
          content: new Legend({
            view: view,
            //style: "card"
          }),
          view: view,
          expanded: false
        });
        view.ui.add(legend, "top-left");

        //***popups***
        //popup template
        var template = { //autocasts the new template
          title: "<img src={logo} height='20' width='20'><font color= '#008000'>{Name}",
          content: [{ //set content elements in the order to display
            type: "fields",
            fieldInfos: [{
              fieldName: "Type",
              label: "Type",
              visible: true,
            }, {
              fieldName: "Address",
              label: "Address",
              visible: true,
            }, {
              fieldName: "Website",
              label: "Website",
              visible: true,
            }, {
              fieldName: "Photo",
              label: "Photo",
              visible: false,
            }]
          }, {
              // You can set a media element within the popup as well. This
              // can be either an image or a chart. You specify this within
              // the mediaInfos. Similar to text elements, media can only be set within the content.
              type: "media",
              mediaInfos: [{
                type: "image",
                value: {
                  sourceURL: "{Photo}"
                }
              }]
            }]
        };
        var template2 = { //autocasts the new template
          title: "<font color= '#008000'>Route 66",
          content: [{ //set content elements in the order to display
            type: "fields",
            fieldInfos: [{
              fieldName: "Photo",
              label: "Photo",
              visible: false,
            }]
          }, {
            type: "media",
            mediaInfos: [{
              type: "image",
              value: {
                sourceURL: "{Photo}"
              }
            }]
          }]
        };
        var template3 = { //autocasts the new template
          title: "<font color= '#008000'>Illinois & Michigan Canal",
          content: [{ //set content elements in the order to display
            type: "fields",
            fieldInfos: [{
              fieldName: "Photo",
              label: "Photo",
              visible: true,
            }]
          }, {
            type: "media",
            mediaInfos: [{
              type: "image",
              value: {
                sourceURL: "{Photo}"
              }
            }]
          }]
        };

        //***feature layers***
        //add will county boundary
        var boundary = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/County_Limits/FeatureServer/0?toke...",
          //id: "boundary",
        });
        map.add(boundary);

        //add Rt 66
        var rt66 = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Rte_66/FeatureServer/0?token=xWHh8...",
          // id: "rt66",
          popupTemplate: template2,
          outFields: ["*"]
        });
        map.add(rt66);

        //add canal
        var canal = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Illinois_and_Michigan_Canal/Featur...",
          popupTemplate: template3,
          //id: "canal",
        });
        map.add(canal);

        //add preserves
        var preserves = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Will_County_Forest_Preserves/Featu...",
          //id: "preserves",
          //zoom: 1,
        });
        map.add(preserves);

        //add attraction feature layer
        //reference the popup template instance in the popuptmeplate property of featurelayer
        var attractions = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Attractions/FeatureServer/0?token=...",
          id: "attractions",
          visible: true,
          popupTemplate: template,
          outFields: ["*"]
        });
        map.add(attractions);

        //***From here down deals with the query by type dropdown menu***
        var attTypeSelect = document.getElementById("attractions");
        view.ui.add("infoDiv", "left");
        //query all features from the attractions layer
        view.when(function() {
            return attractions.when(function() {
              var query = attractions.createQuery();
              return attractions.queryFeatures(query);
            });
          })
          .then(getValues)
          .then(getUniqueValues)
          .then(addToSelect);

        // return an array of all the values in the
        // Type field of the attractions layer
        function getValues(response) {
          var features = response.features;
          var values = features.map(function(feature) {
            return feature.attributes.Type;
          });
          return values;
        }

        // return an array of unique values in
        // the Type field of the attractions layer
        function getUniqueValues(values) {
          var uniqueValues = [];

          values.forEach(function(item, i) {
            if ((uniqueValues.length < 1 || uniqueValues.indexOf(item) === -1) &&
              (item !== "")) {
              uniqueValues.push(item);
            }
          });
          return uniqueValues;
        }

        // Add the unique values to the attractions type
        // select element. This will allow the user
        // to filter attractions by type.
        function addToSelect(values) {
          values.sort();
          values.forEach(function(value) {
            var option = document.createElement("option");
            option.text = value;
            attTypeSelect.add(option);
          });

          return setattractionsDefinitionExpression(attTypeSelect.value);
        }

        // set the definition expression on the attractions
        // layer to reflect the selection of the user
        function setattractionsDefinitionExpression(newValue) {
          attractions.definitionExpression = "Type = '" + newValue + "'";
          if (!attractions.visible) {
            attractions.visible = true;
          }

          return queryForAttractionGeometries();
        }

        // set a new definitionExpression on the attractions layer
        attTypeSelect.addEventListener("change", function() {
          var type = event.target.value;
          setattractionsDefinitionExpression(type);
        });

        // Get all the geometries of the attractions layer
        // the createQuery() method creates a query
        // object that respects the definitionExpression
        // of the layer
        function queryForAttractionGeometries() {
          var attractionsQuery = attractions.createQuery();
          return attractions.queryFeatures(attractionsQuery)
            .then(function(response) {
              attractionsGeometries = response.features.map(function(feature) {
                return feature.geometry;
              });
              return attractionsGeometries;
            });
        }
      }
    )
  </script>

</head>

<body>
  <header class="app_header">
    <img src="http://www.willcogis.org/website2014/gis/images/gisseal_thumbnail.png" alt="GIS Seal" style="float:left;width:48px;height:46px;">
      <div id="searchParentDiv" style="float:right;">
        <div id="searchDiv"></div>
      </div>
      <div class="a">
        <h1 class="local">Will County Attractions</h1>
      </div>
  </header>
  <div id="infoDiv">
    Select attractions type:
    <select id="attractions"></select>
  </div>
  <div id="viewDiv"></div>
</body>

</html>

View solution in original post

0 Kudos
10 Replies
RobertScheitlin__GISP
MVP Emeritus

Jared,

   Your issue was all css rules issues. Here is your code fixed:

<!DOCTYPE html>
<html>

<head>
  <link rel="icon" href="http://www.willcogis.org/website2014/gis/images/gisseal_thumbnail.png">
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Will County Attractions</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.9/esri/css/main.css">

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

    #viewDiv {
      height: calc(100% - 75px);
      /* needed to set the height of the view minus the header */
    }

    /*search*/
    #searchParentDiv {
      height: 100%;
    }

    /*search*/
    .esri-search {
      border: solid 3px red;
      margin-top: 7px;
      margin-right: 7px;
    }

    div.a {
      /* center the header*/
      text-align: center;
    }

    /* Style the header */
    header.app_header {
      background-color: whitesmoke;
      padding: 1px;
      font-size: 12px;
      font-family: 'Sans Serif';
      color: black;
      max-height: 50px;
    }

    .esri-legend__layer-caption {
      display: none;
    }

    /*query dropdown*/
    #infoDiv {
      background-color: black;
      color: white;
      font-family: 'Sans Serif';
      padding: 2px;
      width: 2000px;
    }

    /*query*/
    #results {
      font-weight: bolder;
    }

    @media (max-width: 480px) {
      h1 {
        visibility: hidden;
      }
    }

  </style>

  <script src="https://js.arcgis.com/4.9/"></script>

  <script>
    require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/FeatureLayer",
        "esri/layers/GraphicsLayer",
        "esri/widgets/Search",
        "esri/widgets/Home",
        "esri/widgets/Legend",
        "esri/widgets/Expand",
        "dojo/domReady!"
      ],
      function(
        Map, MapView, FeatureLayer, GraphicsLayer, Search, Home, Legend, Expand
      ) {

        //set basemap
        var map = new Map({
          basemap: "topo",
        });

        //set map view
        var view = new MapView({
          container: "viewDiv",
          map: map,
          scale: 500000,
          center: [-87.95, 41.4],
          //popup settings for attractions layer
          popup: {
            dockEnabled: true,
            dockOptions: {
              //set dock/undock button from on pop-up
              buttonEnabled: false,
              //ignore the default sizes that trigger responsive docking
              breakpoint: false,
            }
          }
        });
        //***widgets***
        //home widget
        var homeBtn = new Home({
          view: view,
        });
        view.ui.add(homeBtn, "top-left");

        //search widget
        var searchWidget = new Search({
          view: view,
          container: "searchDiv"
        });

        //legend widget
        var legend = new Expand({
          content: new Legend({
            view: view,
            //style: "card"
          }),
          view: view,
          expanded: false
        });
        view.ui.add(legend, "top-left");

        //***popups***
        //popup template
        var template = { //autocasts the new template
          title: "<img src={logo}><font color= '#008000'>{Name}",
          content: [{ //set content elements in the order to display
            type: "fields",
            fieldInfos: [{
              fieldName: "Type",
              label: "Type",
              visible: true,
            }, {
              fieldName: "Address",
              label: "Address",
              visible: true,
            }, {
              fieldName: "Website",
              label: "Website",
              visible: true,
            }, {
              fieldName: "Photo",
              label: "Photo",
              visible: false,
            }]
          }, {
            // You can set a media element within the popup as well. This
            // can be either an image or a chart. You specify this within
            // the mediaInfos. Similar to text elements, media can only be set within the content.
            type: "media",
            mediaInfos: [{
              type: "image",
              value: {
                sourceURL: "{Photo}"
              }
            }]
          }]
        };
        var template2 = { //autocasts the new template
          title: "<font color= '#008000'>Route 66",
          content: [{ //set content elements in the order to display
            type: "fields",
            fieldInfos: [{
              fieldName: "Photo",
              label: "Photo",
              visible: false,
            }]
          }, {
            type: "media",
            mediaInfos: [{
              type: "image",
              value: {
                sourceURL: "{Photo}"
              }
            }]
          }]
        };
        var template3 = { //autocasts the new template
          title: "<font color= '#008000'>Illinois & Michigan Canal",
          content: [{ //set content elements in the order to display
            type: "fields",
            fieldInfos: [{
              fieldName: "Photo",
              label: "Photo",
              visible: true,
            }]
          }, {
            type: "media",
            mediaInfos: [{
              type: "image",
              value: {
                sourceURL: "{Photo}"
              }
            }]
          }]
        };

        //***feature layers***
        //add will county boundary
        var boundary = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/County_Limits/FeatureServer/0?toke...",
          //id: "boundary",
        });
        map.add(boundary);

        //add Rt 66
        var rt66 = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Rte_66/FeatureServer/0?token=xWHh8...",
          // id: "rt66",
          popupTemplate: template2,
          outFields: ["*"]
        });
        map.add(rt66);

        //add canal
        var canal = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Illinois_and_Michigan_Canal/Featur...",
          popupTemplate: template3,
          //id: "canal",
        });
        map.add(canal);

        //add preserves
        var preserves = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Will_County_Forest_Preserves/Featu...",
          //id: "preserves",
          //zoom: 1,
        });
        map.add(preserves);

        //add attraction feature layer
        //reference the popup template instance in the popuptmeplate property of featurelayer
        var attractions = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Attractions/FeatureServer/0?token=...",
          id: "attractions",
          visible: true,
          popupTemplate: template,
          outFields: ["*"]
        });
        map.add(attractions);

        //***From here down deals with the query by type dropdown menu***
        var attTypeSelect = document.getElementById("attractions");
        view.ui.add("infoDiv", "left");
        //query all features from the attractions layer
        view.when(function() {
            return attractions.when(function() {
              var query = attractions.createQuery();
              return attractions.queryFeatures(query);
            });
          })
          .then(getValues)
          .then(getUniqueValues)
          .then(addToSelect);

        // return an array of all the values in the
        // Type field of the attractions layer
        function getValues(response) {
          var features = response.features;
          var values = features.map(function(feature) {
            return feature.attributes.Type;
          });
          return values;
        }

        // return an array of unique values in
        // the Type field of the attractions layer
        function getUniqueValues(values) {
          var uniqueValues = [];

          values.forEach(function(item, i) {
            if ((uniqueValues.length < 1 || uniqueValues.indexOf(item) === -1) &&
              (item !== "")) {
              uniqueValues.push(item);
            }
          });
          return uniqueValues;
        }

        // Add the unique values to the attractions type
        // select element. This will allow the user
        // to filter attractions by type.
        function addToSelect(values) {
          values.sort();
          values.forEach(function(value) {
            var option = document.createElement("option");
            option.text = value;
            attTypeSelect.add(option);
          });

          return setattractionsDefinitionExpression(attTypeSelect.value);
        }

        // set the definition expression on the attractions
        // layer to reflect the selection of the user
        function setattractionsDefinitionExpression(newValue) {
          attractions.definitionExpression = "Type = '" + newValue + "'";
          if (!attractions.visible) {
            attractions.visible = true;
          }

          return queryForAttractionGeometries();
        }

        // set a new definitionExpression on the attractions layer
        attTypeSelect.addEventListener("change", function() {
          var type = event.target.value;
          setattractionsDefinitionExpression(type);
        });

        // Get all the geometries of the attractions layer
        // the createQuery() method creates a query
        // object that respects the definitionExpression
        // of the layer
        function queryForAttractionGeometries() {
          var attractionsQuery = attractions.createQuery();
          return attractions.queryFeatures(attractionsQuery)
            .then(function(response) {
              attractionsGeometries = response.features.map(function(feature) {
                return feature.geometry;
              });
              return attractionsGeometries;
            });
        }
      }
    )
  </script>

</head>

<body>
  <header class="app_header">
    <img src="http://www.willcogis.org/website2014/gis/images/gisseal_thumbnail.png" alt="GIS Seal" style="float:left;width:48px;height:46px;">
      <div id="searchParentDiv" style="float:right;">
        <div id="searchDiv"></div>
      </div>
      <div class="a">
        <h1 class="local">Will County Attractions</h1>
      </div>
  </header>
  <div id="infoDiv">
    Select attractions type:
    <select id="attractions"></select>
  </div>
  <div id="viewDiv"></div>
</body>

</html>
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
JaredPilbeam2
MVP Regular Contributor

Robert,

Thanks. That would've taken my a while to figure out. 

The header disappearing problem is fixed. I set this to -100px because after closing out of the popup the header would still slide up at -75px.

        }

        #viewDiv {
            /*set height of the view minus the header*/
            height: calc(100% - 100px);
        }

I set this to visible to get the title to show up.

        @media (max-width: 480px) {
            h1 {
                visibility: visible;
            }

But, the popup is still off the bottom of the screen. Do you know where to adjust it? Does it have something to do with this possibly?

        /*query*/
        #results {
            font-weight: bolder;
        }
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jared,


  I tested the code I pasted pretty throughly and did not have a problem with the pop ups placement. Did you try my exact code?

0 Kudos
JaredPilbeam2
MVP Regular Contributor

Robert,

Yes, I used your exact code (cut/pasted even) and the popup is still where it was before.

It looks decent on an iPhone 6/7/8 using both Firefox and Chrome, but it would be best if I could adjust it up to where you could at least see the whole pic in the popup.

Firefox:

Chrome:

On anything with a smaller screen the popup is not even enough on the screen to scroll. 

iPhone 4 on Chrome:

I've added height to this section but it only helps a little:

        @media (max-width: 480px) {
            h1 {
                visibility:visible;
                max-height: 100px;
            }‍‍‍‍‍

EDIT: I've have the devices set to portrait. If you set the phone to Auto-Rotate it doesn't make much difference. 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jared,

   Your images show me that they are not from my exact code, as I have css rules to hide the app title or else the header is too big and you get the popup placement issue.

0 Kudos
JaredPilbeam2
MVP Regular Contributor

Robert,

Right, sorry. I've since changed it to get the title back and posted the results. So, with your exact code here's the result on an iPhone 6/7/8.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Something is still off as the header is still too tall. This is what I am getting

0 Kudos
JaredPilbeam2
MVP Regular Contributor

Robert,

Ok. Before I was only copying your CSS. This time I copied the entire code and got what you got.

On a smaller device it's better but you still can't read the attributes in the popup.

iPhone 4

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Who in the world still has an iPhone 4? lol.

Try this then.

<!DOCTYPE html>
<html>

<head>
  <link rel="icon" href="http://www.willcogis.org/website2014/gis/images/gisseal_thumbnail.png">
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Will County Attractions</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.9/esri/css/main.css">

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

    #viewDiv {
      height: calc(100% - 75px);
    }

    /*search*/
    #searchParentDiv {
      height: 100%;
    }

    /*search*/
    .esri-search {
      border: solid 3px red;
      margin-top: 7px;
      margin-right: 7px;
    }

    div.a {
      /* center the header*/
      text-align: center;
    }

    /* Style the header */
    header.app_header {
      background-color: whitesmoke;
      padding: 1px;
      font-size: 12px;
      font-family: 'Sans Serif';
      color: black;
      max-height: 50px;
    }

    .esri-legend__layer-caption {
      display: none;
    }

    /*query dropdown*/
    #infoDiv {
      background-color: black;
      color: white;
      font-family: 'Sans Serif';
      padding: 2px;
      width: 100%;
    }

    /*query*/
    #results {
      font-weight: bolder;
    }

    @media (max-width: 480px) {
      h1 {
        visibility: hidden;
      }
      #infoDiv {
        font-size: 10px;
      }
    }

  </style>

  <script src="https://js.arcgis.com/4.9/"></script>

  <script>
    require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/FeatureLayer",
        "esri/layers/GraphicsLayer",
        "esri/widgets/Search",
        "esri/widgets/Home",
        "esri/widgets/Legend",
        "esri/widgets/Expand",
        "dojo/domReady!"
      ],
      function(
        Map, MapView, FeatureLayer, GraphicsLayer, Search, Home, Legend, Expand
      ) {

        //set basemap
        var map = new Map({
          basemap: "topo",
        });

        //set map view
        var view = new MapView({
          container: "viewDiv",
          map: map,
          scale: 500000,
          center: [-87.95, 41.4],
          //popup settings for attractions layer
          popup: {
            dockEnabled: true,
            dockOptions: {
              //set dock/undock button from on pop-up
              buttonEnabled: false,
              //ignore the default sizes that trigger responsive docking
              breakpoint: false,
            }
          }
        });
        //***widgets***
        //home widget
        var homeBtn = new Home({
          view: view,
        });
        view.ui.add(homeBtn, "top-left");

        //search widget
        var searchWidget = new Search({
          view: view,
          container: "searchDiv"
        });

        //legend widget
        var legend = new Expand({
          content: new Legend({
            view: view,
            //style: "card"
          }),
          view: view,
          expanded: false
        });
        view.ui.add(legend, "top-left");

        //***popups***
        //popup template
        var template = { //autocasts the new template
          title: "<img src={logo} height='20' width='20'><font color= '#008000'>{Name}",
          content: [{ //set content elements in the order to display
            type: "fields",
            fieldInfos: [{
              fieldName: "Type",
              label: "Type",
              visible: true,
            }, {
              fieldName: "Address",
              label: "Address",
              visible: true,
            }, {
              fieldName: "Website",
              label: "Website",
              visible: true,
            }, {
              fieldName: "Photo",
              label: "Photo",
              visible: false,
            }]
          }, {
              // You can set a media element within the popup as well. This
              // can be either an image or a chart. You specify this within
              // the mediaInfos. Similar to text elements, media can only be set within the content.
              type: "media",
              mediaInfos: [{
                type: "image",
                value: {
                  sourceURL: "{Photo}"
                }
              }]
            }]
        };
        var template2 = { //autocasts the new template
          title: "<font color= '#008000'>Route 66",
          content: [{ //set content elements in the order to display
            type: "fields",
            fieldInfos: [{
              fieldName: "Photo",
              label: "Photo",
              visible: false,
            }]
          }, {
            type: "media",
            mediaInfos: [{
              type: "image",
              value: {
                sourceURL: "{Photo}"
              }
            }]
          }]
        };
        var template3 = { //autocasts the new template
          title: "<font color= '#008000'>Illinois & Michigan Canal",
          content: [{ //set content elements in the order to display
            type: "fields",
            fieldInfos: [{
              fieldName: "Photo",
              label: "Photo",
              visible: true,
            }]
          }, {
            type: "media",
            mediaInfos: [{
              type: "image",
              value: {
                sourceURL: "{Photo}"
              }
            }]
          }]
        };

        //***feature layers***
        //add will county boundary
        var boundary = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/County_Limits/FeatureServer/0?toke...",
          //id: "boundary",
        });
        map.add(boundary);

        //add Rt 66
        var rt66 = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Rte_66/FeatureServer/0?token=xWHh8...",
          // id: "rt66",
          popupTemplate: template2,
          outFields: ["*"]
        });
        map.add(rt66);

        //add canal
        var canal = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Illinois_and_Michigan_Canal/Featur...",
          popupTemplate: template3,
          //id: "canal",
        });
        map.add(canal);

        //add preserves
        var preserves = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Will_County_Forest_Preserves/Featu...",
          //id: "preserves",
          //zoom: 1,
        });
        map.add(preserves);

        //add attraction feature layer
        //reference the popup template instance in the popuptmeplate property of featurelayer
        var attractions = new FeatureLayer({
          url: "https://services.arcgis.com/fGsbyIOAuxHnF97m/arcgis/rest/services/Attractions/FeatureServer/0?token=...",
          id: "attractions",
          visible: true,
          popupTemplate: template,
          outFields: ["*"]
        });
        map.add(attractions);

        //***From here down deals with the query by type dropdown menu***
        var attTypeSelect = document.getElementById("attractions");
        view.ui.add("infoDiv", "left");
        //query all features from the attractions layer
        view.when(function() {
            return attractions.when(function() {
              var query = attractions.createQuery();
              return attractions.queryFeatures(query);
            });
          })
          .then(getValues)
          .then(getUniqueValues)
          .then(addToSelect);

        // return an array of all the values in the
        // Type field of the attractions layer
        function getValues(response) {
          var features = response.features;
          var values = features.map(function(feature) {
            return feature.attributes.Type;
          });
          return values;
        }

        // return an array of unique values in
        // the Type field of the attractions layer
        function getUniqueValues(values) {
          var uniqueValues = [];

          values.forEach(function(item, i) {
            if ((uniqueValues.length < 1 || uniqueValues.indexOf(item) === -1) &&
              (item !== "")) {
              uniqueValues.push(item);
            }
          });
          return uniqueValues;
        }

        // Add the unique values to the attractions type
        // select element. This will allow the user
        // to filter attractions by type.
        function addToSelect(values) {
          values.sort();
          values.forEach(function(value) {
            var option = document.createElement("option");
            option.text = value;
            attTypeSelect.add(option);
          });

          return setattractionsDefinitionExpression(attTypeSelect.value);
        }

        // set the definition expression on the attractions
        // layer to reflect the selection of the user
        function setattractionsDefinitionExpression(newValue) {
          attractions.definitionExpression = "Type = '" + newValue + "'";
          if (!attractions.visible) {
            attractions.visible = true;
          }

          return queryForAttractionGeometries();
        }

        // set a new definitionExpression on the attractions layer
        attTypeSelect.addEventListener("change", function() {
          var type = event.target.value;
          setattractionsDefinitionExpression(type);
        });

        // Get all the geometries of the attractions layer
        // the createQuery() method creates a query
        // object that respects the definitionExpression
        // of the layer
        function queryForAttractionGeometries() {
          var attractionsQuery = attractions.createQuery();
          return attractions.queryFeatures(attractionsQuery)
            .then(function(response) {
              attractionsGeometries = response.features.map(function(feature) {
                return feature.geometry;
              });
              return attractionsGeometries;
            });
        }
      }
    )
  </script>

</head>

<body>
  <header class="app_header">
    <img src="http://www.willcogis.org/website2014/gis/images/gisseal_thumbnail.png" alt="GIS Seal" style="float:left;width:48px;height:46px;">
      <div id="searchParentDiv" style="float:right;">
        <div id="searchDiv"></div>
      </div>
      <div class="a">
        <h1 class="local">Will County Attractions</h1>
      </div>
  </header>
  <div id="infoDiv">
    Select attractions type:
    <select id="attractions"></select>
  </div>
  <div id="viewDiv"></div>
</body>

</html>
0 Kudos