atmist / snazzy-info-window

Customizable info windows using the Google Maps JavaScript API.
MIT License
614 stars 127 forks source link

Bootstrap Modal won't open from Snazzy infowindow #26

Open szlobi opened 7 years ago

szlobi commented 7 years ago

Hi there,

Trying to open a simple Bootstrap Modal from a Snazzy infowindow, but it just doesn't show up, while the same button outside from Google Maps will pop it up easily. Am I doing it wrong or it needs some enhancement (see code below)?

Thanks for your nice job with Snazzy!

<button id="buttonOutside" type="button" data-toggle="modal" data-target="#myModal">Open Modal</button>
<div id="myModal" class="modal fade" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-body">
                <p>modalcontent</p>
            </div>
        </div>
    </div>
</div>

<div class="map-canvas"></div>

<script>
$(function() {
    var map = new google.maps.Map($('.map-canvas')[0], {
        zoom: 14,
        center: new google.maps.LatLng(40.72, -74)
    });
    var marker = new google.maps.Marker({
        map: map,
        position: new google.maps.LatLng(40.72, -74)
    });
    var info = new SnazzyInfoWindow({
        marker: marker,
        content: 'infowindow content<br><button id="buttonInside" type="button" data-toggle="modal" data-target="#myModal">Open Modal</button>'
    });
}); 
</script>
CaptnClumsy commented 6 years ago

I had the same issue, basically none of the bootstrap controls work within a SnazzyInfoWindow. The problem is that the SnazzyInfoWindow stops all event propogation to other elements in the DOM so Bootstrap does not get notified when for example a dropdown needs expanding. This was critical for my project so I hacked the source for SnazzyInfoWindow and got it working. My modification is pretty hacky lol. First I removed the code that stops event propogation, and now, boom, bootstrap works inside the SnazzyInfoWindow, but it also means clicking or dragging the mouse in the SnazzyInfoWindow affects the map below it (since events are now being propogated to the lower DIVs). So next I modified it such that the floating window used by SnazzyInfoWindow was attached to the document body instead of embedded in the float pane of the map. Now great, no need to stop event propogation and bootstrap works and events do not fall through to the map. But because the window is not inside the map float pane I also had to modify it to move the info window when the map scrolls and I had to use screen coordinates not relative DIV coordinates when working out positions and such like. My modification works fine for me...but the author might want to see what I did and see if there is a more elegant way of including this into SnazzyInfoWindow. Attached is my modified JavaScript code. SnazzyInfoWindowHacked.zip

schnoodly commented 6 years ago

I'm gonna make an assumption, but I believe Bootstrap initializes everything on DOM ready/loading. So a SnazzyWindow, which creates elements in the DOM on command, will not have their contents initialized - a simple fix would be to use Bootstrap's modal init method(s) on the open event for the SnazzyWindow.

goldfinch commented 6 years ago

My workaround was to use callbacks and hash, here is an example if someone is looking for a solution

new SnazzyInfoWindow({
  ...
  callbacks: {

    beforeOpen: function(){

      window.history.replaceState(null, null, ' ');

      $('#modal-target').unbind().modal('dispose').modal('hide').on('hide.bs.modal', function(e) {

        window.history.replaceState(null, null, ' ');

      });

    },

    beforeClose: function(){

      window.history.replaceState(null, null, ' ');

      $('#modal-target').modal('dispose');

    }

  }
});

$(window).on('hashchange', function(e){

  $(window.location.hash).modal('show');

})