Skip to content

Commit 1e5c06b

Browse files
florianmGagaro
authored andcommitted
Add CSS class .django-leaflet-raw-textarea to raw textarea, default width 100% (makinacorpus#249)
* Add CSS class .django-leaflet-raw-textarea to raw textarea, default width 100% * Add link to GeoJSONLint.com to textarea label * Fix whitespace in widget.html * Add hover tip to link in raw textarea label * Add summary to CHANGES * Geometry text area label link: change target to _blank * Fix formatting in leaflet.css * Docs, round 1 * Docs, round 2 * Change to working WMS overlay example
1 parent 8f10a55 commit 1e5c06b

File tree

5 files changed

+194
-7
lines changed

5 files changed

+194
-7
lines changed

CHANGES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ CHANGELOG
66
-------------------
77

88
- #225 changes in staticfiles for django 1.11.14
9+
- #247 Allow resizing of raw Geometry textbox input via CSS, improve label, add docs
10+
- #108 Add examples to docs on adding overlays, customising maps in templates, admin and forms
911
- #248 Allow use of a custom widget in the Admin. (fixes #151)
1012

1113
0.24.0 (2018-06-07)

docs/templates.rst

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ CSS is your friend:
7878
height: 800px;
7979
}
8080

81+
/* Resize the "display_raw" textbox */
82+
.django-leaflet-raw-textarea {
83+
width: 100%;
84+
}
85+
8186
</style>
8287

8388

@@ -147,7 +152,7 @@ list, as shown below.
147152

148153
Note that this will also prevent any overlays defined in settings from being displayed.
149154

150-
155+
.. _overlays:
151156
Overlay layers
152157
~~~~~~~~~~~~~~
153158

@@ -156,8 +161,53 @@ To globally add an overlay layer, use the same syntax as tiles::
156161
'OVERLAYS': [('Cadastral', 'http://server/a/{z}/{x}/{y}.png', {'attribution': '&copy; IGN'})]
157162

158163
Currently, overlay layers from settings are limited to tiles. For vectorial overlays, you
159-
will have to add them via JavaScript (see events).
164+
will have to add them via JavaScript (see also events).
165+
166+
.. new section: worked example on including WMS overlays
167+
To add layers other than the tiles supported by the global config, e.g. WMS layers,
168+
insert a script block, get a reference to the map's ``layerscontrol``, and add any layer supported by Leaflet
169+
as overlays to that layerscontrol object.
170+
171+
172+
In a template:
173+
174+
::
175+
176+
{% block content %}
177+
{% leaflet_map "detailmap" callback="window.map_init" %}
178+
{% endblock %}
179+
180+
181+
{% block javascript %}
182+
{{ block.super }}
183+
<script type="text/javascript">
184+
function map_init(map, options) {
185+
{% include 'shared/overlays.html' %}
186+
}
187+
</script>
188+
{% endblock %}
189+
190+
In a snippet, here called ``shared/overlays.html``, the overlays are configured.
191+
Doing so in a snippet allows the same set of overlays to be re-used across other maps in your Django project.
192+
193+
``shared/overlays.html``:
194+
195+
::
196+
197+
var lc = map.layerscontrol;
198+
199+
// An example from the Atlas of Living Australia https://www.ala.org.au/
200+
lc.addOverlay(
201+
L.tileLayer.wms(
202+
'https://spatial-beta.ala.org.au/geoserver/ALA/wms',
203+
{layers: 'ALA:aus2', format: 'image/png', transparent: true}),
204+
'Australia'
205+
);
206+
207+
// add lc.addOverlay() layers as needed
160208

