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.

Answers:

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)

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.