Merge pull request #1846 from umap-project/autocomplete-module
chore: move autocomplete to modules/
This commit is contained in:
commit
0c9c79195a
5 changed files with 314 additions and 344 deletions
309
umap/static/umap/js/modules/autocomplete.js
Normal file
309
umap/static/umap/js/modules/autocomplete.js
Normal file
|
@ -0,0 +1,309 @@
|
||||||
|
import { DomUtil, DomEvent, setOptions } from '../../vendors/leaflet/leaflet-src.esm.js'
|
||||||
|
import { translate } from './i18n.js'
|
||||||
|
import { ServerRequest } from './request.js'
|
||||||
|
import Alert from './ui/alert.js'
|
||||||
|
|
||||||
|
export class BaseAutocomplete {
|
||||||
|
constructor(el, options) {
|
||||||
|
this.el = el
|
||||||
|
this.options = {
|
||||||
|
placeholder: translate('Start typing...'),
|
||||||
|
emptyMessage: translate('No result'),
|
||||||
|
allowFree: true,
|
||||||
|
minChar: 2,
|
||||||
|
maxResults: 5,
|
||||||
|
}
|
||||||
|
this.cache = ''
|
||||||
|
this.results = []
|
||||||
|
this._current = null
|
||||||
|
setOptions(this, options)
|
||||||
|
this.createInput()
|
||||||
|
this.createContainer()
|
||||||
|
this.selectedContainer = this.initSelectedContainer()
|
||||||
|
}
|
||||||
|
|
||||||
|
get current() {
|
||||||
|
return this._current
|
||||||
|
}
|
||||||
|
|
||||||
|
set current(index) {
|
||||||
|
if (typeof index === 'object') {
|
||||||
|
index = this.resultToIndex(index)
|
||||||
|
}
|
||||||
|
this._current = index
|
||||||
|
}
|
||||||
|
|
||||||
|
createInput() {
|
||||||
|
this.input = DomUtil.element({
|
||||||
|
tagName: 'input',
|
||||||
|
type: 'text',
|
||||||
|
parent: this.el,
|
||||||
|
placeholder: this.options.placeholder,
|
||||||
|
autocomplete: 'off',
|
||||||
|
className: this.options.className,
|
||||||
|
})
|
||||||
|
DomEvent.on(this.input, 'keydown', this.onKeyDown, this)
|
||||||
|
DomEvent.on(this.input, 'keyup', this.onKeyUp, this)
|
||||||
|
DomEvent.on(this.input, 'blur', this.onBlur, this)
|
||||||
|
}
|
||||||
|
|
||||||
|
createContainer() {
|
||||||
|
this.container = DomUtil.element({
|
||||||
|
tagName: 'ul',
|
||||||
|
parent: document.body,
|
||||||
|
className: 'umap-autocomplete',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
resizeContainer() {
|
||||||
|
const l = this.getLeft(this.input)
|
||||||
|
const t = this.getTop(this.input) + this.input.offsetHeight
|
||||||
|
this.container.style.left = `${l}px`
|
||||||
|
this.container.style.top = `${t}px`
|
||||||
|
const width = this.options.width ? this.options.width : this.input.offsetWidth - 2
|
||||||
|
this.container.style.width = `${width}px`
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyDown(e) {
|
||||||
|
switch (e.key) {
|
||||||
|
case 'Tab':
|
||||||
|
if (this.current !== null) this.setChoice()
|
||||||
|
DomEvent.stop(e)
|
||||||
|
break
|
||||||
|
case 'Enter':
|
||||||
|
DomEvent.stop(e)
|
||||||
|
this.setChoice()
|
||||||
|
break
|
||||||
|
case 'Escape':
|
||||||
|
DomEvent.stop(e)
|
||||||
|
this.hide()
|
||||||
|
break
|
||||||
|
case 'ArrowDown':
|
||||||
|
if (this.results.length > 0) {
|
||||||
|
if (this.current !== null && this.current < this.results.length - 1) {
|
||||||
|
// what if one result?
|
||||||
|
this.current++
|
||||||
|
this.highlight()
|
||||||
|
} else if (this.current === null) {
|
||||||
|
this.current = 0
|
||||||
|
this.highlight()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'ArrowUp':
|
||||||
|
if (this.current !== null) {
|
||||||
|
DomEvent.stop(e)
|
||||||
|
}
|
||||||
|
if (this.results.length > 0) {
|
||||||
|
if (this.current > 0) {
|
||||||
|
this.current--
|
||||||
|
this.highlight()
|
||||||
|
} else if (this.current === 0) {
|
||||||
|
this.current = null
|
||||||
|
this.highlight()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyUp(e) {
|
||||||
|
const special = [
|
||||||
|
'Tab',
|
||||||
|
'Enter',
|
||||||
|
'ArrowLeft',
|
||||||
|
'ArrowRight',
|
||||||
|
'ArrowDown',
|
||||||
|
'ArrowUp',
|
||||||
|
'Meta',
|
||||||
|
'Shift',
|
||||||
|
'Alt',
|
||||||
|
'Control',
|
||||||
|
]
|
||||||
|
if (!special.includes(e.key)) {
|
||||||
|
this.search()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onBlur() {
|
||||||
|
setTimeout(() => this.hide(), 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.results = []
|
||||||
|
this.current = null
|
||||||
|
this.cache = ''
|
||||||
|
this.container.innerHTML = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() {
|
||||||
|
this.clear()
|
||||||
|
this.container.style.display = 'none'
|
||||||
|
this.input.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
setChoice(choice) {
|
||||||
|
choice = choice || this.results[this.current]
|
||||||
|
if (choice) {
|
||||||
|
this.input.value = choice.item.label
|
||||||
|
this.options.on_select(choice)
|
||||||
|
this.displaySelected(choice)
|
||||||
|
this.hide()
|
||||||
|
if (this.options.callback) {
|
||||||
|
this.options.callback.bind(this)(choice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createResult(item) {
|
||||||
|
const el = DomUtil.element({
|
||||||
|
tagName: 'li',
|
||||||
|
parent: this.container,
|
||||||
|
textContent: item.label,
|
||||||
|
})
|
||||||
|
const result = {
|
||||||
|
item: item,
|
||||||
|
el: el,
|
||||||
|
}
|
||||||
|
DomEvent.on(el, 'mouseover', () => {
|
||||||
|
this.current = result
|
||||||
|
this.highlight()
|
||||||
|
})
|
||||||
|
DomEvent.on(el, 'mousedown', () => this.setChoice())
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
resultToIndex(result) {
|
||||||
|
return this.results.findIndex((item) => item.item.value === result.item.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
handleResults(data) {
|
||||||
|
this.clear()
|
||||||
|
this.container.style.display = 'block'
|
||||||
|
this.resizeContainer()
|
||||||
|
data.forEach((item) => {
|
||||||
|
this.results.push(this.createResult(item))
|
||||||
|
})
|
||||||
|
this.current = 0
|
||||||
|
this.highlight()
|
||||||
|
//TODO manage no results
|
||||||
|
}
|
||||||
|
|
||||||
|
highlight() {
|
||||||
|
this.results.forEach((result, index) => {
|
||||||
|
if (index === this.current) DomUtil.addClass(result.el, 'on')
|
||||||
|
else DomUtil.removeClass(result.el, 'on')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getLeft(el) {
|
||||||
|
let tmp = el.offsetLeft
|
||||||
|
el = el.offsetParent
|
||||||
|
while (el) {
|
||||||
|
tmp += el.offsetLeft
|
||||||
|
el = el.offsetParent
|
||||||
|
}
|
||||||
|
return tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
getTop(el) {
|
||||||
|
let tmp = el.offsetTop
|
||||||
|
el = el.offsetParent
|
||||||
|
while (el) {
|
||||||
|
tmp += el.offsetTop
|
||||||
|
el = el.offsetParent
|
||||||
|
}
|
||||||
|
return tmp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BaseAjax extends BaseAutocomplete {
|
||||||
|
constructor(el, options) {
|
||||||
|
super(el, options)
|
||||||
|
const alert = new Alert(document.querySelector('header'))
|
||||||
|
this.server = new ServerRequest(alert)
|
||||||
|
}
|
||||||
|
optionToResult(option) {
|
||||||
|
return {
|
||||||
|
value: option.value,
|
||||||
|
label: option.innerHTML,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async search() {
|
||||||
|
let val = this.input.value
|
||||||
|
if (val.length < this.options.minChar) {
|
||||||
|
this.clear()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (val === this.cache) return
|
||||||
|
else this.cache = val
|
||||||
|
val = val.toLowerCase()
|
||||||
|
const [{ data }, response] = await this.server.get(
|
||||||
|
`/agnocomplete/AutocompleteUser/?q=${encodeURIComponent(val)}`
|
||||||
|
)
|
||||||
|
this.handleResults(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AjaxAutocompleteMultiple extends BaseAjax {
|
||||||
|
initSelectedContainer() {
|
||||||
|
return DomUtil.after(
|
||||||
|
this.input,
|
||||||
|
DomUtil.element({ tagName: 'ul', className: 'umap-multiresult' })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
displaySelected(result) {
|
||||||
|
const result_el = DomUtil.element({
|
||||||
|
tagName: 'li',
|
||||||
|
parent: this.selectedContainer,
|
||||||
|
})
|
||||||
|
result_el.textContent = result.item.label
|
||||||
|
const close = DomUtil.element({
|
||||||
|
tagName: 'span',
|
||||||
|
parent: result_el,
|
||||||
|
className: 'close',
|
||||||
|
textContent: '×',
|
||||||
|
})
|
||||||
|
DomEvent.on(close, 'click', () => {
|
||||||
|
this.selectedContainer.removeChild(result_el)
|
||||||
|
this.options.on_unselect(result)
|
||||||
|
})
|
||||||
|
this.hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AjaxAutocomplete extends BaseAjax {
|
||||||
|
initSelectedContainer() {
|
||||||
|
return DomUtil.after(
|
||||||
|
this.input,
|
||||||
|
DomUtil.element({ tagName: 'div', className: 'umap-singleresult' })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
displaySelected(result) {
|
||||||
|
const result_el = DomUtil.element({
|
||||||
|
tagName: 'div',
|
||||||
|
parent: this.selectedContainer,
|
||||||
|
})
|
||||||
|
result_el.textContent = result.item.label
|
||||||
|
const close = DomUtil.element({
|
||||||
|
tagName: 'span',
|
||||||
|
parent: result_el,
|
||||||
|
className: 'close',
|
||||||
|
textContent: '×',
|
||||||
|
})
|
||||||
|
this.input.style.display = 'none'
|
||||||
|
DomEvent.on(
|
||||||
|
close,
|
||||||
|
'click',
|
||||||
|
function () {
|
||||||
|
this.selectedContainer.innerHTML = ''
|
||||||
|
this.input.style.display = 'block'
|
||||||
|
},
|
||||||
|
this
|
||||||
|
)
|
||||||
|
this.hide()
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import Tooltip from './ui/tooltip.js'
|
||||||
import * as Utils from './utils.js'
|
import * as Utils from './utils.js'
|
||||||
import { SCHEMA } from './schema.js'
|
import { SCHEMA } from './schema.js'
|
||||||
import { Request, ServerRequest, RequestError, HTTPError, NOKError } from './request.js'
|
import { Request, ServerRequest, RequestError, HTTPError, NOKError } from './request.js'
|
||||||
|
import { AjaxAutocomplete, AjaxAutocompleteMultiple } from './autocomplete.js'
|
||||||
import Orderable from './orderable.js'
|
import Orderable from './orderable.js'
|
||||||
|
|
||||||
// Import modules and export them to the global scope.
|
// Import modules and export them to the global scope.
|
||||||
|
@ -33,4 +34,6 @@ window.U = {
|
||||||
SCHEMA,
|
SCHEMA,
|
||||||
Orderable,
|
Orderable,
|
||||||
Caption,
|
Caption,
|
||||||
|
AjaxAutocomplete,
|
||||||
|
AjaxAutocompleteMultiple,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,341 +0,0 @@
|
||||||
U.AutoComplete = L.Class.extend({
|
|
||||||
options: {
|
|
||||||
placeholder: 'Start typing...',
|
|
||||||
emptyMessage: 'No result',
|
|
||||||
allowFree: true,
|
|
||||||
minChar: 2,
|
|
||||||
maxResults: 5,
|
|
||||||
},
|
|
||||||
|
|
||||||
CACHE: '',
|
|
||||||
RESULTS: [],
|
|
||||||
|
|
||||||
initialize: function (el, options) {
|
|
||||||
this.el = el
|
|
||||||
const alert = new U.Alert(document.querySelector('header'))
|
|
||||||
this.server = new U.ServerRequest(alert)
|
|
||||||
L.setOptions(this, options)
|
|
||||||
let CURRENT = null
|
|
||||||
try {
|
|
||||||
Object.defineProperty(this, 'CURRENT', {
|
|
||||||
get: function () {
|
|
||||||
return CURRENT
|
|
||||||
},
|
|
||||||
set: function (index) {
|
|
||||||
if (typeof index === 'object') {
|
|
||||||
index = this.resultToIndex(index)
|
|
||||||
}
|
|
||||||
CURRENT = index
|
|
||||||
},
|
|
||||||
})
|
|
||||||
} catch (e) {
|
|
||||||
// Hello IE8
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
},
|
|
||||||
|
|
||||||
createInput: function () {
|
|
||||||
this.input = L.DomUtil.element({
|
|
||||||
tagName: 'input',
|
|
||||||
type: 'text',
|
|
||||||
parent: this.el,
|
|
||||||
placeholder: this.options.placeholder,
|
|
||||||
autocomplete: 'off',
|
|
||||||
className: this.options.className,
|
|
||||||
})
|
|
||||||
L.DomEvent.on(this.input, 'keydown', this.onKeyDown, this)
|
|
||||||
L.DomEvent.on(this.input, 'keyup', this.onKeyUp, this)
|
|
||||||
L.DomEvent.on(this.input, 'blur', this.onBlur, this)
|
|
||||||
},
|
|
||||||
|
|
||||||
createContainer: function () {
|
|
||||||
this.container = L.DomUtil.element({
|
|
||||||
tagName: 'ul',
|
|
||||||
parent: document.body,
|
|
||||||
className: 'umap-autocomplete',
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
resizeContainer: function () {
|
|
||||||
const l = this.getLeft(this.input)
|
|
||||||
const t = this.getTop(this.input) + this.input.offsetHeight
|
|
||||||
this.container.style.left = `${l}px`
|
|
||||||
this.container.style.top = `${t}px`
|
|
||||||
const width = this.options.width ? this.options.width : this.input.offsetWidth - 2
|
|
||||||
this.container.style.width = `${width}px`
|
|
||||||
},
|
|
||||||
|
|
||||||
onKeyDown: function (e) {
|
|
||||||
switch (e.keyCode) {
|
|
||||||
case U.Keys.TAB:
|
|
||||||
if (this.CURRENT !== null) this.setChoice()
|
|
||||||
L.DomEvent.stop(e)
|
|
||||||
break
|
|
||||||
case U.Keys.ENTER:
|
|
||||||
L.DomEvent.stop(e)
|
|
||||||
this.setChoice()
|
|
||||||
break
|
|
||||||
case U.Keys.ESC:
|
|
||||||
L.DomEvent.stop(e)
|
|
||||||
this.hide()
|
|
||||||
break
|
|
||||||
case U.Keys.DOWN:
|
|
||||||
if (this.RESULTS.length > 0) {
|
|
||||||
if (this.CURRENT !== null && this.CURRENT < this.RESULTS.length - 1) {
|
|
||||||
// what if one result?
|
|
||||||
this.CURRENT++
|
|
||||||
this.highlight()
|
|
||||||
} else if (this.CURRENT === null) {
|
|
||||||
this.CURRENT = 0
|
|
||||||
this.highlight()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case U.Keys.UP:
|
|
||||||
if (this.CURRENT !== null) {
|
|
||||||
L.DomEvent.stop(e)
|
|
||||||
}
|
|
||||||
if (this.RESULTS.length > 0) {
|
|
||||||
if (this.CURRENT > 0) {
|
|
||||||
this.CURRENT--
|
|
||||||
this.highlight()
|
|
||||||
} else if (this.CURRENT === 0) {
|
|
||||||
this.CURRENT = null
|
|
||||||
this.highlight()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onKeyUp: function (e) {
|
|
||||||
const special = [
|
|
||||||
U.Keys.TAB,
|
|
||||||
U.Keys.ENTER,
|
|
||||||
U.Keys.LEFT,
|
|
||||||
U.Keys.RIGHT,
|
|
||||||
U.Keys.DOWN,
|
|
||||||
U.Keys.UP,
|
|
||||||
U.Keys.APPLE,
|
|
||||||
U.Keys.SHIFT,
|
|
||||||
U.Keys.ALT,
|
|
||||||
U.Keys.CTRL,
|
|
||||||
]
|
|
||||||
if (special.indexOf(e.keyCode) === -1) {
|
|
||||||
this.search()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onBlur: function () {
|
|
||||||
setTimeout(() => this.hide(), 100)
|
|
||||||
},
|
|
||||||
|
|
||||||
clear: function () {
|
|
||||||
this.RESULTS = []
|
|
||||||
this.CURRENT = null
|
|
||||||
this.CACHE = ''
|
|
||||||
this.container.innerHTML = ''
|
|
||||||
},
|
|
||||||
|
|
||||||
hide: function () {
|
|
||||||
this.clear()
|
|
||||||
this.container.style.display = 'none'
|
|
||||||
this.input.value = ''
|
|
||||||
},
|
|
||||||
|
|
||||||
setChoice: function (choice) {
|
|
||||||
choice = choice || this.RESULTS[this.CURRENT]
|
|
||||||
if (choice) {
|
|
||||||
this.input.value = choice.item.label
|
|
||||||
this.options.on_select(choice)
|
|
||||||
this.displaySelected(choice)
|
|
||||||
this.hide()
|
|
||||||
if (this.options.callback) {
|
|
||||||
L.Util.bind(this.options.callback, this)(choice)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
search: async function () {
|
|
||||||
let val = this.input.value
|
|
||||||
if (val.length < this.options.minChar) {
|
|
||||||
this.clear()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (`${val}` === `${this.CACHE}`) return
|
|
||||||
else this.CACHE = val
|
|
||||||
val = val.toLowerCase()
|
|
||||||
const [{ data }, response] = await this.server.get(
|
|
||||||
`/agnocomplete/AutocompleteUser/?q=${encodeURIComponent(val)}`
|
|
||||||
)
|
|
||||||
this.handleResults(data)
|
|
||||||
},
|
|
||||||
|
|
||||||
createResult: function (item) {
|
|
||||||
const el = L.DomUtil.element({
|
|
||||||
tagName: 'li',
|
|
||||||
parent: this.container,
|
|
||||||
textContent: item.label,
|
|
||||||
})
|
|
||||||
const result = {
|
|
||||||
item: item,
|
|
||||||
el: el,
|
|
||||||
}
|
|
||||||
L.DomEvent.on(
|
|
||||||
el,
|
|
||||||
'mouseover',
|
|
||||||
function () {
|
|
||||||
this.CURRENT = result
|
|
||||||
this.highlight()
|
|
||||||
},
|
|
||||||
this
|
|
||||||
)
|
|
||||||
L.DomEvent.on(
|
|
||||||
el,
|
|
||||||
'mousedown',
|
|
||||||
function () {
|
|
||||||
this.setChoice()
|
|
||||||
},
|
|
||||||
this
|
|
||||||
)
|
|
||||||
return result
|
|
||||||
},
|
|
||||||
|
|
||||||
resultToIndex: function (result) {
|
|
||||||
let out = null
|
|
||||||
this.forEach(this.RESULTS, (item, index) => {
|
|
||||||
if (item.item.value == result.item.value) {
|
|
||||||
out = index
|
|
||||||
return
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return out
|
|
||||||
},
|
|
||||||
|
|
||||||
handleResults: function (data) {
|
|
||||||
this.clear()
|
|
||||||
this.container.style.display = 'block'
|
|
||||||
this.resizeContainer()
|
|
||||||
this.forEach(data, (item) => {
|
|
||||||
this.RESULTS.push(this.createResult(item))
|
|
||||||
})
|
|
||||||
this.CURRENT = 0
|
|
||||||
this.highlight()
|
|
||||||
//TODO manage no results
|
|
||||||
},
|
|
||||||
|
|
||||||
highlight: function () {
|
|
||||||
this.forEach(this.RESULTS, (result, index) => {
|
|
||||||
if (index === this.CURRENT) L.DomUtil.addClass(result.el, 'on')
|
|
||||||
else L.DomUtil.removeClass(result.el, 'on')
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
getLeft: function (el) {
|
|
||||||
let tmp = el.offsetLeft
|
|
||||||
el = el.offsetParent
|
|
||||||
while (el) {
|
|
||||||
tmp += el.offsetLeft
|
|
||||||
el = el.offsetParent
|
|
||||||
}
|
|
||||||
return tmp
|
|
||||||
},
|
|
||||||
|
|
||||||
getTop: function (el) {
|
|
||||||
let tmp = el.offsetTop
|
|
||||||
el = el.offsetParent
|
|
||||||
while (el) {
|
|
||||||
tmp += el.offsetTop
|
|
||||||
el = el.offsetParent
|
|
||||||
}
|
|
||||||
return tmp
|
|
||||||
},
|
|
||||||
|
|
||||||
forEach: function (els, callback) {
|
|
||||||
Array.prototype.forEach.call(els, callback)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
U.AutoComplete.Ajax = U.AutoComplete.extend({
|
|
||||||
initialize: function (el, options) {
|
|
||||||
U.AutoComplete.prototype.initialize.call(this, el, options)
|
|
||||||
if (!this.el) return this
|
|
||||||
this.createInput()
|
|
||||||
this.createContainer()
|
|
||||||
this.selected_container = this.initSelectedContainer()
|
|
||||||
},
|
|
||||||
|
|
||||||
optionToResult: function (option) {
|
|
||||||
return {
|
|
||||||
value: option.value,
|
|
||||||
label: option.innerHTML,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
U.AutoComplete.Ajax.SelectMultiple = U.AutoComplete.Ajax.extend({
|
|
||||||
initSelectedContainer: function () {
|
|
||||||
return L.DomUtil.after(
|
|
||||||
this.input,
|
|
||||||
L.DomUtil.element({ tagName: 'ul', className: 'umap-multiresult' })
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
displaySelected: function (result) {
|
|
||||||
const result_el = L.DomUtil.element({
|
|
||||||
tagName: 'li',
|
|
||||||
parent: this.selected_container,
|
|
||||||
})
|
|
||||||
result_el.textContent = result.item.label
|
|
||||||
const close = L.DomUtil.element({
|
|
||||||
tagName: 'span',
|
|
||||||
parent: result_el,
|
|
||||||
className: 'close',
|
|
||||||
textContent: '×',
|
|
||||||
})
|
|
||||||
L.DomEvent.on(
|
|
||||||
close,
|
|
||||||
'click',
|
|
||||||
function () {
|
|
||||||
this.selected_container.removeChild(result_el)
|
|
||||||
this.options.on_unselect(result)
|
|
||||||
},
|
|
||||||
this
|
|
||||||
)
|
|
||||||
this.hide()
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
U.AutoComplete.Ajax.Select = U.AutoComplete.Ajax.extend({
|
|
||||||
initSelectedContainer: function () {
|
|
||||||
return L.DomUtil.after(
|
|
||||||
this.input,
|
|
||||||
L.DomUtil.element({ tagName: 'div', className: 'umap-singleresult' })
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
displaySelected: function (result) {
|
|
||||||
const result_el = L.DomUtil.element({
|
|
||||||
tagName: 'div',
|
|
||||||
parent: this.selected_container,
|
|
||||||
})
|
|
||||||
result_el.textContent = result.item.label
|
|
||||||
const close = L.DomUtil.element({
|
|
||||||
tagName: 'span',
|
|
||||||
parent: result_el,
|
|
||||||
className: 'close',
|
|
||||||
textContent: '×',
|
|
||||||
})
|
|
||||||
this.input.style.display = 'none'
|
|
||||||
L.DomEvent.on(
|
|
||||||
close,
|
|
||||||
'click',
|
|
||||||
function () {
|
|
||||||
this.selected_container.innerHTML = ''
|
|
||||||
this.input.style.display = 'block'
|
|
||||||
},
|
|
||||||
this
|
|
||||||
)
|
|
||||||
this.hide()
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -1067,7 +1067,7 @@ L.FormBuilder.ManageOwner = L.FormBuilder.Element.extend({
|
||||||
className: 'edit-owner',
|
className: 'edit-owner',
|
||||||
on_select: L.bind(this.onSelect, this),
|
on_select: L.bind(this.onSelect, this),
|
||||||
}
|
}
|
||||||
this.autocomplete = new U.AutoComplete.Ajax.Select(this.parentNode, options)
|
this.autocomplete = new U.AjaxAutocomplete(this.parentNode, options)
|
||||||
const owner = this.toHTML()
|
const owner = this.toHTML()
|
||||||
if (owner)
|
if (owner)
|
||||||
this.autocomplete.displaySelected({
|
this.autocomplete.displaySelected({
|
||||||
|
@ -1096,7 +1096,7 @@ L.FormBuilder.ManageEditors = L.FormBuilder.Element.extend({
|
||||||
on_select: L.bind(this.onSelect, this),
|
on_select: L.bind(this.onSelect, this),
|
||||||
on_unselect: L.bind(this.onUnselect, this),
|
on_unselect: L.bind(this.onUnselect, this),
|
||||||
}
|
}
|
||||||
this.autocomplete = new U.AutoComplete.Ajax.SelectMultiple(this.parentNode, options)
|
this.autocomplete = new U.AjaxAutocompleteMultiple(this.parentNode, options)
|
||||||
this._values = this.toHTML()
|
this._values = this.toHTML()
|
||||||
if (this._values)
|
if (this._values)
|
||||||
for (let i = 0; i < this._values.length; i++)
|
for (let i = 0; i < this._values.length; i++)
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
<script src="{% static 'umap/vendors/simple-statistics/simple-statistics.min.js' %}"
|
<script src="{% static 'umap/vendors/simple-statistics/simple-statistics.min.js' %}"
|
||||||
defer></script>
|
defer></script>
|
||||||
<script src="{% static 'umap/js/umap.core.js' %}" defer></script>
|
<script src="{% static 'umap/js/umap.core.js' %}" defer></script>
|
||||||
<script src="{% static 'umap/js/umap.autocomplete.js' %}" defer></script>
|
|
||||||
<script src="{% static 'umap/js/umap.popup.js' %}" defer></script>
|
<script src="{% static 'umap/js/umap.popup.js' %}" defer></script>
|
||||||
<script src="{% static 'umap/js/umap.forms.js' %}" defer></script>
|
<script src="{% static 'umap/js/umap.forms.js' %}" defer></script>
|
||||||
<script src="{% static 'umap/js/umap.icon.js' %}" defer></script>
|
<script src="{% static 'umap/js/umap.icon.js' %}" defer></script>
|
||||||
|
|
Loading…
Reference in a new issue