I have done the draggable marker on another project and I noticed you were keen on having that implemented so here is the patch to have that happen.

Cheers,
Joel

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

joelpittet’s picture

Title: Dragglable Marker » Draggable Marker
Status: Active » Needs review

fixing horrible title spelling.

calculus’s picture

Nice patch! But sometimes after dropping marker, zoom changes from current one. I also recommend changing setCenter method to panTo method on onDragEnd fucntion.

joelpittet’s picture

Good call calculus, you and your derivatives;)

calculus’s picture

Excellent and really fast job joelpittet! Will this patch committed?

joelpittet’s picture

No idea calculus, this issue has been sitting in the needs review pile since Oct 25th 2011.

jm.federico’s picture

Status: Needs review » Fixed

Hello

Really sorry for the delay
and many thanks for the patch

Implemented just the drag, not the panTo nor the setCenter options.
I don't feel moving without the user requesting it would be a good idea.
I don't this would be used for lon drags, which makes me thing, moving the map would make the pointer loose the marker focus, which would make it harder to make multiple drags, like when trying to pin it to a veri specific location.

Any ways, sorry again for the delay.

joelpittet’s picture

Thanks for adding that in but you left a console.log(me); in the code. Those are nasty for some unnamed browsers... you know who I mean.

joelpittet’s picture

Status: Fixed » Needs work
joelpittet’s picture

So far the panTo has been really nice.

I agree with the setCenter... I changed that myself, it was annoying.

On dragend:
Drupal.Geolocation.maps[i].panTo(me.latLng);
Drupal.Geolocation.codeLatLng(me.latLng, i, 'marker');

Also, read the code you changed:

    google.maps.event.addListener(Drupal.geolocation.markers[i], 'dragend', function(me) {
      console.log(me);
      Drupal.geolocation.codeLatLng(me.latLng, i, 'marker');
      Drupal.geolocation.setMapMarker(me.latLng, i);
    });

from this

 Drupal.Geolocation.onDragEnd = function(e) {
    var i = this.data.index;
    latLng = new google.maps.LatLng(this.getPosition().lat(), this.getPosition().lng());
    Drupal.Geolocation.maps[i].panTo(latLng);
    Drupal.Geolocation.codeLatLng(latLng, i, 'marker');
  }

The reference to the variable i nas no point of reference be it's a listener. The me.latLng should be good but i needs some help.

jm.federico’s picture

Hi, thanks for all your help

Actually i does have a point of reference.
In JS, when you pass a function as an argument, the function will carry all the variables that were visible just before the function call to within itself. The variable i which is an argument in the parent function, remains visible inside the callback.

That means that if we have:

  Drupal.geolocation.setMapMarker = function(latLng, i) {
    // remove old marker
    if (Drupal.geolocation.markers[i]) {
      Drupal.geolocation.markers[i].setMap(null);
    }
    Drupal.geolocation.markers[i] = new google.maps.Marker({
      map: Drupal.geolocation.maps[i],
      draggable: Drupal.settings.geolocation.settings.marker_draggable ? true : false,
      // I dont like this much, rather have no effect
      // Will leave it to see if someone notice and shouts at me!
      // If so, will see consider enabling it again
      // animation: google.maps.Animation.DROP,
      position: latLng
    });
    console.log(i);
    console.log(Drupal.geolocation.markers[i]);

    google.maps.event.addListener(Drupal.geolocation.markers[i], 'dragend', function(me) {
      console.log(i);
      console.log(Drupal.geolocation.markers[i]);
      Drupal.geolocation.codeLatLng(me.latLng, i, 'marker');
      Drupal.geolocation.setMapMarker(me.latLng, i);
    });

    return false; // if called from <a>-Tag
  }

The console.log form outside will print the same as the inside of the callback.

This has a drawback, if we have too many variables in scope, they will persist in memory and can end up using too much memory, but the only big var is

  Drupal.geolocation.markers

which is in memory anyways since we need it to persist, so no memory issues here.

About the me.latLng, google passes an event argument to the callback, which is the one you see in function(me). (I think I named it me, for marked/map event)
So from that side, I'm just using what the google api gives me.

ANy ways, new dev version is available.
Will release 1.1 asap.

Cheers

jm.federico’s picture

Status: Needs work » Fixed

I'm closing this as a feature request.

Will open new for implementing .panTo(latLng) #1526280: Implement .panTo() in draggable markes

joelpittet’s picture

I haven't had luck in the past with implicitly carrying variables from a the outside scope into the event handler's anonymous function. Maybe the bugs have been fixed, it's been 8 or so years since I last tried to do that, since then I have been very specific where my variables are coming from.

Console.log throws errors in IE btw, without developer tools installed. It doesn't have a console object.

jm.federico’s picture

I just realized there is an even more compelling reason, even if the bug has been fixed, creating it as an independent function would give other JS the possibility to override it, which would make it more flexible.

I'll change it to what you suggest.

As for the console.log, commit didn't include them, it was just an example.

Thanks for all your input!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.