Search code examples
twitter-bootstrappopupleafletpopover

Bootstrap popover not working inside of leaflet popup


So as per the title, I'm trying to put some bootstrap popover functionality inside of a leaflet popup. Specifically, I'm aiming to do this:

enter image description here

But in a leaflet popup. I'm using Django and a HTML snippet to generate the table (with the info icons you hover over for the popover) which is used in both the sidebar and the popup so the code is identical, yet the sidebar popovers appear fine and nothing happens when hovering over the info icon in the leaflet popup. The HTML I'm using to generate the popover is:

<th>
Stats date&nbsp;<a tabindex="0" data-toggle="popover" data-trigger="hover click" data-content="Dates for which the statistics below are calculated" class="info-popover"><span class="gtfse-icons-info2 info"></span></a>
</th>

I have a feeling it has something to do with the watcher I placed as per the bootstrap docs:

$(document).ready(function() {
    $('[data-toggle="popover"]').popover()
}

not being heard for map events, but don't know enough about leaflet (or JS in general) to diagnose why...

Any help would be much appreciated


Solution

  • Your popover never gets attached because the popup isn't present in the DOM yet. The popup get inserted into the DOM when you click the marker or use the openPopup method of the popup. There is a way to make this work but it's really hacky. So here it goes:

    You need to listen for the popupopen event on the map and then initialize your popup like this:

    map.on('popupopen', function(){
        $(function () {
            $('[data-toggle="popover"]').popover();
        });
    });
    

    EDIT: Just realized that if you could suffice with only hover trigger of the popover, you wouldn't be facing the problem described below:

    But now you have a problem. When a the popover is opened and a user clicks the map or the close button on the popup, the popup closes and the popover doesn't. There is a popupclose event you could attach a handler on, so you would say this should work:

    map.on('popupclose', function(){
        $(function () {
            $('[data-toggle="popover"]').popover('destroy');
        });
    });
    

    But it doesn't. I'm guessing the popup's DOM get destroyed so quickly that the popover doesn't have the time to close. But you could still get it to work. Now for the hacky part. Disable the closeButton and clickOnClose options on the popup by adding popup options:

    marker.bindPopup(/* content */, {'closeButton': false, 'closeOnClick': false});
    

    Add your own close button to your popup::

    <button id="popup-close" class="btn btn-default">X</button>
    

    With that you can close the popup yourself after you've close the popover. Changed eventhandler function to:

    map.on('popupopen', function(openEvent){
        $(function () {
            $('[data-toggle="popover"]').popover();              // initialize popover
            $('#popup-close').on('click', function(){            // listen for click on close
                $('[data-toggle="popover"]').popover('destroy'); // destroy popover
                map.closePopup();                                // close popup
            });
        });
    });
    

    This is really quick and dirty, if you're gonna do this you should also clean up the clickhandler on the close button and restore the onCloseClick functionality by listening for mapclick event etc. I'm just showing that it is possible, but really hacky as hell.