Recently I built a map with custom markers (pins) and a sorting function to display each by type (Member, Supplier, Prospect, New Member).
The HTML (check boxes wired up with sort()
function):
<input type="checkbox" value="Supplier" onclick="sort()" id="switch2" />
<label for="switch2">Suppliers</label>
The JavaScript:
var markersArray = [];
// data schema ['Company Name',"Address",Latitude,Longitude,"Type"]
var data = [
['Company A',"Address",Latitude,Longitude,"Member"],
['Company B',"Address",Latitude,Longitude,"Supplier"],
['Company C',"Address",Latitude,Longitude,"Prospect"],
];
function initialize(data) {
var mapOptions = {
zoom: 3,
center: new google.maps.LatLng(40, -90)
}
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
// Create the legend with content
var legend = document.createElement('div');
legend.id = 'legend';
var content = [];
content.push('<h3>Legend</h3>');
content.push('<p><div class="legIcon"> <img src="pin_blue.png" alt="icon color" /> </div>Members</p>');
content.push('<p><div class="legIcon"> <img src="pin_red.png" alt="icon color" /> </div>Suppliers</p>');
content.push('<p><div class="legIcon"> <img src="pin_purple.png" alt="icon color" /> </div>New Members</p>');
content.push('<p><div class="legIcon"> <img src="pin_green.png" alt="icon color" /> </div>Prospects</p>');
legend.innerHTML = content.join('');
legend.index = 1;
// call the legend
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(legend);
setMarkers(map, data);
}
function setMarkers(map, locations) {
if (locations == undefined) {
locations = data;
return initialize(locations);
}
for (var i = locations.length - 1; i >= 0; i--) {
var company = locations[i],
pinColor = '';
var myLatLng = new google.maps.LatLng(company[2], company[3]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
icon: image,
shape: shape,
title: company[0],
type: company[4]
});
markersArray.push(marker);
if ( marker.type === 'Member' ) { pinColor = 'blue' }
else if ( marker.type === 'New') { pinColor = 'purple' }
else if ( marker.type === 'Supplier') { pinColor = 'red' }
else { pinColor = 'green' }
var image = {
url: 'pin_' + pinColor + '.png',
size: new google.maps.Size(100, 100),
origin: new google.maps.Point(0,0),
anchor: new google.maps.Point(20, 40)
};
};
}
// initialize map with empty array
google.maps.event.addDomListener(window, 'load', function (data) { initialize([]) });
// standalone functions
function clearOverlays () {
for (var i = 0; i < markersArray.length; i++) {
markersArray[i].setMap(null);
}
markersArray.length = 0;
}
function resetPins () {
clearOverlays();
}
// sort and collect with sliding buttons (checkboxes)
function sort () {
var newData = [];
// Pass the checkbox name to the function
function getCheckedBoxes(chkboxName) {
var checkboxes = document.getElementsByName(chkboxName);
var checkboxesChecked = [];
// loop over them all
for (var i=0; i<checkboxes.length; i++) {
// And stick the checked ones onto an array...
if (checkboxes[i].checked) {
checkboxesChecked.push(checkboxes[i].value);
}
// clear the unchecked
else {
clearOverlays();
}
}
// Return the array if it is non-empty, or null
return checkboxesChecked.length > 0 ? checkboxesChecked : null;
}
// call the boxes
var checkedBoxes = getCheckedBoxes("switch");
for (var i = 0; i < checkedBoxes.length; i++) {
data.forEach(function (d) {
if ( d[4] === checkedBoxes[i] ) {
newData.push(d);
};
});
}
if (newData.length > 0) {
return initialize(newData);
}
else {
return initialize(data);
}
}
I have not written a ton of vanilla JavaScript, so I would like some advice on how to clean this up. The obvious: some loops count down, other up, there are various if
/else
statements that I feel may be superfluous, using .forEach
inside a for
loop.
Curiously, when the code runs, it skips the first element of data when assigning the custom pin as .png. Why does this code not hit the first element in the array?