As suggested by TomazicM, there might be a simplier way to achieve this, with much more cleaner code! Here I'm duplicating a bunch of code, because for the moment I don't know how to simplify it. But it works !
I also managed to remove duplicate properties from a geoJSON file here.
I give here all my js code. It might help other newbies like me, and of course, if there are some advanced coders who want to improve it, you're welcome.
@TomazicM, again thank you very very much for all your help. Thanks to you I can improve my skill little by litte !! : )
Here is my code :
$(document).ready(function(){
var cartoDb = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
subdomains: 'abcd',
maxZoom: 18
});
var cartoDb2 = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
subdomains: 'abcd',
maxZoom: 18
});
/* Here is an example of how I define my custom icons . I'm using leaflet.awesome-markers */
var ccl18Icon = L.AwesomeMarkers.icon({
prefix: 'fa', //font awesome rather than bootstrap
iconColor: 'white',
markerColor: 'orange', // see colors above
icon: 'ambulance' //http://fortawesome.github.io/Font-Awesome/icons/
});
Then a function for each markers, similar to an info window, but I put it in a dynamic panel outside the map with : $('#layer_infos .fill').html(html);
function onEachFeature(feature, layer) {
var html = '';
if (feature.properties.Professeur) {
html += '<p class="prof">' + feature.properties.Professeur + '</p>';
}
if (feature.properties.Professeur2) {
html += '<p class="prof2">' + feature.properties.Professeur2 + '</p>';
}
if (feature.properties.Chu) {
html += '<p class="chu">' + feature.properties.Chu + '</p>';
}
if (feature.properties.Laboratoire) {
html += '<p class="labo">' + feature.properties.Laboratoire + '</p>';
}
if (feature.properties.Prelevement) {
html += '<p>' + feature.properties.Prelevement + '</p>';
}
if (feature.properties.Envoi) {
html += '<p>' + feature.properties.Envoi + '</p>';
}
if (feature.properties.Adresse) {
html += '<p class="adress">' + feature.properties.Adresse + '</p>';
}
if (feature.properties.Cp) {
html += '<p class="cp">' + feature.properties.Cp + '</p>';
}
if (feature.properties.Tel) {
html += '<p class="tel">' + feature.properties.Tel + '</p>';
}
if (feature.properties.Fax) {
html += '<p class="fax">' + feature.properties.Fax + '</p>';
}
if (feature.properties.Mail) {
html += '<p class="mail"><a href="mailto:' + feature.properties.Mail +'">' + feature.properties.Mail + '</a></p>';
}
if (feature.properties.Tel2) {
html += '<p class="tel">' + feature.properties.Tel2 + '</p>';
}
if (feature.properties.Fax2) {
html += '<p class="fax">' + feature.properties.Fax2 + '</p>';
}
if (feature.properties.Mail2) {
html += '<p class="mail"><a href="mailto:' + feature.properties.Mail2 +'">' + feature.properties.Mail2 + '</a></p>';
}
if (feature.properties.Renseignement) {
html += '<p class="rt">' + feature.properties.Renseignement + '</p>';
}
if (feature.properties.Url) {
html += '<p class="url"><a href="' + feature.properties.Url + '">' + feature.properties.Url + '</a></p>';
}
html+='<div class="pictos">';
if (feature.properties.Examen) {
html += '<span class="' + feature.properties.Examen + '">' + feature.properties.Examen + '</span>';
}
html+='</div>';
layer.on('click', function() {
$('#layer_infos .fill').html(html);
if (L.Browser.mobile) {
$('#infos').addClass("slide");
$('#filters').removeClass('slide');
$('.hamburger').text('Sélectionner un examen').fadeIn();
}
})
}
I'm duplicating this last part for my second map in tab 2. Then I create my cluster groups
var promise = $.getJSON("examen.json");
/*cluster for the first map */
var clusters = L.markerClusterGroup({
spiderfyOnMaxZoom: false,
showCoverageOnHover: false,
zoomToBoundsOnClick: true
});
Here is my cluster click action with associated html. I'm targetting the markers inside the selected cluster only. I'm also duplicating this code for my second map !
clusters.on('clusterclick', function(a){
if(a.layer._zoom == 18){
var html = '';
for (feat in a.layer._markers){
if (a.layer._markers[feat].feature.properties['Professeur']) {
html += '<p class="prof">' + a.layer._markers[feat].feature.properties['Professeur'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Professeur2']) {
html += '<p class="prof2">' + a.layer._markers[feat].feature.properties['Professeur2'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Chu']) {
html += '<p class="chu">' + a.layer._markers[feat].feature.properties['Chu'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Laboratoire']) {
html += '<p class="labo">' + a.layer._markers[feat].feature.properties['Laboratoire'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Prelevement']) {
html += '<p>' + a.layer._markers[feat].feature.properties['Prelevement'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Envoi']) {
html += '<p>' + a.layer._markers[feat].feature.properties['Envoi'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Adresse']) {
html += '<p class="adress">' + a.layer._markers[feat].feature.properties['Adresse'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Cp']) {
html += '<p class="cp">' + a.layer._markers[feat].feature.properties['Cp'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Tel']) {
html += '<p class="tel">' + a.layer._markers[feat].feature.properties['Tel'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Fax']) {
html += '<p class="fax">' + a.layer._markers[feat].feature.properties['Fax'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Mail']) {
html += '<p class="mail"><a href="mailto:' + a.layer._markers[feat].feature.properties['Mail'] +'">' + a.layer._markers[feat].feature.properties['Mail'] + '</a></p>';
}
if (a.layer._markers[feat].feature.properties['Tel2']) {
html += '<p class="tel">' + a.layer._markers[feat].feature.properties['Tel2'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Fax2']) {
html += '<p class="fax">' + a.layer._markers[feat].feature.properties['Fax2'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Mail2']) {
html += '<p class="mail"><a href="mailto:' + a.layer._markers[feat].feature.properties['Mail2'] +'">' + a.layer._markers[feat].feature.properties['Mail2'] + '</a></p>';
}
if (a.layer._markers[feat].feature.properties['Renseignement']) {
html += '<p class="rt">' + a.layer._markers[feat].feature.properties['Renseignement'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Url']) {
html += '<p class="url"><a href="' + a.layer._markers[feat].feature.properties['Url'] + '">' + a.layer._markers[feat].feature.properties['Url'] + '</a></p>';
}
html+='<div class="pictos">';
if (a.layer._markers[feat].feature.properties['Examen']) {
html += '<span class="' + a.layer._markers[feat].feature.properties['Examen'] + '">' + a.layer._markers[feat].feature.properties['Examen'] + '</span>';
}
html+='</div>';
}
$('#layer_infos .fill').html(html);
}
})
Then, here an example of how I get geoJson data
promise.then(function(data) {
var allexamens = L.geoJson(data);
/* related filters and makers */
var ccl18 = L.geoJson(data, {
filter: function(feature, layer) {
return feature.properties.Examen == "ccl18";
},
onEachFeature: onEachFeature,
pointToLayer: function(feature, latlng) {
return L.marker(latlng, {
icon: ccl18Icon
})
}
})
And here is an example of my click action on filters
$("#ccl18").click(function() {
if (this.checked) {
ccl18.addTo(clusters);
map.fitBounds(allexamens.getBounds(), {
padding: [50, 50]
});
} else {
clusters.removeLayer(ccl18);
map.fitBounds(allexamens.getBounds(), {
padding: [50, 50]
});
}
});
Thenn I close my "promise.then(function(data) {"
});
And At the end I call my clusters, and close my $(document).ready(function(){..
clusters.addTo(map);
clusterade.addTo(map2);
});
With all this code, I have my map working as expected. Single markers, and clusters.
So before I had this :
And now, When I click on clusters, instead of having separated markers, I get the data of the markers contained in "this" cluster only, and display it in a pannel
spiderfyShapePositions
option, but would probably be very complicated. In initial very broad question you mentioned that you likedL.Marker.Stack
plugin, but could not make it work. I found solution for that, so post new question with what you have tried with this plugin.