Skip to content

Commit 9f549cd

Browse files
committed
Template-based importer (vs. using L.DomUtil)
1 parent 8ce09b0 commit 9f549cd

File tree

3 files changed

+99
-104
lines changed

3 files changed

+99
-104
lines changed

umap/static/umap/js/umap.core.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -482,12 +482,10 @@ L.U.Help = L.Class.extend({
482482
return typeof this[name] === 'function' ? this[name]() : this[name]
483483
},
484484

485-
button: function (container, entries, classname) {
486-
const helpButton = L.DomUtil.createButton(
487-
classname || 'umap-help-button',
488-
container,
489-
L._('Help')
490-
)
485+
button: function (container, entries, classname, button) {
486+
const helpButton =
487+
button ||
488+
L.DomUtil.createButton(classname || 'umap-help-button', container, L._('Help'))
491489
if (entries) {
492490
L.DomEvent.on(helpButton, 'click', L.DomEvent.stop).on(
493491
helpButton,

umap/static/umap/js/umap.importer.js

Lines changed: 54 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,80 @@
11
L.U.Importer = L.Class.extend({
2-
TYPES: ['geojson', 'csv', 'gpx', 'kml', 'osm', 'georss', 'umap'],
32
initialize: function (map) {
43
this.map = map
54
this.presets = map.options.importPresets
65
},
76

8-
build: function () {
9-
this.container = L.DomUtil.create('div', 'umap-upload')
10-
this.title = L.DomUtil.add('h4', '', this.container, L._('Import data'))
11-
this.presetBox = L.DomUtil.create('div', 'formbox', this.container)
12-
this.presetSelect = L.DomUtil.create('select', '', this.presetBox)
13-
this.fileBox = L.DomUtil.create('div', 'formbox', this.container)
14-
this.fileInput = L.DomUtil.element(
15-
'input',
16-
{ type: 'file', multiple: 'multiple', autofocus: true },
17-
this.fileBox
18-
)
19-
this.urlInput = L.DomUtil.element(
20-
'input',
21-
{ type: 'text', placeholder: L._('Provide an URL here') },
22-
this.container
23-
)
24-
this.rawInput = L.DomUtil.element(
25-
'textarea',
26-
{ placeholder: L._('Paste your data here') },
27-
this.container
28-
)
29-
this.typeLabel = L.DomUtil.add(
30-
'label',
31-
'',
32-
this.container,
33-
L._('Choose the format of the data to import')
34-
)
35-
this.layerLabel = L.DomUtil.add(
36-
'label',
37-
'',
38-
this.container,
39-
L._('Choose the layer to import in')
40-
)
41-
this.clearLabel = L.DomUtil.add(
42-
'label',
43-
'',
44-
this.container,
45-
L._('Replace layer content')
46-
)
47-
this.submitInput = L.DomUtil.element(
48-
'input',
49-
{ type: 'button', value: L._('Import'), className: 'button' },
50-
this.container
51-
)
52-
this.map.help.button(this.typeLabel, 'importFormats')
53-
this.typeInput = L.DomUtil.element('select', { name: 'format' }, this.typeLabel)
54-
this.layerInput = L.DomUtil.element(
55-
'select',
56-
{ name: 'datalayer' },
57-
this.layerLabel
58-
)
59-
this.clearFlag = L.DomUtil.element(
60-
'input',
61-
{ type: 'checkbox', name: 'clear' },
62-
this.clearLabel
63-
)
7+
_buildDatalayerOptions: function (element) {
648
let option
659
this.map.eachDataLayerReverse((datalayer) => {
6610
if (datalayer.isLoaded() && !datalayer.isRemoteLayer()) {
6711
const id = L.stamp(datalayer)
68-
option = L.DomUtil.add('option', '', this.layerInput, datalayer.options.name)
12+
option = L.DomUtil.add('option', '', element, datalayer.options.name)
6913
option.value = id
7014
}
7115
})
7216
L.DomUtil.element(
7317
'option',
7418
{ value: '', textContent: L._('Import in a new layer') },
75-
this.layerInput
76-
)
77-
L.DomUtil.element(
78-
'option',
79-
{ value: '', textContent: L._('Choose the data format') },
80-
this.typeInput
19+
element
8120
)
82-
for (let i = 0; i < this.TYPES.length; i++) {
83-
option = L.DomUtil.create('option', '', this.typeInput)
84-
option.value = option.textContent = this.TYPES[i]
85-
}
21+
},
22+
23+
_buildPresetsOptions: function (element) {
8624
if (this.presets.length) {
87-
const noPreset = L.DomUtil.create('option', '', this.presetSelect)
25+
const presetBox = this.form.querySelector('#preset-box')
26+
presetBox.removeAttribute('hidden')
27+
const noPreset = L.DomUtil.create('option', '', element)
8828
noPreset.value = noPreset.textContent = L._('Choose a preset')
89-
for (let j = 0; j < this.presets.length; j++) {
29+
for (const preset of this.presets) {
9030
option = L.DomUtil.create('option', '', presetSelect)
91-
option.value = this.presets[j].url
92-
option.textContent = this.presets[j].label
31+
option.value = preset.url
32+
option.textContent = preset.label
9333
}
94-
} else {
95-
this.presetBox.style.display = 'none'
9634
}
97-
L.DomEvent.on(this.submitInput, 'click', this.submit, this)
98-
L.DomEvent.on(
99-
this.fileInput,
100-
'change',
101-
(e) => {
102-
let type = '',
103-
newType
104-
for (let i = 0; i < e.target.files.length; i++) {
105-
newType = L.Util.detectFileType(e.target.files[i])
106-
if (!type && newType) type = newType
107-
if (type && newType !== type) {
108-
type = ''
109-
break
110-
}
35+
},
36+
37+
build: function () {
38+
template = document.querySelector('#umap-upload')
39+
this.form = template.content.firstElementChild.cloneNode(true)
40+
this.presetSelect = this.form.querySelector('[name="preset-select"]')
41+
this.fileInput = this.form.querySelector('[name="file-input"]')
42+
this.urlInput = this.form.querySelector('[name="url-input"]')
43+
this.rawInput = this.form.querySelector('[name="raw-input"]')
44+
this.typeLabel = this.form.querySelector('#type-label')
45+
const helpButton = this.typeLabel.querySelector('button')
46+
this.map.help.button(this.typeLabel, 'importFormats', '', helpButton)
47+
this.formatSelect = this.form.querySelector('[name="format"]')
48+
this.layerSelect = this.form.querySelector('[name="datalayer"]')
49+
this.clearFlag = this.form.querySelector('[name="clear"]')
50+
this.submitInput = this.form.querySelector('[name="submit-input"]')
51+
this._buildDatalayerOptions(this.layerSelect)
52+
this._buildPresetsOptions(this.presetSelect)
53+
54+
this.submitInput.addEventListener('click', this.submit.bind(this))
55+
this.fileInput.addEventListener('change', (e) => {
56+
let type = ''
57+
let newType
58+
for (const file of e.target.files) {
59+
newType = L.Util.detectFileType(file)
60+
if (!type && newType) {
61+
type = newType
11162
}
112-
this.typeInput.value = type
113-
},
114-
this
115-
)
63+
if (type && newType !== type) {
64+
type = ''
65+
break
66+
}
67+
}
68+
this.formatSelect.value = type
69+
})
11670
},
11771

11872
open: function () {
119-
if (!this.container) this.build()
120-
this.map.ui.openPanel({ data: { html: this.container }, className: 'dark' })
73+
if (!this.form) this.build()
74+
this.map.ui.openPanel({
75+
data: { html: this.form },
76+
className: 'dark',
77+
})
12178
},
12279

12380
openFiles: function () {
@@ -126,16 +83,16 @@ L.U.Importer = L.Class.extend({
12683
},
12784

12885
submit: function () {
129-
let type = this.typeInput.value
130-
const layerId = this.layerInput[this.layerInput.selectedIndex].value
86+
let type = this.formatSelect.value
87+
const layerId = this.layerSelect[this.layerSelect.selectedIndex].value
13188
let layer
13289
if (type === 'umap') {
13390
this.map.once('postsync', this.map._setDefaultCenter)
13491
}
13592
if (layerId) layer = this.map.datalayers[layerId]
13693
if (layer && this.clearFlag.checked) layer.empty()
13794
if (this.fileInput.files.length) {
138-
for (let i = 0, file; (file = this.fileInput.files[i]); i++) {
95+
for (const file of this.fileInput.files) {
13996
this.map.processFileToImport(file, layer, type)
14097
}
14198
} else {

umap/templates/umap/map_init.html

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,45 @@
1-
{% load umap_tags %}
1+
{% load i18n umap_tags %}
22
<div id="map"></div>
3+
4+
<template id="umap-upload">
5+
<form class="umap-upload">
6+
<h4>{% blocktrans %}Import data{% endblocktrans %}</h4>
7+
<div id="preset-box" class="formbox" hidden>
8+
<select name="preset-select"></select>
9+
</div>
10+
<div class="formbox">
11+
<input type="file" name="file-input" multiple>
12+
</div>
13+
<input type="url" name="url-input" placeholder="{% blocktrans %}Provide an URL here{% endblocktrans %}">
14+
<textarea name="raw-input" placeholder="{% blocktrans %}Paste your data here{% endblocktrans %}"></textarea>
15+
16+
<label id="type-label">
17+
{% blocktrans %}Choose the format of the data to import{% endblocktrans %}
18+
<button class="umap-help-button" type="button">{% blocktrans %}Help{% endblocktrans %}</button>
19+
<select name="format">
20+
<option value disabled selected>
21+
{% blocktrans %}Choose the data format{% endblocktrans %}
22+
</option>
23+
<option value="geojson">geojson</option>
24+
<option value="csv">csv</option>
25+
<option value="gpx">gpx</option>
26+
<option value="kml">kml</option>
27+
<option value="osm">osm</option>
28+
<option value="georss">georss</option>
29+
<option value="umap">umap</option>
30+
</select>
31+
</label>
32+
<label id="layer-label">
33+
{% blocktrans %}Choose the layer to import in{% endblocktrans %}
34+
<select name="datalayer"></select>
35+
</label>
36+
<label>
37+
{% blocktrans %}Replace layer content{% endblocktrans %}
38+
<input type="checkbox" name="clear">
39+
</label>
40+
<input type="button" class="button" name="submit-input" value="{% blocktrans %}Import{% endblocktrans %}">
41+
</form>
42+
</template>
343
<!-- djlint:off -->
444
<script type="text/javascript">
545
let MAP = new L.U.Map("map", {{ map_settings|notag|safe }})

0 commit comments

Comments
 (0)