Reputation: 333
I currently have a mapbox app that displays a popup for each marker once clicked which is great. What I want however, is the information within the popup to be sent to a seperate div within the app, so the data is displayed at the bottom of the screen instead of within a popup on the map. So it looks something like the image below, but at the bottom of the page instead and with only the essential data such as name, description etc. The code below is what I am using to generate the markers.
So far I have tried editing the CSS of the mapbox popup, but this only gets overwritten by the default mapbox CSS and even when it's not, it's simply too clunky and does not give the effect I want. I'm also aware that this can be done using Leaflet, but this is not something that I wish to use, so that is not an option for me.
for(var i = 0; i < currentArray.length ; i++){
var el = document.createElement('div');
var markerHeight = 50, markerRadius = 10, linearOffset = 25;
el.className = 'marker2';
new mapboxgl.Marker(el)
.setLngLat([currentArray[i].lng, currentArray[i].lat])
.addTo(map);
new mapboxgl.Marker(el)
.setLngLat([currentArray[i].lng, currentArray[i].lat])
.setPopup(new mapboxgl.Popup({ offset: 25, closeOnClick:true})
.setHTML(
`<div id = "popup-container">
<h3>${currentArray[i].name}</h3>
<p>${currentArray[i].venue}</p>
</div>`
)
)
.addTo(map);
}
callbackEventbrite(function(result){
console.log("env", result)
//var geo = GeoJSON.parse(result.events,{Point: [result.location.latitude, result.location.longitude]});
//console.log(geo);
const keys = Object.values(result);
for(const key of keys){
geojson = {
type: 'featureCollection',
features: [{
type: 'feature',
geometry: {
type: 'Point',
coordinates: [key.venue.longitude, key.venue.latitude]
}
}]
}
eventInfo.push(
{"longitude": key.venue.longitude , "latitude": key.venue.latitude , "name": key.name.text, "venue": key.venue.name, "date": key.start.local, "category": key.category_id}
);
}
});
Upvotes: 2
Views: 3158
Reputation: 53
If you've added properties
to your layer data, you can use them programmatically. Assuming you need to fetch your existing API data and format your geojson, you could try something like this...
// prepare geojson
let json = {
type: "FeatureCollection",
features: []
};
// apiData = some other json source
apiData.forEach(poi => {
// add poi to geojson
json.features.push({
type: "Feature",
properties: { // example properties
id: poi.id,
title: poi.title,
image: poi.image
},
geometry: { type: "Point", coordinates: [poi.longitude, poi.latitude] }
});
});
// add geojson source
map.addSource("my-locations", {
type: "geojson",
data: json,
});
// add stories layer
map.addLayer({
interactive: true,
id: "my-layer",
type: "circle",
source: "my-locations",
paint: {
"circle-color": #6495ED,
"circle-radius": 10,
}
});
map.on("click", "my-layer", e => {
// do something when user clicks on marker
var coordinates = e.features[0].geometry.coordinates.slice();
var id = e.features[0].properties.id;
var html = e.features[0].properties.image + e.features[0].properties.title;
var popupContent = window.document.createElement("div");
popupContent.addEventListener("click", e => {
// do something when user clicks on popup
});
popupContent.innerHTML = html;
new MapboxGL.Popup()
.setLngLat(coordinates)
.setDOMContent(popupContent)
.addTo(map);
});
You may need to switch from using new maboxgl.Marker.addTo
. See details here: https://docs.mapbox.com/help/troubleshooting/transition-from-mapbox-js-to-mapbox-gl-js/#add-a-marker
Upvotes: 2
Reputation: 2682
I slightly modified this example https://docs.mapbox.com/mapbox-gl-js/example/popup-on-click/ so that when the layer is clicked, the description is shown not in a popup, but rather in a div at the bottom of the page.
Check this out https://jsfiddle.net/anatolysukhanov/y2jLedtq/
The idea is that there are 2 divs
<div id="map"></div>
<div id="popup"></div>
styled like this
#map {
position:absolute;
top:0;
bottom:0;
width:100%;
}
#popup {
position: fixed;
bottom: 0;
text-align: center;
width: 100%;
opacity: 0.8;
background-color: white;
}
Upvotes: 1