Zach Zach - 3 months ago 6
Javascript Question

Google Maps API -- Unique Active Icon per marker on click

I have the following JS using the Google Maps API:

// initialize variables
var infowindow = null;
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var gmarkers = [];

$(document).ready(function () { initialize(); });

function initialize() {

// directions
directionsDisplay = new google.maps.DirectionsRenderer();

var centerMap = new google.maps.LatLng(busipress_map_vars.center_lat , busipress_map_vars.center_long);

var myOptions = {
zoom: 4,
center: centerMap,
mapTypeId: google.maps.MapTypeId.TERRAIN
}

var map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);

setMarkers(map, sites);
infowindow = new google.maps.InfoWindow({
content: "loading..."
});

var start = busipress_map_vars.path_start;
var end = busipress_map_vars.path_end;
var request = {
origin:start,
destination:end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});

directionsDisplay.setMap(map);
}

/**
* show locations
*/
var sites = busipress_map_vars.locations;

/**
* set markers on map
*/
function setMarkers(map, markers) {

// default icon
var defaultIcon = new google.maps.MarkerImage(busipress_map_vars.default_map_icon,
// This marker is 32 pixels wide by 32 pixels tall.
new google.maps.Size(busipress_map_vars.default_map_icon_width, busipress_map_vars.default_map_icon_height),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at 0,32.
new google.maps.Point((busipress_map_vars.default_map_icon_width / 2), busipress_map_vars.default_map_icon_height));

// default shadow
var shadow = new google.maps.MarkerImage(busipress_map_vars.map_icon_shadow,
// The shadow image is larger in the horizontal dimension
// while the position and offset are the same as for the main image.
new google.maps.Size(busipress_map_vars.map_icon_shadow_width, busipress_map_vars.map_icon_shadow_height),
new google.maps.Point(0,0),
new google.maps.Point((busipress_map_vars.default_map_icon_width / 2), busipress_map_vars.map_icon_shadow_height));

// active icion
var activeIcon = new google.maps.MarkerImage(busipress_map_vars.active_map_icon,
// This marker is 20 pixels wide by 32 pixels tall.
new google.maps.Size(busipress_map_vars.active_map_icon_width, busipress_map_vars.active_map_icon_height),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at 0,32.
new google.maps.Point((busipress_map_vars.active_map_icon_width / 2), busipress_map_vars.active_map_icon_height));
var shape = {
coord: [9,0,6,1,4,2,2,4,0,8,0,12,1,14,2,16,5,19,7,23,8,26,9,30,9,34,11,34,11,30,12,26,13,24,14,21,16,18,18,16,20,12,20,8,18,4,16,2,15,1,13,0],
type: 'poly'
};

for (var i = 0; i < markers.length; i++) {
var sites = markers[i];
var siteLatLng = new google.maps.LatLng(sites[1], sites[2]);
var marker = new google.maps.Marker({
position: siteLatLng,
map: map,
title: sites[0],
icon: sites[4][0],
shadow: sites[6][0],
zIndex: 1,
html: sites[3]
});

google.maps.event.addListener(marker, "click", function () {
for (var i = 0; i < gmarkers.length; i++) {
//gmarkers[i].setIcon(defaultIcon);
gmarkers[i].setIcon(sites[4][0]);
}
//this.setIcon(activeIcon);
this.setIcon(sites[5][0]);

infowindow.setContent(this.html);
infowindow.open(map, this);
});
gmarkers.push(marker);
}
}


What I'm attempting to do is map an icon for each
site
(as it is unique) for each marker and then on-click, change it to the active-state of that site. So, changing it to the active icon seems to work, but using that reset function (to change all of the others back to the default icon) it converts it back to one of the site's icons, not each individual one. Anyone have any thoughts on why this may be happening?

Also, when I first dug into this, I was using
defaultIcon
for example (you can see it commented out in the click-action. Since I'm now passing in the URL of the icon via localizing the Javascript, is there anything I can pass into
new google.maps.Marker
as far as the size, origin and point as done in the original
var defaultIcon
declaration. For example,
sites[4][0]
is just going to have an image URL, but
sites[4][1]
is going to have the width, and
sites[4][2]
has the height. I'm not actually sure what it'd be going off of without me having anything there, so a little confused here. Thanks!

Update



I was thinking the issue might be where I'm declaring the variables, so I added them into the
for loop
and adjusted the map markers to use these:

// initialize variables
var infowindow = null;
var directionDisplay;
var directionsService = new google.maps.DirectionsService();
var gmarkers = [];

$(document).ready(function () { initialize(); });

function initialize() {

// directions
directionsDisplay = new google.maps.DirectionsRenderer();

var centerMap = new google.maps.LatLng(busipress_map_vars.center_lat , busipress_map_vars.center_long);

var myOptions = {
zoom: 4,
center: centerMap,
mapTypeId: google.maps.MapTypeId.TERRAIN
}

var map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);

setMarkers(map, sites);
infowindow = new google.maps.InfoWindow({
content: "loading..."
});

var start = busipress_map_vars.path_start;
var end = busipress_map_vars.path_end;
var request = {
origin:start,
destination:end,
travelMode: google.maps.DirectionsTravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});

