What I'm trying to do is have a popup box when you click on a marker on the leaflet map. In this popup box are five elements present.
Title
Description
Image
Button (Next Image)
Button (Previous Image)
So what I tried to do was add a custom pop which for each feature:
onEachFeature: function(feature, layer) {
layer.bindPopup(insertDataPopUp(feature), customPopUpOptions);
}
But in my pop up settings when I call a onclick function in my HTML, the function is not recognized. So what I'm trying to do if someone clicks the next image button a new image is displayed. But the issue right now is that the function in the HTML is not found....
Here is the code for the popup where the issue lies:
function insertDataPopUp(feature) {
if (feature.properties.pictures != null) {
var picturePath = feature.properties.pictures[0];
var picture = "<img id='popupFoto' src=" + picturePath + " alt=''/>";
} else {
picture = "";
}
var customPopup =
"<div id='infoBox'><h2>" +
feature.properties.name +
"</h2><p>" +
feature.properties.description +
"</p>" +
picture +
'<button onclick="nextFoto()">Back</button> <button onclick="nextFoto()">Forward</button></div>';
return customPopup;
}
I'm using leaflet, javascript and the vue framework.
I fixed this by using DOM elements. The answer can be found here:
Adding buttons inside Leaflet popup
Related
I'm making an image gallery with all the thumbnails displayed to the left which, when clicked, will display on the right the image itself and previous/next buttons displayed as thumbnails of the previous/next images.
The test page is here (view on desktop; mobile doesn't include this functionality), javascript is here and within the php document I have this code:
<div class="gallery-desktop-thumbs" id="perditionrock"></div>
<script>
var x,xmlhttp,xmlDoc
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "perditionrock.xml", false);
xmlhttp.send();
xmlDoc = xmlhttp.responseXML;
x = xmlDoc.getElementsByTagName("scrn");
div="";
for (i = 0; i <x.length; i++) {
div += "<div class='thumbnail' onclick='displayIMG(" + i + ")' style='background-image:url(";
div += x[i].getElementsByTagName("zone")[0].childNodes[0].nodeValue;
div += "/t/"
div += x[i].getElementsByTagName("photo")[0].childNodes[0].nodeValue;
div += ".jpg);'></div>";
}
document.getElementById("perditionrock").innerHTML = div;
</script>
<section id="gallery-desktop">
</section>
It almost works! Clicking the thumbnail from the gallery functions perfectly. Clicking the previous/next thumbnails loads the previous/next image, but only in its own timestream, starting from the final image. The thumbnails and the previous/next don't work in concert.
eg. If you scroll backwards through the images, say to image 10, then click image 15 in the thumbnails, image 15 loads with images 14 as the previous thumbnail and image 16 as the next. However, if you click the next thumbnail, it goes back to the previous/next stream and loads image 11.
How do I make the previous/next link relative to the image that's already loaded?
(Side note: I'm no code monkey, but I am trying to learn! If any solutions could also be explained as you give them, that'd be awesome. Thanks!)
The problem is, that you want to access a variable, that doesn't exist within your next and previous function.
So basically you have to store the selected index, so you can access it.
// JavaScript Document
var idx = 0;
function next() {
if (idx < x.length-1) {
idx++;
displayIMG(idx);
}
}
function previous() {
if (idx > 0) {
idx--;
displayIMG(idx);
}
}
function displayIMG(i) {
idx = i;
document.getElementById("gallery-desktop").innerHTML =
"<a href=" +
x[i].getElementsByTagName("zone")[0].childNodes[0].nodeValue +
"/" +
x[i].getElementsByTagName("photo")[0].childNodes[0].nodeValue +
".jpg target=_blank><div id=main-image style=background-image:url(" +
x[i].getElementsByTagName("zone")[0].childNodes[0].nodeValue +
"/m/" +
x[i].getElementsByTagName("photo")[0].childNodes[0].nodeValue +
".jpg);></div></a> <nav id=gallery-pn><h6>" +
x[i].getElementsByTagName("title")[0].childNodes[0].nodeValue +
"</h6><nav id=gallery-p onClick=previous() style=background-image:url(" +
x[i].getElementsByTagName("prevzone")[0].childNodes[0].nodeValue +
"/t/" +
x[i].getElementsByTagName("prev")[0].childNodes[0].nodeValue +
".jpg);></nav>" +
"<nav id=gallery-n onClick=next() style=background-image:url(" +
x[i].getElementsByTagName("nextzone")[0].childNodes[0].nodeValue +
"/t/" +
x[i].getElementsByTagName("next")[0].childNodes[0].nodeValue +
".jpg);></nav></nav>";
}
I have an openlayers map that loads a couple of kml files containing about 120 polygon placemarks each. As they're too many to show a popup for each, I had to create an outside-map menu, so the user can click on any one of these features and see it's info / location.
I use this function to create the outside-map menu, containing all the features:
vEnergeticos.getSource().on('change', function(evt){
var source = evt.target;
if (source.getState() === 'ready') {
var energeticos = source.getFeatures();
for (var i in energeticos) {
var figura = energeticos[i].getGeometry().getExtent();
var myCenter = ol.extent.getCenter(figura);
$("#containerLeft").append("<a href=javascript:showMenuPopup(" + myCenter + "," + energeticos[i].get('ID') + ")>" + energeticos[i].get('name') + "</a><br>");
}
}
});
and then when the user clicks on any of these options, this function is called:
function showMenuPopup(xx, yy, theID){
var myPixel = map.getPixelFromCoordinate([xx, yy]);
var elNombre = "";
var laDescripcion = "";
map.forEachFeatureAtPixel(myPixel, function(feature, layer) {
if (feature.get('ID') == theID){
elNombre = feature.get('name');
laDescripcion = feature.get('description');
}
});
popupTitle.innerHTML = elNombre;
popupContent.innerHTML = laDescripcion;
overlay.setPosition([xx,yy]);
}
This works in some situations, however, when the selected feature is outside of the current map view, the map relocates successfully (overlay.setPosition([xx,yy]);), the popup is shown, but the popup is empty. If the feature is visible when the user clicks from the left menu, then the popup is shown correctly.
Just to be clear enough, imagine you're seeing a map where you can see part of Europe, and then you click on some item located in Canada (using the off-map menu), you'll see the map relocates in Canada, but the popup that is shown is empty. If you click again on that very same off-map link, or any other feature that is visible at that location/zoom view, then the popup is shown correctly.
I tried to use the "moveend (ol.MapEvent)" in order to fix this, so the popup was loaded after the map is relocated, but it didn't work for me. The moveend event is called before the map starts to move using overlay.setPosition([xx,yy]), and I haven't been able to find some other "after-relocation" event that I could use.
I've been struggling with this for many days now, so any help will be really appreciated.
Regards!!
The problem is that the features outside of the current map view are not "AtPixel", so you won't catch them with map.forEachFeatureAtPixel.
I suggest you to avoid passing coordinates to showMenuPopup: you just need the feature id, than you can retrieve the feature's coordinates inside showMenuPopup.
$("#containerLeft").append("<a href=javascript:showMenuPopup('" + energeticos[i].getId() + "')>" + energeticos[i].get('name') + "</a><br>");
Then
function showMenuPopup(featureId){
var feature = vEnergeticos.getSource().getFeatureById(featureId);
var elNombre = feature.get('name');
var laDescripcion = feature.get('description');
var figura = feature.getGeometry().getExtent();
var myCenter = ol.extent.getCenter(figura);
popupTitle.innerHTML = elNombre;
popupContent.innerHTML = laDescripcion;
overlay.setPosition(myCenter);
}
Using leaflet, I call below function when I add a layer to the map. This function adds popups to each feature.
They work when I click on them but I can't get the bindPopup.openPopup() to work so it opens without being clicked on.
There aren't any errors but the popup doesn't open without being clicked on.
var popupToOpen = null;
var clickedLocationId = 0;
function onEachFeature(feature, layer) {
if (feature.properties && feature.properties.UserName) {
if (feature.properties.MarkerId == clickedLocationId) {
layer.bindPopup("<div id='unlockLocationId'>" + feature.properties.MarkerId + "</div><div>" + feature.properties.UserName + "</div>").openPopup();
} else {
layer.bindPopup("<div id='unlockLocationId'>" + feature.properties.MarkerId + "</div><div>" + feature.properties.UserName + "</div>");
}
}
}
I've tried the way you're trying but the popup doesn't open. Well, you can try opening popup another way.
Create a function where you iterate your geojson layer and open the popup if the id matches. Here is the function
function openMarkerPopup(id){
geojson.eachLayer(function(feature){
if(feature.feature.properties.id==id){
feature.openPopup();
}
});
}
Simply pass the required id to this function, and it'd work.
openMarkerPopup(108);
Here is a working fiddle
I have set up features from an external geoJson file in Mapbox and bound popups to these features following the example at https://www.mapbox.com/mapbox.js/example/v1.0.0/custom-popup/
var myLayer = L.mapbox.featureLayer(bldgData).addTo(map);
myLayer.eachLayer(function(layer) {
// set up popup for each marker
var content = "";
var props = layer.feature.properties;
var imagePart = "<img class='popupPic' src='images/thumbnails/" + props.filename + "' ></img>";
var infoPart = "<h3 class='popupInfo'>" + props.bldgName + "</h3><p>" +
props.architect + "<br />" + props.year + "</p>";
content = imagePart + infoPart;
layer.bindPopup(content, {closeButton: false});
});
The popups are set up to display on mouseover...
myLayer.on('mouseover', function(e) {
e.layer.closePopup();
e.layer.openPopup();
});
myLayer.on('mouseout', function(e) {
e.layer.closePopup();
});
I have also set up filtering to display selected features following the example at https://www.mapbox.com/mapbox.js/example/v1.0.0/filtering-markers/
function chooseBldg(){
var bldgs = document.getElementById("buildingTypeMenu").value;
if(bldgs == "all") {
myLayer.setFilter(function(f) {return true;});
}
else {
myLayer.setFilter(function(f) {
return f.properties['buildingType'] === bldgs;
});
}
}
The popups display correctly when I first display the page, and the filters correctly select the subset of markers to display, but after the filter has been triggered the popups no longer display on mouseover. Do I need to rebind the popups (by explicitly triggering the eachLayer function or something) after the filter has been done?
Rebind popups solved this problem for me.
I'm writing a webpage that uses an image map. The image and map are loaded dynamically. If I click on the area element new content is loaded. Also the url changes its hash (eg. index.php#somepage). I have three layers of pages, the main layer (homepage) has it's own image with a map (index.php), the second layer offers a new image + map (index.php#somepage) and the third layer opens an overlay on the second layer, therefore changing the hash (index.php#somepage_somesubpage).
I now want to be able to send someone a link to index.php#somepage_somesubpage. So I slice the hash and trigger the click-method of the imagemap on the first level to load index.php#somepage when the page is loaded. I added a callback to that, calling the desired click-method of the now updated imagemap. This does not work for some reason I can't figure out. I am able to open index.php#somepage, but when I enter index.php#somepage_somesubpage I end up getting the same result.
Here is the code of $(document).ready:
var cont = $('#content');
$( document ).ready(function() {
cont.load('pages/home.php', function(responseTxt,statusTxt,xhr){
if(statusTxt=='error')
{
cont.load('404.php');
}
lineparser('#content'); //Perform some fancy stuff on the page
var hash = location.hash.replace('#', '');
if (hash != ''){
if(hash.indexOf('_') > 0)
{
//open page with content
$('area[href~="#' + hash.slice(0, hash.indexOf('_')) + '"]').first().trigger("click", function(){
$('area[href~="#' + hash + '"]').first().trigger("click");
});
}
else{
//open menu page
$('area[href~="#' + hash + '"]').first().trigger("click");
}
}
});
});
I solved the problem like this:
$('area[href~="#' + hash.slice(0, hash.indexOf('_')) + '"]').first().trigger("click", [hash]);
Then I added the following:
$(document.body).on('click', "map area", function(e, schachteln){
...
if(schachteln){
$('area[href~="#' + schachteln + '"]').first().trigger("click");
}
}