picto field: better handling of default input values
We don't want to have an URL in the "char" field, and vice versa
This commit is contained in:
parent
c581172197
commit
cdfcce297d
2 changed files with 85 additions and 65 deletions
|
@ -525,38 +525,50 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
||||||
|
|
||||||
build: function () {
|
build: function () {
|
||||||
L.FormBuilder.BlurInput.prototype.build.call(this)
|
L.FormBuilder.BlurInput.prototype.build.call(this)
|
||||||
this.buttonsContainer = L.DomUtil.create('div', '')
|
this.buttons = L.DomUtil.create('div', '', this.parentNode)
|
||||||
this.pictogramsContainer = L.DomUtil.create('div', 'umap-pictogram-list')
|
this.tabs = L.DomUtil.create('div', 'pictogram-tabs', this.parentNode)
|
||||||
this.tabsContainer = L.DomUtil.create('div', 'pictogram-tabs')
|
this.body = L.DomUtil.create('div', 'umap-pictogram-body', this.parentNode)
|
||||||
L.DomUtil.before(this.input, this.buttonsContainer)
|
this.footer = L.DomUtil.create('div', '', this.parentNode)
|
||||||
L.DomUtil.before(this.input, this.tabsContainer)
|
|
||||||
L.DomUtil.before(this.input, this.pictogramsContainer)
|
|
||||||
this.udpatePreview()
|
this.udpatePreview()
|
||||||
this.on('define', this.onDefine)
|
this.on('define', this.onDefine)
|
||||||
},
|
},
|
||||||
|
|
||||||
onDefine: function () {
|
onDefine: function () {
|
||||||
|
this.buttons.innerHTML = ''
|
||||||
this.buildTabs()
|
this.buildTabs()
|
||||||
const value = this.value()
|
const value = this.value()
|
||||||
if (!value || value.startsWith('/')) this.showSymbolsTab()
|
if (!value || value.startsWith('/')) this.showSymbolsTab()
|
||||||
else if (value.startsWith('http')) this.showURLTab()
|
else if (value.startsWith('http')) this.showURLTab()
|
||||||
else this.showCharsTab()
|
else this.showCharsTab()
|
||||||
|
const closeButton = L.DomUtil.createButton(
|
||||||
|
'button action-button',
|
||||||
|
this.footer,
|
||||||
|
L._('Close'),
|
||||||
|
function (e) {
|
||||||
|
this.body.innerHTML = ''
|
||||||
|
this.tabs.innerHTML = ''
|
||||||
|
this.footer.innerHTML = ''
|
||||||
|
if (this.isDefault()) this.undefine(e)
|
||||||
|
else this.udpatePreview()
|
||||||
|
},
|
||||||
|
this
|
||||||
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
buildTabs: function () {
|
buildTabs: function () {
|
||||||
const symbol = L.DomUtil.add(
|
const symbol = L.DomUtil.add(
|
||||||
'button',
|
'button',
|
||||||
'flat tab-symbols',
|
'flat tab-symbols',
|
||||||
this.tabsContainer,
|
this.tabs,
|
||||||
L._('Symbol')
|
L._('Symbol')
|
||||||
),
|
),
|
||||||
char = L.DomUtil.add(
|
char = L.DomUtil.add(
|
||||||
'button',
|
'button',
|
||||||
'flat tab-chars',
|
'flat tab-chars',
|
||||||
this.tabsContainer,
|
this.tabs,
|
||||||
L._('Emoji & Character')
|
L._('Emoji & Character')
|
||||||
)
|
)
|
||||||
url = L.DomUtil.add('button', 'flat tab-url', this.tabsContainer, L._('URL'))
|
url = L.DomUtil.add('button', 'flat tab-url', this.tabs, L._('URL'))
|
||||||
L.DomEvent.on(symbol, 'click', L.DomEvent.stop).on(
|
L.DomEvent.on(symbol, 'click', L.DomEvent.stop).on(
|
||||||
symbol,
|
symbol,
|
||||||
'click',
|
'click',
|
||||||
|
@ -572,31 +584,40 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
||||||
L.DomEvent.on(url, 'click', L.DomEvent.stop).on(url, 'click', this.showURLTab, this)
|
L.DomEvent.on(url, 'click', L.DomEvent.stop).on(url, 'click', this.showURLTab, this)
|
||||||
},
|
},
|
||||||
|
|
||||||
highlightTab: function (name) {
|
openTab: function (name) {
|
||||||
const els = this.tabsContainer.querySelectorAll('button')
|
const els = this.tabs.querySelectorAll('button')
|
||||||
for (let el of els) {
|
for (let el of els) {
|
||||||
L.DomUtil.removeClass(el, 'on')
|
L.DomUtil.removeClass(el, 'on')
|
||||||
}
|
}
|
||||||
let el = this.tabsContainer.querySelector(`.tab-${name}`)
|
let el = this.tabs.querySelector(`.tab-${name}`)
|
||||||
L.DomUtil.addClass(el, 'on')
|
L.DomUtil.addClass(el, 'on')
|
||||||
|
this.body.innerHTML = ''
|
||||||
},
|
},
|
||||||
|
|
||||||
isUrl: function () {
|
isPath: function () {
|
||||||
return this.value() && this.value().indexOf('/') !== -1
|
const value = this.value()
|
||||||
|
return value && value.length && value.startsWith('/')
|
||||||
|
},
|
||||||
|
|
||||||
|
isRemoteUrl: function () {
|
||||||
|
const value = this.value()
|
||||||
|
return value && value.length && value.startsWith('http')
|
||||||
|
},
|
||||||
|
|
||||||
|
isImg: function () {
|
||||||
|
return this.isPath() || this.isRemoteUrl()
|
||||||
},
|
},
|
||||||
|
|
||||||
udpatePreview: function () {
|
udpatePreview: function () {
|
||||||
if (this.isDefault()) {
|
this.buttons.innerHTML = ''
|
||||||
this.buttonsContainer.innerHTML = ''
|
if (this.isDefault()) return
|
||||||
return
|
|
||||||
}
|
|
||||||
if (!L.Util.hasVar(this.value())) {
|
if (!L.Util.hasVar(this.value())) {
|
||||||
// Do not try to render URL with variables
|
// Do not try to render URL with variables
|
||||||
if (this.isUrl()) {
|
if (this.isImg()) {
|
||||||
const img = L.DomUtil.create(
|
const img = L.DomUtil.create(
|
||||||
'img',
|
'img',
|
||||||
'',
|
'',
|
||||||
L.DomUtil.create('div', 'umap-pictogram-choice', this.buttonsContainer)
|
L.DomUtil.create('div', 'umap-pictogram-choice', this.buttons)
|
||||||
)
|
)
|
||||||
img.src = this.value()
|
img.src = this.value()
|
||||||
L.DomEvent.on(img, 'click', this.showSymbolsTab, this)
|
L.DomEvent.on(img, 'click', this.showSymbolsTab, this)
|
||||||
|
@ -604,7 +625,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
||||||
const el = L.DomUtil.create(
|
const el = L.DomUtil.create(
|
||||||
'span',
|
'span',
|
||||||
'',
|
'',
|
||||||
L.DomUtil.create('div', 'umap-pictogram-choice', this.buttonsContainer)
|
L.DomUtil.create('div', 'umap-pictogram-choice', this.buttons)
|
||||||
)
|
)
|
||||||
el.textContent = this.value()
|
el.textContent = this.value()
|
||||||
L.DomEvent.on(el, 'click', this.showSymbolsTab, this)
|
L.DomEvent.on(el, 'click', this.showSymbolsTab, this)
|
||||||
|
@ -612,7 +633,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
||||||
}
|
}
|
||||||
this.button = L.DomUtil.createButton(
|
this.button = L.DomUtil.createButton(
|
||||||
'button action-button',
|
'button action-button',
|
||||||
this.buttonsContainer,
|
this.buttons,
|
||||||
this.value() ? L._('Change') : L._('Add'),
|
this.value() ? L._('Change') : L._('Add'),
|
||||||
this.onDefine,
|
this.onDefine,
|
||||||
this
|
this
|
||||||
|
@ -638,7 +659,7 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
||||||
function (e) {
|
function (e) {
|
||||||
this.input.value = value
|
this.input.value = value
|
||||||
this.sync()
|
this.sync()
|
||||||
this.unselectAll(this.gridContainer)
|
this.unselectAll(this.grid)
|
||||||
L.DomUtil.addClass(container, 'selected')
|
L.DomUtil.addClass(container, 'selected')
|
||||||
},
|
},
|
||||||
this
|
this
|
||||||
|
@ -648,9 +669,9 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
||||||
|
|
||||||
clear: function () {
|
clear: function () {
|
||||||
this.input.value = ''
|
this.input.value = ''
|
||||||
this.unselectAll(this.pictogramsContainer)
|
this.unselectAll(this.body)
|
||||||
this.sync()
|
this.sync()
|
||||||
this.pictogramsContainer.innerHTML = ''
|
this.body.innerHTML = ''
|
||||||
this.udpatePreview()
|
this.udpatePreview()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -662,11 +683,11 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
||||||
for (let item of items) {
|
for (let item of items) {
|
||||||
status = this.addIconPreview(item, grid) || status
|
status = this.addIconPreview(item, grid) || status
|
||||||
}
|
}
|
||||||
if (status) this.gridContainer.appendChild(parent)
|
if (status) this.grid.appendChild(parent)
|
||||||
},
|
},
|
||||||
|
|
||||||
buildSymbolsList: function () {
|
buildSymbolsList: function () {
|
||||||
this.gridContainer.innerHTML = ''
|
this.grid.innerHTML = ''
|
||||||
const categories = {}
|
const categories = {}
|
||||||
let category
|
let category
|
||||||
for (const props of this.pictogram_list) {
|
for (const props of this.pictogram_list) {
|
||||||
|
@ -686,37 +707,13 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
||||||
return !this.value() || this.value() === this.obj.getMap().options.default_iconUrl
|
return !this.value() || this.value() === this.obj.getMap().options.default_iconUrl
|
||||||
},
|
},
|
||||||
|
|
||||||
showCharsTab: function () {
|
|
||||||
// Do not show default value here, as it's not a character
|
|
||||||
// and it has not been explicitely chosen by the user.
|
|
||||||
this.highlightTab('chars')
|
|
||||||
if (this.isDefault()) this.input.value = ''
|
|
||||||
this.input.type = 'text'
|
|
||||||
this.input.placeholder = L._('Type char or paste emoji')
|
|
||||||
this.pictogramsContainer.innerHTML = ''
|
|
||||||
},
|
|
||||||
|
|
||||||
showSymbolsTab: function () {
|
showSymbolsTab: function () {
|
||||||
this.highlightTab('symbols')
|
this.openTab('symbols')
|
||||||
this.input.type = 'hidden'
|
this.searchInput = L.DomUtil.create('input', '', this.body)
|
||||||
this.buttonsContainer.innerHTML = ''
|
|
||||||
this.searchInput = L.DomUtil.create('input', '', this.pictogramsContainer)
|
|
||||||
this.searchInput.type = 'search'
|
this.searchInput.type = 'search'
|
||||||
this.searchInput.placeholder = L._('Search')
|
this.searchInput.placeholder = L._('Search')
|
||||||
this.gridContainer = L.DomUtil.create('div', '', this.pictogramsContainer)
|
this.grid = L.DomUtil.create('div', '', this.body)
|
||||||
L.DomEvent.on(this.searchInput, 'input', this.buildSymbolsList, this)
|
L.DomEvent.on(this.searchInput, 'input', this.buildSymbolsList, this)
|
||||||
const closeButton = L.DomUtil.createButton(
|
|
||||||
'button action-button',
|
|
||||||
this.pictogramsContainer,
|
|
||||||
L._('Close'),
|
|
||||||
function (e) {
|
|
||||||
this.pictogramsContainer.innerHTML = ''
|
|
||||||
this.tabsContainer.innerHTML = ''
|
|
||||||
if (this.isDefault()) this.undefine(e)
|
|
||||||
else this.udpatePreview()
|
|
||||||
},
|
|
||||||
this
|
|
||||||
)
|
|
||||||
if (this.pictogram_list) {
|
if (this.pictogram_list) {
|
||||||
this.buildSymbolsList()
|
this.buildSymbolsList()
|
||||||
} else {
|
} else {
|
||||||
|
@ -730,11 +727,34 @@ L.FormBuilder.IconUrl = L.FormBuilder.BlurInput.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showCharsTab: function () {
|
||||||
|
this.openTab('chars')
|
||||||
|
const value = !this.isImg() ? this.value() : null
|
||||||
|
const input = this.buildInput(this.body, value)
|
||||||
|
input.placeholder = L._('Type char or paste emoji')
|
||||||
|
input.type = 'text'
|
||||||
|
},
|
||||||
|
|
||||||
showURLTab: function () {
|
showURLTab: function () {
|
||||||
this.highlightTab('url')
|
this.openTab('url')
|
||||||
this.input.type = 'url'
|
const value = this.isRemoteUrl() ? this.value() : null
|
||||||
this.input.placeholder = L._('Add URL')
|
const input = this.buildInput(this.body, value)
|
||||||
this.pictogramsContainer.innerHTML = ''
|
input.placeholder = L._('Add image URL')
|
||||||
|
input.type = 'url'
|
||||||
|
},
|
||||||
|
|
||||||
|
buildInput: function (parent, value) {
|
||||||
|
const input = L.DomUtil.create('input', 'blur', parent)
|
||||||
|
const button = L.DomUtil.create('span', 'button blur-button', parent)
|
||||||
|
if (value) input.value = value
|
||||||
|
L.DomEvent.on(input, 'blur', () => {
|
||||||
|
// Do not clear this.input when focus-blur
|
||||||
|
// empty input
|
||||||
|
if (input.value === value) return
|
||||||
|
this.input.value = input.value
|
||||||
|
this.sync()
|
||||||
|
})
|
||||||
|
return input
|
||||||
},
|
},
|
||||||
|
|
||||||
unselectAll: function (container) {
|
unselectAll: function (container) {
|
||||||
|
|
|
@ -59,7 +59,7 @@ def test_can_change_picto_at_map_level(map, live_server, page, pictos):
|
||||||
define.click()
|
define.click()
|
||||||
symbols = page.locator(".umap-pictogram-choice")
|
symbols = page.locator(".umap-pictogram-choice")
|
||||||
expect(symbols).to_have_count(2)
|
expect(symbols).to_have_count(2)
|
||||||
search = page.locator(".umap-pictogram-list input")
|
search = page.locator(".umap-pictogram-body input")
|
||||||
search.type("star")
|
search.type("star")
|
||||||
expect(symbols).to_have_count(1)
|
expect(symbols).to_have_count(1)
|
||||||
symbols.click()
|
symbols.click()
|
||||||
|
@ -93,7 +93,7 @@ def test_can_change_picto_at_datalayer_level(map, live_server, page, pictos):
|
||||||
define.click()
|
define.click()
|
||||||
symbols = page.locator(".umap-pictogram-choice")
|
symbols = page.locator(".umap-pictogram-choice")
|
||||||
expect(symbols).to_have_count(2)
|
expect(symbols).to_have_count(2)
|
||||||
search = page.locator(".umap-pictogram-list input")
|
search = page.locator(".umap-pictogram-body input")
|
||||||
search.type("circle")
|
search.type("circle")
|
||||||
expect(symbols).to_have_count(1)
|
expect(symbols).to_have_count(1)
|
||||||
symbols.click()
|
symbols.click()
|
||||||
|
@ -127,7 +127,7 @@ def test_can_change_picto_at_marker_level(map, live_server, page, pictos):
|
||||||
define.click()
|
define.click()
|
||||||
symbols = page.locator(".umap-pictogram-choice")
|
symbols = page.locator(".umap-pictogram-choice")
|
||||||
expect(symbols).to_have_count(2)
|
expect(symbols).to_have_count(2)
|
||||||
search = page.locator(".umap-pictogram-list input")
|
search = page.locator(".umap-pictogram-body input")
|
||||||
search.type("circle")
|
search.type("circle")
|
||||||
expect(symbols).to_have_count(1)
|
expect(symbols).to_have_count(1)
|
||||||
symbols.click()
|
symbols.click()
|
||||||
|
@ -156,7 +156,7 @@ def test_can_use_remote_url_as_picto(map, live_server, page, pictos):
|
||||||
expect(define).to_be_visible()
|
expect(define).to_be_visible()
|
||||||
define.click()
|
define.click()
|
||||||
url_tab = page.get_by_role("button", name="URL")
|
url_tab = page.get_by_role("button", name="URL")
|
||||||
input_el = page.locator("input[name='iconUrl']")
|
input_el = page.get_by_placeholder("Add image URL")
|
||||||
expect(input_el).to_be_hidden()
|
expect(input_el).to_be_hidden()
|
||||||
expect(url_tab).to_be_visible()
|
expect(url_tab).to_be_visible()
|
||||||
url_tab.click()
|
url_tab.click()
|
||||||
|
@ -165,7 +165,7 @@ def test_can_use_remote_url_as_picto(map, live_server, page, pictos):
|
||||||
input_el.blur()
|
input_el.blur()
|
||||||
expect(marker).to_have_attribute("src", "https://foo.bar/img.jpg")
|
expect(marker).to_have_attribute("src", "https://foo.bar/img.jpg")
|
||||||
# Now close and reopen the form, it should still be the URL tab
|
# Now close and reopen the form, it should still be the URL tab
|
||||||
close = page.locator("#umap-ui-container").get_by_text("Close")
|
close = page.locator("#umap-ui-container").get_by_title("Close")
|
||||||
expect(close).to_be_visible()
|
expect(close).to_be_visible()
|
||||||
close.click()
|
close.click()
|
||||||
edit_settings.click()
|
edit_settings.click()
|
||||||
|
@ -195,7 +195,7 @@ def test_can_use_char_as_picto(map, live_server, page, pictos):
|
||||||
define = page.locator(".umap-field-iconUrl .define")
|
define = page.locator(".umap-field-iconUrl .define")
|
||||||
define.click()
|
define.click()
|
||||||
url_tab = page.get_by_role("button", name="Emoji & Character")
|
url_tab = page.get_by_role("button", name="Emoji & Character")
|
||||||
input_el = page.locator("input[name='iconUrl']")
|
input_el = page.get_by_placeholder("Type char or paste emoji")
|
||||||
expect(input_el).to_be_hidden()
|
expect(input_el).to_be_hidden()
|
||||||
expect(url_tab).to_be_visible()
|
expect(url_tab).to_be_visible()
|
||||||
url_tab.click()
|
url_tab.click()
|
||||||
|
@ -205,7 +205,7 @@ def test_can_use_char_as_picto(map, live_server, page, pictos):
|
||||||
expect(marker).to_have_count(1)
|
expect(marker).to_have_count(1)
|
||||||
expect(marker).to_have_text("♩")
|
expect(marker).to_have_text("♩")
|
||||||
# Now close and reopen the form, it should still be the URL tab
|
# Now close and reopen the form, it should still be the URL tab
|
||||||
close = page.locator("#umap-ui-container").get_by_text("Close")
|
close = page.locator("#umap-ui-container").get_by_title("Close")
|
||||||
expect(close).to_be_visible()
|
expect(close).to_be_visible()
|
||||||
close.click()
|
close.click()
|
||||||
edit_settings.click()
|
edit_settings.click()
|
||||||
|
|
Loading…
Reference in a new issue