1
votes

I'm using this library on my Java project. I does include it along with some other leaflet plugins in my jsp file. In the script, I encounter a very strange and seem-to-be-impossible error. If I initialize the map with a context menu, map's context menu will show up. But the similar thing does not happen with the marker. My markers are not static and only created when a button is clicked, as seen in this function:

function handleItem(item) {

    var tbody=$('#traffic-data').find('tbody');

    var row=document.createElement("tr");
    row.setAttribute('class','danger');
    row.setAttribute("from-lat",item.fromLat);
    row.setAttribute("from-lng",item.fromLng);
    row.setAttribute("to-lat",item.toLat);
    row.setAttribute("to-lng",item.toLng);

    var cenLat=(item.fromLat+item.toLat)/2;
    var cenLng=(item.fromLng+item.toLng)/2;

    var cell=document.createElement("td");
    geocodeService.reverse().latlng([cenLat,cenLng]).run(function(error, result) {
        if (!error){
            cell.innerHTML=result.address.Match_addr;
        }
        cell.onclick=function(){
            focusJam(cenLat,cenLng);
        };
        row.appendChild(cell);

        cell=document.createElement("td");
        cell.innerHTML=new Date();
        row.appendChild(cell);

        cell=document.createElement("td");
        cell.innerHTML=item.velocity;
        row.appendChild(cell);

        cell=document.createElement("td");
        row.appendChild(cell);

        cell=document.createElement("td");
        cell.innerHTML=Math.round(L.latLng(item.fromLat,item.toLng)
            .distanceTo(L.latLng(item.toLat,item.toLng)));
        row.appendChild(cell);

        cell=document.createElement("td");
        row.appendChild(cell);

        cell=document.createElement("td");
        var action=document.createElement('span');
        action.setAttribute('class','glyphicon glyphicon-ok-sign');
        action.onclick=function(){
            row.removeAttribute('class');
            row.setAttribute('class','info');
            L.marker(L.latLng(cenLat,cenLng),{icon:customDefaultIcon},{
                contextmenu: true,
                contextmenuWidth: 140,
                contextmenuItems: [{
                    text: 'Marker item',
                    index: 0
                }, {
                    separator: 'Marker item',
                    index: 1
                }]
            }).addTo(map);
        };
        cell.append(action);
        action=document.createElement('span');
        action.setAttribute('class','glyphicon glyphicon-trash');
        action.onclick=function(){
            row.remove();
        };
        cell.append(action);
        row.appendChild(cell);

        tbody.append(row);
    });

};

Strange enough, this marker initialization:

L.marker(L.latLng(cenLat,cenLng),{icon:customDefaultIcon},{
                contextmenu: true,
                contextmenuWidth: 140,
                contextmenuItems: [{
                    text: 'Marker item',
                    index: 0
                }, {
                    separator: 'Marker item',
                    index: 1
                }]
            }).addTo(map);

was completely in vain, only renders the marker but not the context menu when rightclicked. But if I initialize like this:

L.marker(L.latLng(cenLat,cenLng),{
                contextmenu: true,
                contextmenuWidth: 140,
                contextmenuItems: [{
                    text: 'Marker item',
                    index: 0
                }, {
                    separator: 'Marker item',
                    index: 1
                }]
            },{icon:customDefaultIcon}).addTo(map);

the context menu will be rendered when rightclicked as usual, but the marker has no icon and only renders the alt attribute. In addition, this context menu does not disappear when I click out of it, even duplicate when I rightclick it once again. This error is too nonsense and I can't get why

1

1 Answers

3
votes

The L.Marker constructor takes in one set of options:

var m1 = L.marker(latlng, options);       // good
var m2 = L.marker(latlng, opts1, opts2);  // wrong

So this is wrong:

var opts1 = {
            contextmenu: true,
            contextmenuWidth: 140,
            contextmenuItems: [{
                text: 'Marker item',
                index: 0
              }, {
                separator: 'Marker item',
                index: 1
              }]
            };

var opts2 = {icon:customDefaultIcon};

L.marker(L.latLng(cenLat,cenLng), opts1, opts2).addTo(map);

And this is right:

var opts = {
            contextmenu: true,
            contextmenuWidth: 140,
            contextmenuItems: [{
                text: 'Marker item',
                index: 0
              }, {
                separator: 'Marker item',
                index: 1
              }],
            icon: customDefaultIcon
            };

L.marker(L.latLng(cenLat,cenLng), opts).addTo(map);

Be careful to not confuse yourself when setting the set of options, specially if some of your options are arrays of dictionaries. Create aux variables as needed to make your code more readable, e.g.:

var menuitems = [{
                  text: 'Marker item',
                  index: 0
                }, {
                  separator: 'Marker item',
                  index: 1
                }];

var opts = {
            contextmenu: true,
            contextmenuWidth: 140,
            contextmenuItems: menuitems,
            icon: customDefaultIcon
            };

L.marker(L.latLng(cenLat,cenLng), opts).addTo(map);