I've been fairly successful using the dojox/mobile components. I used the example 'Find Nearby' a year or so ago, in one of it's earlier iterations: Find nearby locations | ArcGIS API for JavaScript At the time, the example was written with API version 2.7. Because it was based on a really old version of the API, as well as in legacy, I updated it, comparing the code I had with the updated example. I thought I had it all updated and working.
Something in these changes has caused this to stop working on an iPhone. I'm assuming there is something with either a meta tag, or CSS change or maybe both. The original example had a line item specifically for iPhone.css. I'm wondering if this is missing from the example or if it's combined in some other css and no long necessary. It looks like there is still a css available for it, under the newer directory structure as
<link type="text/css" href="https://js.arcgis.com/3.9/dojox/mobile/themes/iphone/iphone.css" rel='stylesheet'>
I added that entry into my code, but that didn't help.
I've also not sure what apple meta tags are necessary.
Since this was working until I started trying to update it, I'm hoping someone can review this and give me some idea of why this doesn't work in particular on an iPhone. I have had it tested on Android and a Windows phone and it works there. I've tried various emulation web sites, and they all work as well.
This link is public facing:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
<title>Warming Center Locations</title>
<link type="text/css" rel="stylesheet" href="https://js.arcgis.com/3.9/js/dojo/dijit/themes/claro/claro.css">
<link type="text/css" href="https://js.arcgis.com/3.9/dojox/mobile/themes/iphone/iphone.css" rel='stylesheet'>
<link rel="stylesheet" href="https://js.arcgis.com/3.9/js/esri/css/esri.css">
<link rel="stylesheet" href="css/style.css">
<script type="text/javascript">
var dojoConfig = {
mblAlwaysHideAddressBar: true,
parseOnLoad: false
};
</script>
<script type="text/javascript" src="https://js.arcgis.com/3.9compact/"></script>
<script type="text/javascript">
// var pathName = "https://ogi.oa.mo.gov";
var pathName = "https://ogitest.oa.mo.gov";
var locator,geomService, map, spatialReference, resizeEvt, currentLocation, currentGraphic, startAddr;
var searchQuery,siteFeatureLayer, infoTemplate, siteInfoTemplate;
var startSymbol, siteRenderer;
var routeGraphicLayer,routePolylineSymbol, segmentGraphicsLayer;
var routeTask, routeParams, directionFeatures, itemList;
var currentBufferDist = 25;
var pointSource = "";
require(["dojox/mobile","dojox/mobile/parser","dojox/mobile/compat","dojox/mobile/deviceTheme",
"dojo/dom", "dijit/registry", "dojo/on", "dojo/query", "dojo/sniff", "dojo/keys",
"esri/map", "esri/SpatialReference", "esri/geometry/Extent", "esri/dijit/Popup","esri/InfoTemplate",
"esri/layers/FeatureLayer", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/layers/GraphicsLayer",
"esri/tasks/locator","esri/tasks/GeometryService", "esri/tasks/query", "esri/tasks/QueryTask",
"esri/tasks/RouteTask", "esri/tasks/RouteParameters", "esri/tasks/FeatureSet","esri/units",
"esri/tasks/BufferParameters",
"esri/renderers/SimpleRenderer", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol",
"esri/symbols/SimpleMarkerSymbol","esri/symbols/PictureMarkerSymbol", "esri/symbols/TextSymbol",
"esri/symbols/Font","esri/geometry/Point","esri/geometry/webMercatorUtils","esri/geometry/mathUtils",
"esri/graphic", "dojo/_base/Color", "dojo/_base/array", "dojox/mobile/ListItem","dojox/mobile/Button",
"dojox/mobile/RoundRectList","dojox/mobile/View","dojox/mobile/ToolBarButton","dojox/mobile/Heading",
"dojox/mobile/RoundRect","dojox/mobile/TextBox","dojox/mobile/ContentPane",
"dojo/domReady!"],
function(mobile, parser, compat,dTheme, dom, registry, on, query, has,keys,
Map, SpatialReference, Extent,Popup, InfoTemplate,
FeatureLayer, ArcGISDynamicMapServiceLayer, GraphicsLayer,
Locator, GeometryService, Query, QueryTask,
RouteTask,RouteParameters,FeatureSet,esriUnits,BufferParameters,
SimpleRenderer, SimpleLineSymbol, SimpleFillSymbol,SimpleMarkerSymbol, PictureMarkerSymbol,
TextSymbol, Font, Point, webMercatorUtils, mathUtils, Graphic, Color, arrayUtils, ListItem, Button, RoundRectList){
parser.parse();
routeTask = new RouteTask(pathName+"/arcgis/rest/services/BaseMap/Route/NAServer/Route");
geomService = new GeometryService(pathName+"/arcgis/rest/services/Utilities/Geometry/GeometryServer");
locator = new Locator("https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer");
locator.on("address-to-locations-complete", showGeocodeResults);
resizeEvt = (window.onorientationchange !== undefined && !has('android')) ? "orientationchange" : "resize";
on(window, resizeEvt, resizeMap);
var spatialReference = new SpatialReference({ wkid : 102100});
var startExtent = new Extent(-10723197, 4186914, -9829190, 4992866, spatialReference);
var map = new Map("mapDiv", {
extent : startExtent,
basemap:"streets",
autoResize:false
});
map.on("load", mapLoadHandler);
startSymbol = new PictureMarkerSymbol('images/bluedot.png', 20, 20);
routePolylineSymbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([115, 44, 123, 0.6]), 4.5);
var routeRenderer = new SimpleRenderer(routePolylineSymbol);
routeGraphicLayer = new GraphicsLayer({id : "routeGraphicLayer"});
routeGraphicLayer.setRenderer(routeRenderer);
map.addLayer(routeGraphicLayer);
var segmentSymbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([102, 255, 255, 0.5]), 10);
var segmentRenderer = new SimpleRenderer(segmentSymbol);
segmentGraphicsLayer = new GraphicsLayer({
id : "segmentGraphicsLayer"
});
segmentGraphicsLayer.setRenderer(segmentRenderer);
map.addLayer(segmentGraphicsLayer);
var locSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_SQUARE, 4, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color("#f79d17"), 2), new Color("#f79d17"));
var siteSymbol = new PictureMarkerSymbol('images/i_pin_red_sm.png', 32, 32);
siteRenderer = new SimpleRenderer(siteSymbol);
siteInfoTemplate = new InfoTemplate();
siteInfoTemplate.setTitle("<b>Site Information</b>");
siteInfoTemplate.setContent(generateInfoContent);
siteFeatureLayer = new FeatureLayer(pathName+"/arcgis/rest/services/DHSS/warmingCenter/MapServer/0", {
id : "siteFeatureLayer",
mode : FeatureLayer.MODE_SELECTION,
outFields : ['*'],
infoTemplate : siteInfoTemplate
});
siteFeatureLayer.setRenderer(siteRenderer);
map.addLayer(siteFeatureLayer);
searchQuery = new Query();
routeParams = new RouteParameters();
routeParams.returnRoutes = true;
routeParams.returnDirections = true;
routeParams.directionsLengthUnits = esriUnits.MILES;
routeParams.outSpatialReference = map.spatialReference;
routeParams.stops = new FeatureSet();
//-------------------------------------------------
//map resize events needed for mobile maps
function resizeMap() {
mobile.hideAddressBar();
adjustMapHeight();
map.resize();
map.reposition();
}
function adjustMapHeight() {
var headHeight = registry.byId('mapHeader').domNode.clientHeight;
var availHeight = mobile.getScreenSize().h - headHeight - 60;
if (has('iphone') || has('ipod')) {
availHeight += iphoneAdjustment();
}
dom.byId("mapDiv").style.height = availHeight + "px";
dom.byId("mapDiv").style.width = "100%";
}
function iphoneAdjustment() {
var sz = mobile.getScreenSize();
if (sz.h > sz.w) { //its portrait
//Need to add address bar height back to map because it has not been hidden yet 44 = height of bottom safari button bar
return screen.availHeight - window.innerHeight - 44;
} else { // must be landscape
//Need to react to full screen / bottom button bar visible toggles
var _conn = on(window, 'resize', function() {
_conn.remove();
resizeMap();
});
return 0;
}
}
//functions for geolocation API -------------------------
function mapLoadHandler(evt){
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(estimateAddressLocation, geoLocationError);
} else {
alert("No geolocation support. You must specify a starting address to begin your search.");
registry.byId('locationDiv').domNode.innerHTML = "Your location not detected";
registry.byId('accuracyDiv').domNode.innerHTML = "Use 'Enter my starting address' to set your current location.";
registry.byId('mainHeader').set("busy", false);
}
registry.byId('mapView').on('AfterTransitionIn', resizeMap);
}
function estimateAddressLocation(location) {
var pt = new Point([location.coords.longitude, location.coords.latitude], new SpatialReference({ wkid : 4326 }));
// Geolocation api returns an address but iPhone returns null so use reverse geocoding to get address
locator.locationToAddress(pt, 100, function(candidate) {
if (candidate.address) {
startAddr = candidate.address.Address;
var address = candidate.address.Address + "<br/> "
+ candidate.address.City + ", "
+ candidate.address.Region
+ " " + candidate.address.Postal;
registry.byId('locationDiv').domNode.innerHTML = "Placed near: <br/> " + address;
var webMercPt = webMercatorUtils.geographicToWebMercator(candidate.location);
registry.byId('accuracyDiv').domNode.innerHTML = "Location accurate within "
+ location.coords.accuracy + " meters <br />of the address listed. Last Updated: "
+ new Date(location.timestamp).toLocaleString();
if (pointSource == "Geocode") {
currentLocation = candidate.location;
}else {
currentLocation = webMercPt; // webMercator
}
registry.byId('mainHeader').set("busy", false);
if (!currentGraphic) { //currentGraphic used as the starting location for buffer search
var attr = { "Source" : "Geolocated point"};
currentGraphic = new Graphic(currentLocation, startSymbol, attr);
pointSource = "geoLocation";
map.graphics.add(currentGraphic);
map.centerAndZoom(currentLocation, 16);
} else {
currentGraphic.setGeometry(currentLocation);
}
}
}, function(error) {
registry.byId('locationDiv').innerHTML = 'Unable to approximate address for your current location';
});
}
function geoLocationError(error){
if (watchProcess !== null) {
navigator.geolocation.clearWatch(watchProcess);
watchProcess = null;
}
switch (error.code) {
case error.PERMISSION_DENIED:
alert("Geolocation access denied or disabled. To enable geolocation on your iPhone, go to Settings > General > Location Services");
break;
case error.POSITION_UNAVAILABLE:
alert("Location information not available");
break;
case error.TIMEOUT:
alert("Request to get located timed out.");
break;
default:
alert("unknown error");
break;
}
}
//
function emptyContainer (container) {
var itemChildren = container.getChildren();
if (itemChildren.length > 0) {
arrayUtils.forEach(itemChildren, function(widget){
widget.destroyRecursive();
});
}
}
function generateInfoContent(graphic){
var formatString = "";
var disclaimerTest = graphic.attributes.HOURS_OF_OPERATION_DISCLAIMER;
locTest = graphic.attributes.LOC_CODE;
formatString = "<b>"+graphic.attributes.FACILITY +"</b><br/>" +graphic.attributes.ADDRESS+"<br/>"
+ graphic.attributes.CITY+", " + graphic.attributes.STATE + "</br>"
+ "Phone: " + graphic.attributes.PHONE + "<br/>"
+ "Hours: " + graphic.attributes.HOURS_OF_OPERATION;
if (disclaimerTest){
formatString = formatString + "<br/>" + graphic.attributes.HOURS_OF_OPERATION_DISCLAIMER;
}
switch (locTest){
case "CENT":
formatString = formatString + "</br></br> ** Location Approximate ** ";
break;
default:
}
return formatString;
}
//search functions -------------------------------
function queryFeatures() {
itemList = registry.byId('searchResults');
emptyContainer(itemList);
var bufferParams = new BufferParameters();
bufferParams.geometries = [currentGraphic.geometry];
bufferParams.distances = [currentBufferDist];
bufferParams.unit = GeometryService.UNIT_STATUTE_MILE;
bufferParams.outSpatialReference = map.spatialReference;
geomService.buffer(bufferParams, function(geometries) {
var bufferGeometry = geometries[0];
var geometryExtent = bufferGeometry.getExtent();
query.geometry = geometryExtent;
query.outSpatialReference = map.spatialReference;
siteFeatureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(features) {
if (features.length === 0) {//If no results are found, suggest increasing search distance
var noResults = new ListItem({
label : "No Results"
});
noResults.set("class", "mblVariableHeight");
noResults.domNode.innerHTML = "No results found. Try a larger search distance using the settings option.";
itemList.addChild(noResults);
return;
}
//format returned distance to something more readable
arrayUtils.forEach(features, function(feature) {
feature.distance = Math.round((mathUtils.getLength(feature.geometry, currentGraphic.geometry) / 1609.344) * 100) / 100;
});
//sorts the returned features so closest features are at the top
var sortedFeatures = features.sort(function(a, b) {
return a.distance - b.distance;
});
//create the formatted string to populate the listitem, add a map button that solves the route between the current location and site
arrayUtils.forEach(sortedFeatures, function(result) {
var formatString = result.attributes.FACILITY + "<br />" + result.attributes.ADDRESS
+ " - " + result.attributes.CITY + "<br />"
+ result.attributes.PHONE + " -- "
+ result.distance + " miles<br/>"
var resultItem = new ListItem({
label : result.attributes.FACILITY
});
resultItem.set("variableHeight", true);
resultItem.domNode.innerHTML = formatString;
var button = new Button({
label : 'Map It',
moveTo : 'mapView'
}).placeAt(resultItem.domNode);
var locationDetails = function(result) {
mapResults(result);
};
on(button, 'click', function (){
locationDetails(result)
});
itemList.addChild(resultItem);
});
}, function(error) {
alert(error.message);
});
}, function(error) {
alert(error.message);
});
}
//Routing functions ------------------------------------------
function mapResults(feature) {
var att;
var widget = registry.byId('resultsView');
widget.performTransition('mapView', 1, "slide", null);
routeGraphicLayer.clear();
segmentGraphicsLayer.clear();
routeParams.stops.features.length = 0;
var startLoc = new Graphic(currentLocation, locSymbol, {'name':startAddr});
var endLoc = new Graphic(feature.geometry, locSymbol, {'name':feature.attributes.FACILITY});
routeParams.outSpatialReference = map.spatialReference;
routeParams.stops.features.push(startLoc);
routeParams.stops.features.push(endLoc);
on(routeTask,'solve-complete', showRoute);
on(routeTask, 'error', routeError);
routeTask.solve(routeParams);
}
// adds the route graphics to the graphicsLayer and populates the directions list
function showRoute(solveResult) {
var dirLi;
var directions = solveResult.result.routeResults[0].directions;
directionFeatures = directions.features;
var dirView = registry.byId('routeDirections');
emptyContainer(dirView);
var dirList = new RoundRectList();
dirView.addChild(dirList);
arrayUtils.forEach(directions.features, function(feature, index) {
routeGraphicLayer.add(new Graphic(feature.geometry, routePolylineSymbol));
dirLi = new ListItem({
label:feature.attributes.text
});
if (index === 0 || index === directions.features.length - 1) {//first and list entries don't use a click event
dirList.addChild(dirLi);
}else{
dirLi.set("clickable", true);
dirLi.set("rightText", "Map");
on (dirLi, 'click', function () {
zoomToSegment(index);
});
dirList.addChild(dirLi);
}
});
map.setExtent(directions.extent, true);
}
function routeError(error) {
alert("Problem finding route \n" + error.message );
registry.byId("directions").domNode.innerHTML = "<b>Problem finding route</b> " ;
}
//Zoom to the appropriate segment afer clicking a hyperlink in the directions list
function zoomToSegment(index) {
var segment = directionFeatures[index];
segmentGraphicsLayer.clear();
var segmentGraphic = new Graphic(segment.geometry);
segmentGraphicsLayer.add(segmentGraphic);
var adjExtent =segment.geometry.getExtent().expand(3);
map.setExtent(adjExtent);
var widget = registry.byId('directionsView');
widget.performTransition('mapView', -1, "fade", null);
}
// geocoding functions -----------------------------------------------
function locate() {
map.graphics.clear();
var address = {
"SingleLine": dom.byId("txtAddress").value
};
locator.outSpatialReference = map.spatialReference;
var options = {
address: address,
outFields: ["*"],
searchExtent: startExtent
};
locator.addressToLocations(options);
}
function showGeocodeResults(evt){
var geometry, candidate;
var MOcandidates = arrayUtils.filter(evt.addresses, function(candidate){
return candidate.attributes.Region == "Missouri";
});
candidate = MOcandidates[0];
var attr = {
"address": candidate.address
};
geometry = candidate.location;
currentLocation = geometry;
pointSource = "Geocode";
var graphic = new Graphic(geometry, startSymbol, attr);
map.graphics.add(graphic);
currentGraphic = graphic;
startAddr = candidate.address;
registry.byId('locationDiv').domNode.innerHTML = candidate.address;
registry.byId('accuracyDiv').domNode.innerHTML = "Not using geolocation, searching from address.";
}
//event listeners -----------------
registry.byId('geoLocateItem').on("click", function() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(estimateAddressLocation, geoLocationError);
} else {
alert("No geolocation support. You must specify a starting address to begin your search.");
registry.byId('locationDiv').innerHTML = "Your location not detected";
registry.byId('accuracyDiv').innerHTML = "Use 'Enter my starting address' to set your current location.";
}
});
//function for changing search distance
query(".distanceList").on("click", function(){
var dist = String(this.id);
currentBufferDist = dist;
console.log("search distance set to " + dist);
});
on(registry.byId('centerItem'), 'click', function (){
if (!currentGraphic) {
alert("No geolocation support. You must specify a starting address to begin your search");
} else {
queryFeatures();
}
});
on(registry.byId("btnGo"), 'click', function(){
locate();
var w = registry.byId('addressView');
w.performTransition('mainView', -1, "slide");
});
on(dom.byId("txtAddress"), "keydown", function(evt){
switch (evt.keyCode){
case keys.ENTER:
var w = registry.byId('addressView');
w.performTransition('mainView', -1, "slide");
// console.log("enter has been pressed");
locate();
break;
default:
// console.log("some other key: " + evt.keyCode);
}
});
});//end main function
</script>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-12671191-9']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body class="claro">
<div id="mainView" data-dojo-type="dojox/mobile/View" >
<h1 id="mainHeader" data-dojo-type="dojox/mobile/Heading"> Find a Warming Center </h1>
<ul data-dojo-type="dojox/mobile/EdgeToEdgeList" >
<li id="centerItem" data-dojo-type="dojox/mobile/ListItem"
data-dojo-props="icon:'images/i_pin_red_sm.png', moveTo:'resultsView', variableHeight:true">
Warming Centers
</li>
<li id="AddressItem" data-dojo-type="dojox/mobile/ListItem"
data-dojo-props="icon:'images/mailbox.png', moveTo:'addressView',variableHeight:true" >
Enter a starting address
</li>
<li id="geoLocateItem" data-dojo-type="dojox/mobile/ListItem"
data-dojo-props="icon:'images/crosshairs.png',variableHeight:true, clickable: true" >
Use my current location
</li>
<li id="settingsItem" data-dojo-type="dojox/mobile/ListItem"
data-dojo-props="icon:'images/settings.png', moveTo:'settingsView',variableHeight:true" >
Change Search Distance
</li>
</ul>
<h2 data-dojo-type="dojox/mobile/RoundRectCategory">Current Location</h2>
<div id="locationDiv" data-dojo-type="dojox/mobile/RoundRect" ></div>
<div id="accuracyDiv" data-dojo-type="dojox/mobile/RoundRect" ></div>
</div>
<div id="resultsView" data-dojo-type="dojox/mobile/View" >
<h2 id="resultsHeader" data-dojo-type="dojox/mobile/Heading" data-dojo-props="label:'Search Results', variableHeight:'true'">
<div data-dojo-type="dojox/mobile/ToolBarButton"
data-dojo-props="label:'Home', moveTo:'mainView', transition:'slide',transitionDir:-1">
</div>
</h2>
<ul id="searchResults" data-dojo-type="dojox/mobile/RoundRectList"></ul>
</div>
<div id="addressView" data-dojo-type="dojox/mobile/View">
<div data-dojo-type="dojox/mobile/ToolBarButton"
data-dojo-props="label:'Back', moveTo:'mainView', transition:'slide',transitionDir:-1">
</div>
<div id="addrPane" data-dojo-type="dojox/mobile/RoundRect">
<h4> Enter address:</h4>
<input id="txtAddress" class="textBox" type="text" placeHolder="Search by address or place" style="width:270px ">
</input>
<div id="btnGo" data-dojo-type="dojox/mobile/ToolBarButton"> GO </div>
</div>
</div>
<div id="settingsView" data-dojo-type="dojox/mobile/View">
<div data-dojo-type="dojox/mobile/ToolBarButton"
data-dojo-props="label:'Back', moveTo:'mainView', transition:'slide',transitionDir:-1">
</div>
<ul id="searchDistList" data-dojo-type="dojox/mobile/EdgeToEdgeList"
data-dojo-props="select:'single'" >
<li id="5" class="distanceList" data-dojo-type="dojox/mobile/ListItem"
data-dojo-props="variableHeight:true, clickable: true">
5 miles
</li>
<li id="10" class="distanceList" data-dojo-type="dojox/mobile/ListItem"
data-dojo-props="variableHeight:true, clickable: true">
10 miles
</li>
<li id="25" class="distanceList" data-dojo-type="dojox/mobile/ListItem"
data-dojo-props="variableHeight:true, clickable: true, checked:true">
25 miles
</li>
<li id="50" class="distanceList" data-dojo-type="dojox/mobile/ListItem"
data-dojo-props="variableHeight:true, clickable: true">
50 miles
</li>
</ul>
</div>
<div id="directionsView" data-dojo-type="dojox/mobile/View">
<h2 id="dirHeader" data-dojo-type="dojox/mobile/Heading" data-dojo-props="label:'Directions', variableHeight:'true'">
<div data-dojo-type="dojox/mobile/ToolBarButton"
data-dojo-props="label:'Back', moveTo:'mapView', transition:'slide',transitionDir:-1">
</div>
</h2>
<div id="routeDirections" data-dojo-type="dojox/mobile/RoundRect" ></div>
</div>
<div id="mapView" data-dojo-type="dojox/mobile/View">
<h2 id="mapHeader" data-dojo-type="dojox/mobile/Heading" data-dojo-props="label:'Map', variableHeight:'true'">
<div data-dojo-type="dojox/mobile/ToolBarButton"
data-dojo-props="label:'Search Results', moveTo:'resultsView', transition:'slide',transitionDir:-1">
</div>
<div id="btnDirections" data-dojo-type="dojox/mobile/ToolBarButton"
data-dojo-props="label:'Directions', moveTo:'directionsView', transition:'slide',transitionDir:1" style="float:right;"> </div>
</h2>
<div id="mapDiv"> </div>
</div>
</body>
</html>
Solved! Go to Solution.
Hi Tracy,
I tested your site using my iphone (ios8) and debugged through Safari and noticed a ton of errors in the console similar to the ones outlined in this dojo bug:
https://bugs.dojotoolkit.org/ticket/18168
Currently it looks like you are using vesrion 3.9 of the JSAPI. You might want to upgrade to version 3.11 because that contains a later version of dojo that contains fixes for some reported issues on ios8.
If you stick with version 3.9 you'll want to update the url to the iphone.css file. Here's the url for the iphone.css file at 3.9:
http://js.arcgis.com/3.9/js/dojo/dojox/mobile/themes/iphone/iphone.css
At 3.11 use this instead:
http://js.arcgis.com/3.11/dojox/mobile/themes/iphone/iphone.css
For details on the meta tags and what they do check out the Safari HTML Reference here:
Hi Tracy,
I tested your site using my iphone (ios8) and debugged through Safari and noticed a ton of errors in the console similar to the ones outlined in this dojo bug:
https://bugs.dojotoolkit.org/ticket/18168
Currently it looks like you are using vesrion 3.9 of the JSAPI. You might want to upgrade to version 3.11 because that contains a later version of dojo that contains fixes for some reported issues on ios8.
If you stick with version 3.9 you'll want to update the url to the iphone.css file. Here's the url for the iphone.css file at 3.9:
http://js.arcgis.com/3.9/js/dojo/dojox/mobile/themes/iphone/iphone.css
At 3.11 use this instead:
http://js.arcgis.com/3.11/dojox/mobile/themes/iphone/iphone.css
For details on the meta tags and what they do check out the Safari HTML Reference here:
Do I need to specify a specific css for a device if I'm also using dojox/mobile/deviceTheme? I thought that was what you used it when you were attempting to get your style set up to look more like a native app.
I'm not sure I'm following you on how you're able to debug. The chances of me getting an iphone to debug on are nil. Is there an emulation environment I could check out? There weren't many choices with a basic Internet search. I tried all the ones I found, and the code worked OK on those.
I'm debugging within the Safari environment as best I can. It almost looks like the only error it's generating is an error on the debugger itself, not the code it's supposed to be debugging.
Tracy,
I don't think you need to load iphone.css if using device theme but your current app code is loading the iphone.css file so you might want to remove it.
I have a mac so I was able to remotely debug using safari. Here are the instructions if you have access to a mac.
Enable Remote Debugging with Safari Web Inspector in iOS 6 | Modus Create
I think many (maybe all) of the issues in your app could be resolved by upgrading to the latest version of the JSAPI so you include the fixes dojo made to handle ios8.
I upgraded the API. That would be awesome if that took care of my problem. I still have the iPhone.css entry. If I leave it, is that forcing the style to always be iPhone, or will the deviceTheme still work?
I need to track down a few more iPhone users. In our group, it's not that common.
Tracy,
It is now working on my iPhone (besides the fact that it can't find a warming location in Alabama). The other day I could not even navigate between view on my iPhone and now I can. Do you have an address that I could try?
111 e 11th st, kansas city, mo
I like it because it's easy to type.
Tracy,
So, your app works fine on my iPhone 5. The only minor thing is the map does not take up all available space (no matter which orientation I use on the device). There is about 3/8 of an inch of gray space below the map.
I have fiddled around a lot with the map size, playing with autoResize:false and trying to manage the resize events properly. One suggestion I had from an older posting was to add the functions adjustMapHeight and iPhoneAdjustment, to try to account for the size the header might be in each environment, but I'm not very satisfied with the results. It's kind of a swag as far as I can tell to detect for sure how much space the header will take, leaving the remainder to fill out with the map. I might be better off taking most of that code out, but I'm afraid I'll be making it even worse.
It's a relief to me that it's working at all. The original version was created non-AMD at version 2.8, I think, nearly 2 years ago. That version worked OK on an iPhone, at least at the time.