Reputation: 683
I am running a google map from HTML data and I really need to be able to click on rows (divs) to open the relevant marker. I was hoping to add an onclick within an .each()
function but I cant get anything I have tried to work.
Basically if clicking on each row could open the relevant infowindow it would solve all my problems :)
Help would be much appreciated.
<script type="text/javascript" language="javascript">
var infowindow = new google.maps.InfoWindow();
var myOptions = {
zoom: 4,
center: new google.maps.LatLng(-40.900557, 174.885971),
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true
};
var icon = "img/marker.png";
$(function() {
map = new google.maps.Map(document.getElementById("map"), myOptions);
// grab data attributes from html
$('.row').each(function( index ){
var rLat = $(this).data("coordinates").lat;
var rLong = $(this).data("coordinates").long;
var rTitle = $(this).find('.itemtitle a').html();
var rTel = $(this).find('.tel').html();
var rAdd = $(this).find('.add').html();
var contentString = '<div style="text-align:left"><h4 style="color:#0068a6;font-size:16px;margin:0px 0px 10px 0px;">' + rTitle + '</h4><strong>' + rTel + '</strong><br /><br />' + rAdd + '</div>';
var myLatLng = new google.maps.LatLng( rLat, rLong );
var otherMarkers = new google.maps.Marker({
position: myLatLng,
map: map,
icon: icon
});
// click actions
google.maps.event.addListener(otherMarkers, 'click', (function(otherMarkers, index) {
return function() {
infowindow.setContent( contentString );
infowindow.open( map, otherMarkers );
}
})(otherMarkers, index));
});
});
$(function() {
$(".leftblock .ctrlholder:nth-child(2)").addClass("last");
$(".leftblock .ctrlholder:nth-child(3)").addClass("last");
});
</script>
HTML
<div class="row" data-coordinates='{"lat" : -41.407493, "long" : 174.584122}'>
<h4 class="itemtitle"><a href="">Title</a></h4>
<p class="centralregion">Address</p>
<ul>
<li class="add">Post Address</li>
<li class="tel">tel</li>
</ul>
<span class="filter3"></span>
</div>
Thanks in advance.
Upvotes: 1
Views: 2903
Reputation: 18078
The following approach is slightly convoluted but has the advantage of being economical of memory.
$(function() {
var myOptions = {
zoom: 4,
center: new google.maps.LatLng(-40.900557, 174.885971),
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true
};
var map = new google.maps.Map(document.getElementById("map"), myOptions);
var infowindow = new google.maps.InfoWindow();
var icons = {
'dflt': "../images/map_icons/beach-certified.png",
'selected': "../images/map_icons/harbour-guest.png"
};
var infoTemplate = '<div style="text-align:left"><h4 style="color:#0068a6;font-size:16px;margin:0px 0px 10px 0px;">%Title</h4><strong>%Tel</strong><br /><br />%Add</div>';
var seletedMarker = null;
//Function for composing the info string on the fly.
//This avoids needing to store fully composed info strings in a closure,
//on the offchance that they will be viewed.
function composeInfoString(row) {
var $row = $(row);
return infoTemplate
.replace('%Title', $row.find('.itemtitle a').html())
.replace('%Tel', $row.find('.tel').html())
.replace('%Add', $row.find('.add').html());
}
//closure-forming function to trap row and marker
function clickHandler(row, marker) {
return function() {
if(seletedMarker) {
seletedMarker.setIcon(icons.dflt);//revert seletedMarker's icon to .dflt
}
infowindow.setContent( composeInfoString(row) );
infowindow.open( map, marker );
marker.setIcon(icons.selected);//Set marker's icon to .seleted
seletedMarker = marker;//Remember the currently selected marker so it can be reverted to default next time round.
};
}
$('.row').each(function( index, row ) {
var $row = $(row);
var coords = $row.data("coordinates");
//console.log([coords.lat, coords.lng].join());
var marker = new google.maps.Marker({
position: new google.maps.LatLng( Number(coords.lat), Number(coords.lng) ),
icon: icons.dflt,
map: map
});
var fn = clickHandler(row, marker);
google.maps.event.addListener(marker, 'click', fn);
$row.data('clickFn', fn);//associate fn with row.
});
//Delegate handling of row clicks upward (to closest common row container).
$(document).on('click', '.row', function() {
var fn = $(this).data('clickFn');
if(fn) fn();//this is the functionality you seek
});
});
The economies are twofold :
fn
(pragmatically speaking, a "closure") to each row as a .data()
item, and delegating click handling upwards, you can exploit the same closure used when clicking the marker directly without the need for an additional function wrapper per marker/row.These kinds of economies can be significant when working with many markers, and otherwise do no harm.
Also, you might like to consider changing your coordinate longitude property from long
to lng
. In the code, this will avoid .long
, which can give problems in some browsers. long
is one of many underlying language keywords that should be avoided as js object property identifiers.
Now tested - See updated fiddle. Various fixes are reflected above.
Code modified to swap-out selected marker icon- See updated fiddle.
Upvotes: 0
Reputation: 171679
Since you already loop over all the rows to create markers you can add a click handler to each row that will click on the marker
after adding marker event listener:
google.maps.event.addListener(otherMarkers......);
Add a row click handler that triggers a marker click:
/* "this" is the row instance*/
$(this).click(function(){
google.maps.trigger( otherMarkers ,'click')
})
Upvotes: 1