Javascript API map 3.7 has no coordinates when handling map click

5014
13
10-17-2013 08:44 AM
GregHawk
New Contributor
In the new 3.7 API a map click generated by a touch on a mobile device no longer has any coordinates for X and Y.  This is obviously an issue if you intend to place a graphic on the map or do anything based on where the tap was.

[ATTACH=CONFIG]28408[/ATTACH]
0 Kudos
13 Replies
derekswingley1
Frequent Contributor
Can you post code to reproduce this? Based on this post and a discussion on twitter, I think there's an issue here but haven't been abel to get a simple case to reproduce it.

I'm seeing coords when I run this in ios 7:  http://rawr.gr/egz (tap the map)
0 Kudos
GregHawk
New Contributor
Working on a simple example. I had found a sample on the esri site that exhibited it but I am having trouble finding it now.
0 Kudos
GregHawk
New Contributor
I also noticed on the sample you sent that the alert box fired twice
0 Kudos
GregHawk
New Contributor
one difference I am noting is that when the proper event comes back it is a MouseEvent.  When the incorrect one comes back it is just Event.  It still has mapPoint, and screenPoint properties but they are messed up.  This is presumably why there is no coordinate so it has to do with the wrong event firing.  I did notice that esri re-fires some events. This can have the effect of losing screen coordinates.  I found that out by looking up how to simulate a mouseclick.  You can but there are no coords for example.
0 Kudos
derekswingley1
Frequent Contributor
I think this is the likely culprit of the missing map point coordinates:  https://bugs.dojotoolkit.org/ticket/17228

Are you using any dojox/mobile modules?

If so, try
document.dojoClick = false
after dojox/mobile modules are loaded.
0 Kudos
GregHawk
New Contributor
I finally figured it out.  If you include either dojox/mobile/View or dojox/mobile/ScrollableView or presumably anything derived from mobile view then it creates the problem.  Here is sample code that illustrates the issue.

<!DOCTYPE html>

<html>
<head>
    <title>test</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    <style>
        html, body, #mapView
        {
            height: 100%;
            width: 100%;
            margin: 0;
            padding: 0;
        }
    </style>
    <link rel="stylesheet" href="http://js.arcgis.com/3.7/js/esri/css/esri.css" />
    <script src="http://js.arcgis.com/3.7/"></script>
    <script>
        var map;

        require([
                "esri/map",
                "dojox/mobile/View",
                //"dojox/mobile/ScrollableView",
                "dojo/domReady!"
        ], function (
                Map
            ) {

            map = new Map('mapDiv', {
                basemap: "streets",
                zoom: 4
            });
            map.on("click", function (e) {
                alert(e.mapPoint.x.toFixed() + ", " + e.mapPoint.y.toFixed());
            });
        });
    </script>
</head>
<body>
    <div id="mapDiv"></div>
</body>
</html>
0 Kudos
GregHawk
New Contributor
Alright.  After talking to esri support and working with them we found a method that will allow you to include View in your requires statement and still get coordinates.  The issue was a dojo bug technically.  Though it was not supposed to be supported in dojo yet the fix suggested there does work.  After loading the requires add the following line.

document.dojoClick = false;


Also there is an issue that when you tap/click the event fires twice. One is just an object and the other is a MouseEvent.  Depending on the user agent (mobile or desktop)   you need to read a different object.  Here is the code to short circuit the double event and listen to the appropriate event.

if ((Object.prototype.toString.call(evt).slice(8, -1) == 'MouseEvent') && isMobile || (Object.prototype.toString.call(evt).slice(8, -1) == 'Object' && !isMobile))


It is up to you how to detemine if "isMobile".  I suggested checking user-agent
0 Kudos
ErikkRoss
New Contributor


Also there is an issue that when you tap/click the event fires twice. One is just an object and the other is a MouseEvent.  Depending on the user agent (mobile or desktop)   you need to read a different object.  Here is the code to short circuit the double event and listen to the appropriate event.

if ((Object.prototype.toString.call(evt).slice(8, -1) == 'MouseEvent') && isMobile || (Object.prototype.toString.call(evt).slice(8, -1) == 'Object' && !isMobile))


It is up to you how to detemine if "isMobile".  I suggested checking user-agent


I have been running into this fire twice problem. Can you explain where this code should be placed? Using your sample page, where would this be placed? Does it go within the map.on click event?  I do understand that the isMobile variable would have to be set prior.
0 Kudos
ErikkRoss
New Contributor
I have been running into this fire twice problem. Can you explain where this code should be placed? Using your sample page, where would this be placed? Does it go within the map.on click event?  I do understand that the isMobile variable would have to be set prior.


I was able to figure this out. The code does need to be placed inside the click event function. I also found out that if you are using the old connect style events you only need the following code:

 if ((Object.prototype.toString.call(evt).slice(8, -1) != 'MouseEvent')) 


Full example:

//use older connect event style
dojo.connect(map, "onClick", doIdentify);

function doIdentify(evt) {

    //on mobile devices this event will fire multiple times, Check the evt to see if one that fires contains MouseEvent...if it does, ignore it.     
   if ((Object.prototype.toString.call(evt).slice(8, -1) != 'MouseEvent')) 
   {
         //code for click goes here. 
   }

}



That was all I needed to get rid of the fire twice problem. I have tested it on an Android phone, tablet and a iPad. The double firing stopped. Now, I am not using mobile view or scrollableview in my application, but I was still running into that fire twice problem on mobile devices.

If you use the new "On Style" then this code will not work because "Object" will also be returned instead of "MouseEvent" on moblie devices.  If you want to use the on style you'll need to use the code that greghawk posted. For now, I am going to use the old connect events so I don't have to do mobile detection, and hope that ESRI solves this problem.

One issue I did run into though. If you are using esri.toolbars.Draw, the event property is only returned when using the "on" event. The connect event style only returns a geometry property. The only way to check the event would be to use the "on" style.
0 Kudos