209+
For an overview of available layer types and options, see the
210+
[Leaflet docs on tile layers](https://leafletjs.com/examples/wms/wms.html).
161211

162212
Attribution prefix
163213
~~~~~~~~~~~~~~~~~~

docs/widget.rst

Lines changed: 127 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ It embeds *Leaflet.draw* in version *0.4.0*.
77

88
.. image :: https://f.cloud.github.com/assets/546692/1048836/78b6ad94-1094-11e3-86d8-c3e88626a31d.png
99
10-
10+
.. _admin:
1111
In Adminsite
1212
------------
1313

@@ -33,6 +33,89 @@ A mixin is also available for inline forms:
3333
model = PoiLocation
3434

3535

36+
To modify the map widget used in the Django admin,
37+
override a custom ``admin/change_form.html``:
38+
39+
::
40+
41+
{% extends "admin/change_form.html" %}
42+
{% load i18n admin_urls staticfiles leaflet_tags %}
43+
44+
{% block stylesheets %}
45+
{{ block.super }}
46+
{% leaflet_css plugins="ALL" %}
47+
<style>
48+
/* Force leaflet controls underneath header (z-index 1000) and
49+
above leaflet tiles (z-index 400)*/
50+
.leaflet-top{z-index:999;}
51+
</style>
52+
{% endblock %}
53+
54+
{% block javascripts %}
55+
{{ block.super }}
56+
{% leaflet_js plugins="ALL" %}
57+
{% include 'shared/leaflet_widget_overlays.js' %}
58+
{% endblock %}
59+
60+
In this way, both CSS and JS can be modified for all admin leaflet widgets.
61+
62+
As an example of modifying the CSS, here the leaflet map widget controls
63+
are forced underneath a bootstrap4 navbar.
64+
65+
As an example of modifying the JS, a custom snippet called
66+
``shared/leaflet_widget_overlays.js`` uses the map init event to add
67+
some custom (non-tile) overlays.
68+
69+
::
70+
71+
<script type="text/javascript">
72+
window.addEventListener("map:init", function (event) {
73+
var map = event.detail.map; // Get reference to map
74+
{% include 'shared/overlays.html' %}
75+
76+
// Other modifications, e.g. fullscreen control:
77+
map.addControl(new L.Control.Fullscreen());
78+
// Note, this requires the Leaflet fullscreen CSS, JS,
79+
// and image assets to be present as static files,
80+
// and configured in LEAFLET_SETTINGS
81+
});
82+
</script>
83+
84+
Again, the actual overlays here are factored out into a separate snippet.
85+
In this example, we re-use ``shared/overlays.html`` as also shown in ref::overlays_.
86+
87+
To show a textarea input for the raw GeoJSON geometry, override admin ``form_fields``:
88+
89+
::
90+
from django.contrib.gis.db import models as geo_models
91+
92+
LEAFLET_WIDGET_ATTRS = {
93+
'map_height': '500px',
94+
'map_width': '100%',
95+
'display_raw': 'true',
96+
'map_srid': 4326,
97+
}
98+
99+
LEAFLET_FIELD_OPTIONS = {'widget': LeafletWidget(attrs=LEAFLET_WIDGET_ATTRS)}
100+
101+
FORMFIELD_OVERRIDES = {
102+
geo_models.PointField: LEAFLET_FIELD_OPTIONS,
103+
geo_models.MultiPointField: LEAFLET_FIELD_OPTIONS,
104+
geo_models.LineStringField: LEAFLET_FIELD_OPTIONS,
105+
geo_models.MultiLineStringField: LEAFLET_FIELD_OPTIONS,
106+
geo_models.PolygonField: LEAFLET_FIELD_OPTIONS,
107+
geo_models.MultiPolygonField: LEAFLET_FIELD_OPTIONS,
108+
}
109+
110+
class MyAdmin(admin.ModelAdmin):
111+
112+
formfield_overrides = FORMFIELD_OVERRIDES
113+
114+
115+
The widget attribute `display_raw` toggles the textarea input.
116+
The textarea can be resized by overriding its CSS class ``.django-leaflet-raw-textarea``.
117+
118+
36119
In forms
37120
--------
38121

@@ -52,6 +135,9 @@ With *Django* >= 1.6:
52135
fields = ('name', 'geom')
53136
widgets = {'geom': LeafletWidget()}
54137

138+
Again, the LeafletWidget can be intialized with custom attributes,
139+
e.g. ``LeafletWidget(attrs=LEAFLET_WIDGET_ATTRS)`` as shown above.
140+
55141
With all *Django* versions:
56142

57143
::
@@ -100,7 +186,9 @@ Every map field will trigger an event you can use to add your custom machinery :
100186
});
101187

