As a followup to my strangely popular KML Toggle example on Google Maps, someone has prompted me to do a Marker Toggle code example. I’m pretty late to the game to notice that Google updated some of the Maps library syntax, you can now for example pass an object literal for latitude longitude. As a warning, the code is a bit clumped together to briefly give an example into working with markers. I wouldn’t recommend master functions that do everything under the sun which is why Angular is a great library to separate your concerns and dependencies.
This example organizes code as follows:
- Marker information is formatted as a json object, the standard format used today for data sharing.
- A single global map variable.
- The Google Map
initializeMap()
procedural function- In addition this function creates markers and your DOM controls.
- The
createMarkers()
function that instantiates markers with infowindows and stores it back in the json. createControls()
dynamically generates the controls based on information in the json. This would be akin to using Angular’s ng-repeat.toggleControl()
is a state changing function that sets your checkbox state, class style, and marker visibility. It uses inverted logic, if the checkbox is checked, then do the opposite.
Click here to the Google Maps Marker Toggle code example.
// Our data source object in json format var markerJson = { "coffee1": { "name": "Urban Bean Coffee", "coordinates": { "lat": 44.958813, "lng": -93.287918 } }, "coffee2": { "name": "Spyhouse Coffee", "coordinates": { "lat": 44.998846, "lng": -93.246241 } }, "coffee3": { "name": "Blue Moon", "coordinates": { "lat": 44.948480, "lng": -93.216707 } } }; // Set a global variable for map var map; // Setup a listener to load the map via Google google.maps.event.addDomListener(window, 'load', initializeMap); /* Google Maps Related Functions */ // Initialize our goo function initializeMap() { var options = { center: { lat: 44.9812, lng: -93.2687 }, zoom: 13, mapTypeId: google.maps.MapTypeId.ROADMAP } map = new google.maps.Map(document.getElementById("map_canvas"), options); // Create markers into DOM createMarkers(markerJson); // Create controls dynamically after parsing json createControls(markerJson); }; // Instantiate markers in the background and pass it back to the json object function createMarkers(markerJson) { for (var id in markerJson) { var shop = markerJson[id]; var marker = new google.maps.Marker({ map: map, position: shop.coordinates, title: shop.name, animation: google.maps.Animation.DROP }); // This attaches unique infowindows to each marker // You could otherwise do a global infowindow var and have it overwrite itself marker.infowindow = new google.maps.InfoWindow({ content: "This coffeeshop is called " + shop.name }); marker.addListener('click', function() { this.infowindow.open(map, this); }); shop.marker = marker; } }; // In this example create the controls dynamically with all checked, obj is each "coffee" listing function createControls(markerJson) { var html = ""; for (var id in markerJson) { var shop = markerJson[id]; html += '<li><a class="selected" href="#" id="' + id + '" onclick="toggleControl(this); return false"><input onclick="inputClick(this)" type="checkbox" checked id="' + id + '" />' + shop.name + '</a></li>'; } document.getElementById("controls").innerHTML = html; }; // Toggle class, checkbox state, and marker visibility function toggleControl(control) { var checkbox = control.getElementsByTagName("input")[0]; var shop = markerJson[control.id]; if (checkbox.checked == true) { checkbox.checked = false; control.className = "normal"; shop.marker.setVisible(false); // If you have hundreds of markers use setMap(map) } else { checkbox.checked = true; control.className = "selected"; shop.marker.setVisible(true); // Similarly use setMap(null) } }; // Cleanup function, resets controls, hides all markers, does not destroy function removeAll() { for (var id in markerJson) { var shop = markerJson[id]; shop.marker.setVisible(false); document.getElementById(id).className = "normal"; document.getElementById(id).getElementsByTagName("input")[0].checked = false; } }; // In this case we are keeping the input box for accessibility purposes, so we bubble up the click event to the parent control function inputClick(input) { input.parentElement.click(); };