Search code examples
javascriptdom-eventsgoogle-earth-plugin

Delete placemark from within balloon popup


I'm experimenting with the Google Earth Plugin API for an application that I'm writing. I want to be able to delete placemarks from the map. The simplest way I could think of to do this is to create a balloon popup with a 'Delete' link but I've been unable to figure out how to do delete:

balloon.setContentString(
'Location: ' + event.getLatitude().toString() + ", " +
event.getLongitude().toString() + '<br />&nbsp;<br />' +
'<a href="#" onclick="ge.getFeatures().removeChild(event.getCurrentTarget())">Delete</a><br /><a href="#" onclick="prompt(\'Enter new name\', \'blah\'\)">Rename</a>');

This results in:

Uncaught TypeError: Object #<MouseEvent> has no method 'getCurrentTarget' earth2.html:1 onclick

(As you can see I also want to be able to rename, but presumably that won't be so hard to figure out when I've figured out deleting?)

The entire code can be found at:

http://chrishowells.co.uk:81/earth2.html

The entire block:

google.earth.addEventListener(ge.getWindow(), 'mousedown', function(event) {
if (event.getTarget().getType() == 'KmlPlacemark' &&
    event.getTarget().getGeometry().getType() == 'KmlPoint') {
  // don't show the default popup
  //http://code.google.com/apis/ajax/playground/?exp=earth#javascript_in_balloons
  event.preventDefault();

var balloon = ge.createHtmlStringBalloon('');
balloon.setFeature(event.getTarget());
//balloon.setMaxWidth(300);

balloon.setContentString(
  'Location: ' + event.getLatitude().toString() + ", " +
event.getLongitude().toString() + '<br />&nbsp;<br />' +
'<a href="#" onclick="ge.getFeatures().removeChild(event.getCurrentTarget())">Delete</a><br /><a href="#" onclick="prompt(\'Enter new name\', \'blah\'\)">Rename</a>');
ge.setBalloon(balloon);

var placemark = event.getTarget();

dragInfo = {
    placemark: event.getTarget(),
    dragged: false
  };
}
});

Solution

  • The error you are getting is telling you exactly what the problem is.

     Object #<MouseEvent> has no method 'getCurrentTarget'
    

    The issue being that within the onclick event handler of the anchor the event variable referrers to the click on the link rather than the click on the placemark. That is the event is a DOM mouse event rather than a KmlMouseEvent.

    Also, the method you need to call to reference the object to which the KMLEvent was originally dispatched is getTarget.

    See the API guide for KmlEvent.getTarget: https://developers.google.com/earth/documentation/reference/interface_kml_event#adfee4d0797ff7d437e77c649673f9ffc

    To fix this you need to do a number of things, firstly define a global variable to hold any current placemark click event. Do this at the top of the script where you define the ge variable add a currentEvent variable as well. i.e.

    var ge = null; 
    var currentEvent = null;
    

    Secondly your mousedown listener should be ammended to allow the javascript in the balloon to reference the currentEvent variable you have defined.

    Finally, you should then use the currentEvent variable to reference the Placemark to remove it via the code in the balloon.

    For example.

    google.earth.addEventListener(ge.getWindow(), 'mousedown', function(event) {
    
        if (event.getTarget().getType() == 'KmlPlacemark' &&
        event.getTarget().getGeometry().getType() == 'KmlPoint') {
            currentEvent = event; // used in the balloon content string
            event.preventDefault();
    
            var balloon = ge.createHtmlStringBalloon('');
            balloon.setFeature(event.getTarget());
    
            balloon.setContentString(
            'Location: ' + event.getLatitude().toString() + ", " +
            event.getLongitude().toString() + '<br />&nbsp;<br />' +
            '<a href="#" onclick="ge.getFeatures().removeChild(currentEvent.getTarget());ge.setBalloon(null);">Delete</a><br /><a href="#" onclick="prompt(\'Enter new name\', \'blah\'\)">Rename</a>');
            ge.setBalloon(balloon);
    
            dragInfo = {
                placemark: event.getTarget(),
                dragged: false
            };
        }
    });
    

    I have tested this fully and it works AOK, when you click delete the placemark is removed and the current balloon is closed.