directionsDisplay.setMap(map);
}

/**
* show locations
*/
var sites = busipress_map_vars.locations;

/**
* set markers on map
*/
function setMarkers(map, markers) {

for (var i = 0; i < markers.length; i++) {
var sites = markers[i];

// default icon
var defaultIcon = new google.maps.MarkerImage(sites[4][0],
// This marker is 32 pixels wide by 32 pixels tall.
new google.maps.Size(sites[4][1], sites[4][2]),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at 0,32.
new google.maps.Point((sites[4][1] / 2), sites[4][2]));

// default shadow
var shadow = new google.maps.MarkerImage(sites[6][0],
// The shadow image is larger in the horizontal dimension
// while the position and offset are the same as for the main image.
new google.maps.Size(sites[6][1], sites[6][2]),
new google.maps.Point(0,0),
new google.maps.Point((sites[6][1] / 2), sites[6][2]));

// active icion
var activeIcon = new google.maps.MarkerImage(sites[5][0],
// This marker is 20 pixels wide by 32 pixels tall.
new google.maps.Size(sites[5][1], sites[5][2]),
// The origin for this image is 0,0.
new google.maps.Point(0,0),
// The anchor for this image is the base of the flagpole at 0,32.
new google.maps.Point((sites[5][1] / 2), sites[5][2]));
var shape = {
coord: [9,0,6,1,4,2,2,4,0,8,0,12,1,14,2,16,5,19,7,23,8,26,9,30,9,34,11,34,11,30,12,26,13,24,14,21,16,18,18,16,20,12,20,8,18,4,16,2,15,1,13,0],
type: 'poly'
};

var siteLatLng = new google.maps.LatLng(sites[1], sites[2]);
var marker = new google.maps.Marker({
position: siteLatLng,
map: map,
title: sites[0],
icon: defaultIcon,
shadow: shadow,
zIndex: 1,
html: sites[3]
});

google.maps.event.addListener(marker, "click", function () {
for (var i = 0; i < gmarkers.length; i++) {
gmarkers[i].setIcon(defaultIcon);
}
this.setIcon(activeIcon);

infowindow.setContent(this.html);
infowindow.open(map, this);
});
gmarkers.push(marker);
}
}


but it stil changes the
defaultIcon
to one for all, instead of the individual defaultIcon images. This may have something to do with the for loop inside of the other for loop, but I'm not quite sure.

Answer

You need to change the click listener function:

    google.maps.event.addListener(marker, "click", function () {
        for (var i = 0; i < gmarkers.length; i++) {
           gmarkers[i].setIcon(defaultIcon);
        }
        this.setIcon(activeIcon);

        infowindow.setContent(this.html);
        infowindow.open(map, this);
    });

You need to save the "unique" icon for each marker and change it back to that one, rather than the defaultIcon. Simplest would probably be to save it as a property of the marker (i.e. marker.myDefaultIcon), then you can do something like this:

gmarkers[i].setIcon(gmarkers[i].myDefaultIcon);

jsfiddle (again modified from your previous question)

UPDATE: I get a javascript error on the link you provided:

Error: marker[i] is undefined
Source File: http://zslabs.com/jhtwp/wp-content/plugins/busipress/js/map.1349993292.js
Line: 105

105 is this line: this.setIcon(marker[i].myActiveIcon);

here:

    google.maps.event.addListener(marker, "click", function () {
        for (var i = 0; i < gmarkers.length; i++) {
           gmarkers[i].setIcon(gmarkers[i].myDefaultIcon);
        }
        this.setIcon(marker[i].myActiveIcon);

        infowindow.setContent(this.html);
        infowindow.open(map, this);
    });

I think you want this.myActiveIcon.

jsfiddle illustrating the concept ("dots" are active, no dot is default)

Comments