Can I attach other events to a map?

1127
7
01-10-2014 12:42 PM
JimWharton
New Contributor III
I need to attach either a double-tap/click or a long press to a map that I'm using on a mobile device. Currently double-clicking is not supported on mobile devices. I can include doubleTap.js but it won't attach to a map:

var pick = on(map, 'dbltap', function(evt) {
            Event.stop(evt);
            var latLng = webMercatorUtils.xyToLngLat(evt.mapPoint.x, evt.mapPoint.y);
            var location = {};
            coords = {
              latitude: latLng[1],
              longitude: latLng[0],
              accuracy:null,
              heading:null
            };
            var locationInfo = {
              coords:coords,
              point: evt.mapPoint
            };
            pick.remove();
            topic.publish('location-picked', locationInfo);
            menus.hideTapAndHoldDialog();
          });


Dojo provides a gestures library in DojoX, but it also will not work when trying to attach a listener to a map.

on(map, tap.hold, function(e){//does not fire})


The API states a bunch of events that the map object honors, but I need to let a user pan, zoom and then double-click/press and hold to get a point. I've asked a similar question below, but I just need to know if we are completely limited to the events offered.
0 Kudos
7 Replies
TimCollyer
Occasional Contributor
It looks like a double click event was added in 3.5? Can you use that?

https://developers.arcgis.com/en/javascript/jsapi/map-amd.html#event-dbl-click
0 Kudos
JimWharton
New Contributor III
It works great in the browser, but it doesn't seem to work on mobile. Double-click to zoom DOES work just fine. I can disable that, and attempt to attach another event to dbl-click, but it won't fire. It looks like it's just trying to select text/dom elements.

Unfortunately, when doing mobile development, being limited to click or drag, is VERY limiting. I know Dojo has had other gestures for a few years, so I'm a bit surprised that they might not be useable with the JSAPI.
0 Kudos
JeffPace
MVP Alum
Ever find a solution for dbltap on touch? I need this as well.
0 Kudos
JimWharton
New Contributor III
Ever find a solution for dbltap on touch? I need this as well.


I ended up using a press and hold event from Hammer.js. I would have used the dojo/touch events, but their tap-hold event doesn't support returning screen coordinates.
0 Kudos
deleted-user-RAnWn8DDSd1P
New Contributor III
how did you get the hammer press/hold to not conflict with map.on('click'...?  after the hold fires, when pulling off it does mouseup and then the click fires.  I'm trying to figure out how to suppress the click action when a hold occurs and just carry on with the hold action.
0 Kudos
JimWharton
New Contributor III
Here's my exact use:

define([
  "dojo/_base/declare",
  "dijit/_WidgetBase",
  "dijit/_TemplatedMixin",
  "dojo/text!./templates/PointPickerWidget.html",
  "dojo/_base/event",
  "utils/menus",
  "dojo/query",
  "dojo/dom-construct",
  "dojo/topic",
  "dojo/on",
  "esri/geometry/Point",
  "esri/geometry/screenUtils",
  "esri/geometry/webMercatorUtils",

  "dojo/domReady!"
],
  function(declare,
           _WidgetBase,
           _TemplatedMixin,
           template,
           Event,
           menus,
           query,
           domConstruct,
           topic,
           on,
           Point,
           screenUtils,
           webMercatorUtils) {

    return declare("PointPickerWidget",[_WidgetBase, _TemplatedMixin], {
        templateString: template,
        widgetsInTemplate: true,
        lat:0,
        lng:0,
        accuracy:'Obtaining GPS Location...',
        tryCount:0,

        constructor: function() {
        },
        postMixInProperties: function() {
          
        },
        getAccuracy: function() {
          var self = this;
          var updatedAccuracy;
          if(navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function(loc) {
              if(loc.coords.accuracy >= 30) {
                updatedAccuracy = domConstruct.toDom('GPS Accuracy: ' + loc.coords.accuracy);
                domConstruct.place(updatedAccuracy, 'location-accuracy', 'only');
              } else {
                if(self.tryCount < 3) {
                  self.getAccuracy();      
                  self.tryCount += 1;
                } else {
                  updatedAccuracy = domConstruct.toDom('Unable to obtain GPS location. Please select a point instead.');   
                  domConstruct.place(updatedAccuracy, 'location-accuracy', 'only');
                }
              }
            });
          }
        },
        postCreate: function() {
          domConstruct.place(this.domNode, "point-picker", "only");
          this.getAccuracy();
        },
        getCurrentLocation: function() {
          if( navigator.geolocation ) {
            navigator.geolocation.getCurrentPosition(function(location) {

              var point = new Point(location.coords.longitude, location.coords.latitude);
              map.centerAndZoom(point, 12);
              var locationInfo = {
                coords:location.coords,
                point: point
              };
              topic.publish('location-picked', locationInfo);
            });
          } else {
            alert("Geolocation not supported!");
          }
          menus.closePointPicker();
        },
        pickLocation: function() {
          menus.closePointPicker();
          menus.showTapAndHoldDialog();
          map.disableDoubleClickZoom();
          var mapDiv = document.getElementById('map');
          var hammertime = Hammer(mapDiv);
          hammertime.on("hold", function (evt) {
            // convert screen coords to map coords
            var x, y, point, mapPoint;
            x = evt.gesture.center.pageX;
            y = evt.gesture.center.pageY;
            point = new Point(x, y);
            mapPoint = screenUtils.toMapPoint(
              map.extent,
              map.width,
              map.height,
              point
            );
            var latLng = webMercatorUtils.xyToLngLat(mapPoint.x, mapPoint.y);
            var location = {};
            coords = {
              latitude: latLng[1],
              longitude: latLng[0],
              accuracy:null,
              heading:null
            };
            var locationInfo = {
              coords:coords,
              point: mapPoint
            };
            hammertime.off("hold");
            topic.publish('location-picked', locationInfo);
            menus.hideTapAndHoldDialog();
          });

        }

      }
    );
  });
0 Kudos
deleted-user-RAnWn8DDSd1P
New Contributor III
ok yeah doesn't look like you're using the map 'click' event as well.  i figured out a fix to have both coexist.  basically when a hold fires I set a variable so that when the click happens after finger release or mouse up I can bail out of the click action if the var is set
0 Kudos