Wrong pop up gets opened on marker click - javascript

I have a lot of markers so i cluster them. I got problem where i want to remain my pop up open when user zoom out from the cluster and i found this solution
https://jsfiddle.net/sghL4z96/65/
Leaflet Markercluster: Exempt marker from clustering
it works fine. But the problem is when the markers are too close on the cluster itself
and when i try with this same solution i got this result
https://jsfiddle.net/s2mnvL5w/3/
where when i click on the cluster two markers show up.For example if i click on the left one i get pop up with text one.When i close this popup,i try again to open the left marker and then i get pop up with text two which is wrong.Instead i get one.Where is my mistake and hopw the solution can be adjusted to the markers with very near coordinates.
clustered.on('popupopen', function(e) {
console.log('open');
const m = e.popup._source;
clustered.removeLayer(m);
unclustered.addLayer(m);
m.openPopup();
});
unclustered.on('popupclose', function(e) {
console.log('close');
let m = e.popup._source;
unclustered.removeLayer(m);
clustered.addLayer(m);
m.closePopup();
});
UPDATED - THE FULL SOLUTION
https://jsfiddle.net/s2mnvL5w/24/

This is because you remove the layer from the clustered group. After adding it again to the group it has a new order.
You can do something like this:
let popup;
const mkMarker = function(lat, lng, txt) {
const m = L.marker(L.latLng(lat, lng));
m.addTo(clustered);
m.popupText = txt;
m.on('click',(e)=>{
var marker = e.target;
var latlng = marker.getLatLng();
var offset = [0,0];
if(marker._preSpiderfyLatlng){
latlng = marker._preSpiderfyLatlng;
}else{
offset= marker.options.icon.options.popupAnchor;
}
popup = L.popup({offset: offset}).setContent(marker.popupText).setLatLng(latlng).addTo(map)
})
return m;
};
And remove the popupopen / close listener function

Related

How to add a click event to any of my markers which i have stored in an array

I'm working with leaflet js and I have an array in which i store my markers which are automatically added to the map after the location of the user has been obtained.
problem is that i want to add an onclick listener so that any marker that is clicked will run a function.
please help me out cuz i'm stuck right now.
//objects for markers
var allMarkers=[];
var AllMarkers = L.layerGroup(allMarkers);
var Allpoints=[{
"latitudes":9.4258946,"longitudes":-0.8842213, "names":"first", "eastings":556568, "northings":446445, "description": "aijaskj jnrkajra skjanjanek ", "elevations": 5668
},
{
"latitudes":9.4254946,"longitudes":-0.8812213, "names":"second"},
{
"latitudes":9.4054946,"longitudes":-0.8802213, "names":"third"},
{
"latitudes":9.4754946,"longitudes":-0.8712213, "names":"fourth"},
];
//automatically plot all previous markers
var point = L.point(9.2754946, -0.8912213);
q = 0;
while(q< Allpoints.length){
//create Marker here
_newMarker = L.marker(
[Allpoints[q].latitudes, Allpoints[q].longitudes],
{title: Allpoints[q].names,
riseOnHover: true,
} ).addTo(mymap);
allMarkers.push(_newMarker);
q++
}
//function to send back the details of the clicked marker to a paragraph in my index.htm
//PROBLEM
L.marker('click', markers, showMarkerDetails) //however the code immediately above does not work
function showMarkerDetails(){
$("#returnControlName").html(controlName);
$("#returnControlLocation").html(`${controlLat.toFixed(4)} , ${controlLong.toFixed(4)} `);
$("#returnControlEastings").html(controlEastings);
$("#returnControlName").html(controlNorthings);
$("#returnControlName").html(controlElevation);
$("#returnControlName").html(controlDescription);
}
With L.marker() you add new markers / points to the map, you can't add events like that to them. (L.marker('click', markers, showMarkerDetails) )
Change your code to:
//automatically plot all previous markers
var point = L.point(9.2754946, -0.8912213);
q = 0;
while(q< Allpoints.length){
//create Marker here
_newMarker = L.marker([Allpoints[q].latitudes, Allpoints[q].longitudes],
{title: Allpoints[q].names,
riseOnHover: true,
}).addTo(mymap);
_newMarker.informations = Allpoints[q]; // save the data to the marker to read it later out
_newMarker.on('click',showMarkerDetails); // add click event to the markers
allMarkers.push(_newMarker);
q++
}
function showMarkerDetails(e){
var layer = e.target // get the clicked marker
var infos = layer.informations;
console.log(infos.description);
$("#returnControlName").html(controlName);
$("#returnControlLocation").html(`${controlLat.toFixed(4)} , ${controlLong.toFixed(4)} `);
$("#returnControlEastings").html(controlEastings);
$("#returnControlName").html(controlNorthings);
$("#returnControlName").html(controlElevation);
$("#returnControlName").html(controlDescription);
}

