diff --git a/umap/static/umap/css/form.css b/umap/static/umap/css/form.css index 1d61cab72..10f12f2c4 100644 --- a/umap/static/umap/css/form.css +++ b/umap/static/umap/css/form.css @@ -1,3 +1,6 @@ +.umap-form-inline { + display: inline; +} input[type="text"], input[type="password"], input[type="date"], input[type="datetime-local"], input[type="email"], input[type="number"], input[type="search"], input[type="tel"], input[type="time"], input[type="file"], diff --git a/umap/static/umap/js/modules/umap.js b/umap/static/umap/js/modules/umap.js index 68a325d2a..f61fc714c 100644 --- a/umap/static/umap/js/modules/umap.js +++ b/umap/static/umap/js/modules/umap.js @@ -1423,9 +1423,14 @@ export default class Umap extends ServerStored { const row = DomUtil.create('li', 'orderable', ul) DomUtil.createIcon(row, 'icon-drag', translate('Drag to reorder')) datalayer.renderToolbox(row) - const title = DomUtil.add('span', '', row, datalayer.options.name) + const builder = new U.FormBuilder( + datalayer, + [['options.name', { handler: 'EditableText' }]], + { className: 'umap-form-inline' } + ) + const form = builder.build() + row.appendChild(form) row.classList.toggle('off', !datalayer.isVisible()) - title.textContent = datalayer.options.name row.dataset.id = stamp(datalayer) }) const onReorder = (src, dst, initialIndex, finalIndex) => { diff --git a/umap/static/umap/js/umap.forms.js b/umap/static/umap/js/umap.forms.js index 1cc384a31..c0601fedb 100644 --- a/umap/static/umap/js/umap.forms.js +++ b/umap/static/umap/js/umap.forms.js @@ -259,6 +259,35 @@ L.FormBuilder.CheckBox.include({ }, }) +L.FormBuilder.EditableText = L.FormBuilder.Element.extend({ + build: function () { + this.input = L.DomUtil.create('span', this.options.className || '', this.parentNode) + this.input.contentEditable = true + this.fetch() + L.DomEvent.on(this.input, 'input', this.sync, this) + L.DomEvent.on(this.input, 'keypress', this.onKeyPress, this) + }, + + getParentNode: function () { + return this.form + }, + + value: function () { + return this.input.textContent + }, + + fetch: function () { + this.input.textContent = this.toHTML() + }, + + onKeyPress: function (event) { + if (event.keyCode === 13) { + event.preventDefault() + this.input.blur() + } + }, +}) + L.FormBuilder.ColorPicker = L.FormBuilder.Input.extend({ colors: U.COLORS, getParentNode: function () { diff --git a/umap/tests/integration/test_edit_datalayer.py b/umap/tests/integration/test_edit_datalayer.py index bc22c2234..f9a9fa076 100644 --- a/umap/tests/integration/test_edit_datalayer.py +++ b/umap/tests/integration/test_edit_datalayer.py @@ -221,3 +221,14 @@ def test_deleting_datalayer_should_remove_from_caption( page.locator(".panel.right").get_by_title("Delete layer").click() page.get_by_role("button", name="OK").click() expect(panel.get_by_text("test datalayer")).to_be_hidden() + + +def test_can_edit_datalayer_name_in_list(live_server, openmap, datalayer, page): + page.goto(f"{live_server.url}{openmap.get_absolute_url()}?edit") + page.get_by_role("link", name="Manage layers").click() + page.get_by_text("test datalayer").click() + page.get_by_text("test datalayer").fill("test datalayer foobar") + page.get_by_role("button", name="Open browser").click() + expect( + page.locator(".panel.left").get_by_text("test datalayer foobar") + ).to_be_visible()