Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting a reference to a leafletjs instance from a django-leaflet form

Using django-leaflet I've created a form as follows

class AnnotationForm(forms.ModelForm):
     <crispy forms stuff redacted from here for brevity>     

    class Meta:
        model = Annotation # Your user model
        fields= ['name','annotationType','description','location_point','document','e']
        widgets = {'location_point': LeafletWidget(),'e':forms.HiddenInput()}

Its instantiated from a view in the normal way.

And in the templates;-

        {% crispy annotation_form %}

Now. At the start on body load, it hides the div containing the map, and elsewhere there is some code that essentially watches the annotationType dropdown, and if "location" is selected it unhides the div.

The problem is , it appears leafletjs does not like being instantiated hidden, and seems to get a bit confused about its bounds. Im assuming the answer thus is to call _onresize() on the map, however I can't seem to find how to get a reference to the map instance.

L.map('id_annotation_location_point_map')._onResize()

..just produces a complaint that the map is already initialized. Inspecting the code generated by the form seems to have the map being created inside a (function() { etc etc } )() type closure which makes just hijacking the variable from there infeasible.

So my question is, how DOES one get a reference to a leaflet.js map in this sort of situation?

There is How can I get a leaflet.js instance using only a DOM object? but it doesn't seem to actually answer the question, just propose an alternative that isn't available in my case.

like image 763
Shayne Avatar asked Oct 01 '22 16:10

Shayne


1 Answers

I had exactly the same problem - was rendering a map in a hidden div using django-leaflet and couldn't figure out how to trigger the _onResize/invalidateSize functions.

I don't know that it's a particularly good solution, but what I did was grab the reference to the map from the map:init event, like this:

$(document).ready(function() {
    // Store the variable to hold the map in scope
    var map;
    
    // Populate the map var during the map:init event (see Using Javascript callback function)
    // here https://github.com/makinacorpus/django-leaflet
    $(window).on('map:init', function(e) {
      map = e.originalEvent.detail.map;
    });

    // Hide the map
    $('#hiddenDivWithMap').hide();

    // Click the thing which shows the map
    $('#myButton').click(function() {
      $('#hiddenDivWithMap').show();
      map.invalidateSize()
    });
});

This works, for me anyway. It doesn't set the zoom/extent/bounds of the map though, I need to figure out how to do that still.

like image 79
rkian Avatar answered Oct 12 '22 16:10

rkian