Leaflet Marker's Popup get disappear when Marker get update on the Map?

I have map , where I have Markers.When I click on Marker, it shows name of marker on popup using openPopup().
getBindPopup: function (e) {
var element = e;
var latlng = [element.lat, element.lng];
return L.popup()
.setLatLng(latlng)
.setContent('' + element.name + '')
.openPopup();
}
This is the function , I am using to show Popup on marker.
I am calling this function in another function and then Markers getting update :
var popup = App.elementData.getBindPopup(element);
//below line :calling getBindPopup function
App.map.Markers[element.id] = L.marker(latlng, element).bindPopup(popup);
// This line will update all Markers on Map
App.map.Count._update(App.map.Markers);
But after App.map.Count._update(App.map.Markers); popup get disappear.
I need popup even after markers updates on the map.
Please suggest.
Thank you.

Can MarkerClusterer have a long click or double click?

Googlemap API v3 - Can I get Content from Marker?
This is my last Question.
There is another problem,when markers become MarkerClusterer i set a click event to show all marker avg and show on infowindow.
And,my Question is Can MarkerClusterer have a long click or double click?
I mean double click and zoom in like MarkerClusterer click or long click then show infowindow,Because I need to zoom in,and After zoom in how to hide infowindow?
My code in the link.
By the way I try to give markerclusterer "dblclick",like this
markerCluster = new MarkerClusterer(map, markers_Select, mcOptions);
google.maps.event.addListener(markerCluster, 'dblclick', function(cluster) {
var info = new google.maps.MVCObject;
info.set('position', cluster.center_);
var allmarke = cluster.getMarkers();
var titles = "";
var total = 0;
for (var i = 0; i < allmarke.length; i++) {
total += parseFloat(allmarke[i]._myValue);
}
titles = "avg:" + (total / (allmarke.length)).toFixed(2);
g_infoWindow.setContent(titles);
g_infoWindow.open(map, info);
});
but not work....

google maps api v3 multiple markers infowindow onclick works but not when called outside

I have a weird problem and maybe I am just not seeing it clearly. It definitely always helps to have others look at my code. Anyways, I have a drop down menu with options in it, needless to say, onchange it calls a function to open an infowindow. The listener for the click works perfectly fine when displaying the info window, but the handleSelected() function does not display anything.:
<select size='37' id='dpMenu' onchange='handleSelected(this)'>
Now I have an array for my markers outside of my function that creates the markers.
var gmarkers = [];
var oldInfoWin;
var map;
function createEpiMarker(map,point,epi_icon,html,name,detail,iqrid) {
var epimarker = new google.maps.Marker({
position: point,
map: map,
icon: epi_icon
});
epimarker.infowindow = new google.maps.InfoWindow({content: html });
google.maps.event.addListener(epimarker, "click", function() {
epimarker.infowindow.open(map, epimarker);
oldInfoWin = epimarker.infowindow;
infoWindowOpen = true;
});
gmarkers.push(epimarker);
}
This code here handles the dropdown menu selection:
function handleSelected(opt){
var i = opt[opt.selectedIndex].index - 1;
if(i != -1){
gmarkers[i].infowindow.open(map, gmarkers[i]);
oldInfoWin = gmarkers[i].infowindow;
infoWindowOpen = true;
}
}

