Richard
Richard

Reputation: 313

Using longclick/taphold with Google Maps in jQuery Mobile?

I'm using Google Maps with jQuery Mobile.

I can bind a click event to the map easily enough, but is there a way to bind a long click? I'd like to add a marker to the map following a long click.

I can use jQuery Mobile's 'taphold', designed especially for long clicks, but that doesn't give me a way to access map properties such as the latlng of the tap:

    $('#map-canvas').bind('taphold', function(e) {
      console.log('taphold');
      e.stopImmediatePropagation();
      return false;
    } );

Conversely, I can use the Google Maps click listener, but that picks up short clicks, which makes the map fiddly to use on a mobile:

google.maps.event.addListener($('#map-canvas'), 'click', function(event){  ...

I don't see a 'longclick' event listener for Google Maps API V3: http://code.google.com/apis/maps/documentation/javascript/reference.html#Map

Any ideas?

Thanks for your help.

Upvotes: 9

Views: 7221

Answers (5)

Rene Berwanger
Rene Berwanger

Reputation: 157

The union in two codes above. This disables "HOLD" when starts dragging.

function LongClick(map, maxTime) {
    this.maxTime = maxTime;
    this.isDragging = false;
    var me = this;
    me.map = map;
    google.maps.event.addListener(map, 'mousedown', function(e) {
        me.onMouseDown_(e);
    });
    google.maps.event.addListener(map, 'mouseup', function(e) {
        me.onMouseUp_(e);
    });
    google.maps.event.addListener(map, 'drag', function(e) {
        me.onMapDrag_(e);
    });
}
LongClick.prototype.onMouseUp_ = function(e) {
    var now = +new Date;
    if (now - this.downTime > this.maxTime && this.isDragging === false) {
        google.maps.event.trigger(this.map, 'longpress', e);
    }
}
LongClick.prototype.onMouseDown_ = function() {
    this.downTime = +new Date;
    this.isDragging = false;
}
LongClick.prototype.onMapDrag_ = function(e) {
    this.isDragging = true;
};

Upvotes: 0

jedi
jedi

Reputation: 859

The same code working with jquery-ui-map v.3.0-rc1 used on a marker.

var gmarker = map.gmap('addMarker', marker_opts);
new LongPress(gmarker, 500);
gmarker.addEventListener('taphold', function(e) {
    //do something
}

function LongPress(elem, length) {
  this.length_ = length;
  var me = this;
  me.elem_ = elem;
  me.timeoutId_ = null;
  elem.addEventListener('mousedown', function(e) {
    me.onMouseDown_(e);
  });
  elem.addEventListener('mouseup', function(e) {
    me.onMouseUp_(e);
  });
  elem.addEventListener('drag', function(e) {
    me.onMapDrag_(e);
  });
};

LongPress.prototype.onMouseUp_ = function(e) {
  clearTimeout(this.timeoutId_);
};

LongPress.prototype.onMouseDown_ = function(e) {
  clearTimeout(this.timeoutId_);
  var elem = this.elem_;
  var event = e;
  this.timeoutId_ = setTimeout(function() {
    elem.triggerEvent('taphold');
  }, this.length_);
};

LongPress.prototype.onMapDrag_ = function(e) {
  clearTimeout(this.timeoutId_);
};

Upvotes: 0

RyanOC
RyanOC

Reputation: 587

Here is the implemented answer from Leiko http://jsfiddle.net/ryanoc/BaFGw/3/code{};

Upvotes: 2

Leiko
Leiko

Reputation: 952

Using the code sample gave by Richard I made some changes to ensure that longpress events are not triggered if drag events were made during the "delay". Plus, longpress event is now triggered at the end of the delay, not when the mouseup event is triggered. Here it is :

function LongPress(map, length) {
  this.length_ = length;
  var me = this;
  me.map_ = map;
  me.timeoutId_ = null;
  google.maps.event.addListener(map, 'mousedown', function(e) {
    me.onMouseDown_(e);
  });
  google.maps.event.addListener(map, 'mouseup', function(e) {
    me.onMouseUp_(e);
  });
  google.maps.event.addListener(map, 'drag', function(e) {
    me.onMapDrag_(e);
  });
};
LongPress.prototype.onMouseUp_ = function(e) {
  clearTimeout(this.timeoutId_);
};
LongPress.prototype.onMouseDown_ = function(e) {
  clearTimeout(this.timeoutId_);
  var map = this.map_;
  var event = e;
  this.timeoutId_ = setTimeout(function() {
    google.maps.event.trigger(map, 'longpress', event);
  }, this.length_);
};
LongPress.prototype.onMapDrag_ = function(e) {
  clearTimeout(this.timeoutId_);
};

Hope it will help someone !

Upvotes: 8

Richard
Richard

Reputation: 32979

For anyone looking for a solution, I got this on the Google Maps forums, and it does the trick.

function LongClick(map, length) {
    this.length_ = length;
    var me = this;
    me.map_ = map;
    google.maps.event.addListener(map, 'mousedown', function(e) { me.onMouseDown_(e) });
    google.maps.event.addListener(map, 'mouseup', function(e) { me.onMouseUp_(e) });   
}   
LongClick.prototype.onMouseUp_ = function(e) {
    var now = +new Date;
    if (now - this.down_ > this.length_) {
        google.maps.event.trigger(this.map_, 'longpress', e);
    }   
}   
LongClick.prototype.onMouseDown_ = function() {
    this.down_ = +new Date;   
}
new LongClick(map, 300);
google.maps.event.addListener(map, 'longpress', function(event) {
    do stuff...
}

Upvotes: 9

Related Questions