102188

103-
If you need a reusable customization of widgets maps, first override the JavaScript field behaviour by extending ``L.GeometryField``, then in Django subclass the ``LeafletWidget`` to specify the custom ``geometry_field_class``.
189+
If you need a reusable customization of widgets maps, first override the JavaScript
190+
field behavior by extending ``L.GeometryField``, then in *Django* subclass the
191+
``LeafletWidget`` to specify the custom ``geometry_field_class``.
104192

105193
::
106194

@@ -124,6 +212,43 @@ If you need a reusable customization of widgets maps, first override the JavaScr
124212
fields = ('name', 'geom')
125213
widgets = {'geom': YourMapWidget()}
126214

215+
216+
To customise individual forms, you can either extend the geometry field as shown above,
217+
or inject a script into the form template.
218+
219+
In this example, a custom set of overlays is added as shown for both ref::overlays_
220+
and ref::admin_ widgets, insert an extra script into the form template
221+
in the same way as shown in ref::admin_.
222+
223+
::
224+
225+
{% extends "base.html" %}
226+
{% load staticfiles leaflet_tags geojson_tags crispy_forms_tags bootstrap4 %}
227+
228+
<!-- The form -->
229+
{% block content %}
230+
<div class="container">
231+
<div class="row">
232+
<div class="col-12">
233+
{% crispy form form.helper %}
234+
</div><!-- .col -->
235+
</div><!-- .row -->
236+
</div><!-- .container -->
237+
{% endblock %}
238+
239+
{% block extrastyle %}
240+
{% leaflet_css plugins="ALL" %}
241+
{{ form.media.css }}
242+
{% endblock %}
243+
244+
{% block extrajs %}
245+
{% leaflet_js plugins="ALL" %}
246+
{{ form.media.js }}
247+
{% include 'shared/leaflet_widget_overlays.js' %}
248+
{% endblock extrajs %}
249+
250+
251+
127252
Plugins
128253
-------
129254

leaflet/static/leaflet/leaflet.css

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,6 @@
550550

551551

552552
/* div icon */
553-
554553
.leaflet-div-icon {
555554
background: #fff;
556555
border: 1px solid #666;
@@ -634,3 +633,8 @@
634633
margin-left: -12px;
635634
border-right-color: #fff;
636635
}
636+
637+
/* Resize the "display_raw" textbox */
638+
.django-leaflet-raw-textarea {
639+
width: 100%;
640+
}

leaflet/templates/leaflet/widget.html

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,11 @@
4141
{% endblock map %}
4242
{% endif %}
4343

44-
{% if display_raw %}<p> Geometry:</p>{% endif %}
45-
<textarea id="{{ id_css }}" class="required" cols="150" rows="10" name="{{ name }}">{{ serialized }}</textarea>
44+
{% if display_raw %}
45+
<p>Draw on map or paste a <a
46+
href="http://geojsonlint.com/"
47+
title="Validate your GeoJSON Geometry at GeoJSONLint.com in a new window"
48+
target="_blank"
49+
rel="nofollow">valid GeoJSON Geometry</a>:</p>
50+
{% endif %}
51+
<textarea id="{{ id_css }}" class="required django-leaflet-raw-textarea" cols="150" rows="10" name="{{ name }}">{{ serialized }}</textarea>

0 commit comments

Comments
 (0)