Google Maps: remember id of marker with open info window

I have a Google map that is showing a number of markers. When the user moves the map, the markers are redrawn for the new boundaries, using the code below:
GEvent.addListener(map, "moveend", function() {
var newBounds = map.getBounds();
for(var i = 0; i < places_json.places.length ; i++) {
// if marker is within the new bounds then do...
var latlng = new GLatLng(places_json.places[i].lat, places_json.places[i].lon);
var html = "blah";
var marker = createMarker(latlng, html);
map.addOverlay(marker);
}
});
My question is simple. If the user has clicked on a marker so that it is showing an open info window, currently when the boundaries are redrawn the info window is closed, because the marker is added again from scratch. How can I prevent this?
It is not ideal, because often the boundaries are redrawn when the user clicks on a marker and the map moves to display the info window - so the info window appears and then disappears again :)
I guess there are a couple of possible ways:
remember which marker has an open info window, and open it again when the markers are redrawn
don't actually re-add the marker with an open info window, just leave it there
However, both require the marker with an open window to have some kind of ID number, and I don't know that this is actually the case in the Google Maps API. Anyone?
----------UPDATE------------------
I've tried doing it by loading the markers into an initial array, as suggested. This loads OK, but the page crashes after the map is dragged.
<script type="text/javascript" src="{{ MEDIA_URL }}js/markerclusterer.js"></script>
<script type='text/javascript'>
function createMarker(point,html, hideMarker) {
//alert('createMarker');
var icon = new GIcon(G_DEFAULT_ICON);
icon.image = "http://chart.apis.google.com/chart?cht=mm&chs=24x32&chco=FFFFFF,008CFF,000000&ext=.png";
var tmpMarker = new GMarker(point, {icon: icon, hide: hideMarker});
GEvent.addListener(tmpMarker, "click", function() {
tmpMarker.openInfoWindowHtml(html);
});
return tmpMarker;
}
var map = new GMap2(document.getElementById("map_canvas"));
map.addControl(new GSmallMapControl());
var mapLatLng = new GLatLng({{ place.lat }}, {{ place.lon }});
map.setCenter(mapLatLng, 12);
map.addOverlay(new GMarker(mapLatLng));
// load initial markers from json array
var markers = [];
var initialBounds = map.getBounds();
for(var i = 0; i < places_json.places.length ; i++) {
var latlng = new GLatLng(places_json.places[i].lat, places_json.places[i].lon);
var html = "<strong><a href='/place/" + places_json.places[i].placesidx + "/" + places_json.places[i].area + "'>" + places_json.places[i].area + "</a></strong><br/>" + places_json.places[i].county;
var hideMarker = true;
if((initialBounds.getSouthWest().lat() < places_json.places[i].lat) && (places_json.places[i].lat < initialBounds.getNorthEast().lat()) && (initialBounds.getSouthWest().lng() < places_json.places[i].lon) && (places_json.places[i].lon < initialBounds.getNorthEast().lng()) && (places_json.places[i].placesidx != {{ place.placesidx }})) {
hideMarker = false;
}
var marker = createMarker(latlng, html, hideMarker);
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers, {maxZoom: 11});
</script>
You should probably create all your markers at an initial stage with your createMarker() method, and store the returned GMarker objects inside an array. Make sure to set the hide: true property in GMarkerOptions when you create your markers, so that they would be created as hidden by default.
Then instead of iterating through places_json.places, you could iterate through your new GMarker array. You would be able to get the coordinates of each marker with the GMarker.getLatLng() method, with which to check if each marker lies within the bounds.
Finally simply call GMarker.show() for markers that lie within the bounds, or GMarker.hide() to hide them.
You would eliminate the expensive destruction/creation of markers on each map movement. As a positive-side effect, this will also solve your GInfoWindow problem.
If you're using that many markers, make sure you use GMarkerManager. It's designed for many markers, with only a few visible at once.
http://mapki.com/wiki/Marker_Optimization_Tips

Categories

Resources