mirror of
https://github.com/umap-project/umap.git
synced 2025-04-29 11:52:38 +02:00
wip: make it simpler to create an autocomplete class
This commit is contained in:
parent
e51347e239
commit
5b914c1bd2
3 changed files with 106 additions and 89 deletions
|
@ -1,6 +1,11 @@
|
||||||
import { DomUtil, DomEvent, setOptions } from '../../vendors/leaflet/leaflet-src.esm.js'
|
import {
|
||||||
|
DomUtil,
|
||||||
|
DomEvent,
|
||||||
|
setOptions,
|
||||||
|
Util,
|
||||||
|
} from '../../vendors/leaflet/leaflet-src.esm.js'
|
||||||
import { translate } from './i18n.js'
|
import { translate } from './i18n.js'
|
||||||
import { ServerRequest } from './request.js'
|
import { Request, ServerRequest } from './request.js'
|
||||||
|
|
||||||
export class BaseAutocomplete {
|
export class BaseAutocomplete {
|
||||||
constructor(el, options) {
|
constructor(el, options) {
|
||||||
|
@ -216,11 +221,17 @@ export class BaseAutocomplete {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BaseAjax extends BaseAutocomplete {
|
export class BaseAjax extends BaseAutocomplete {
|
||||||
|
URL = '/foobar/?q={q}'
|
||||||
constructor(el, options) {
|
constructor(el, options) {
|
||||||
super(el, options)
|
super(el, options)
|
||||||
this.server = new ServerRequest()
|
this.initRequest()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initRequest() {
|
||||||
|
this.request = new Request()
|
||||||
|
}
|
||||||
|
|
||||||
optionToResult(option) {
|
optionToResult(option) {
|
||||||
return {
|
return {
|
||||||
value: option.value,
|
value: option.value,
|
||||||
|
@ -237,42 +248,32 @@ class BaseAjax extends BaseAutocomplete {
|
||||||
if (val === this.cache) return
|
if (val === this.cache) return
|
||||||
else this.cache = val
|
else this.cache = val
|
||||||
val = val.toLowerCase()
|
val = val.toLowerCase()
|
||||||
const [{ data }, response] = await this.server.get(
|
const url = Util.template(this.URL, {q: encodeURIComponent(val)})
|
||||||
`/agnocomplete/AutocompleteUser/?q=${encodeURIComponent(val)}`
|
this.handleResults(await this._search(url))
|
||||||
)
|
}
|
||||||
this.handleResults(data)
|
|
||||||
|
async _search(url) {
|
||||||
|
const response = await this.request.get(url)
|
||||||
|
if (response && response.ok) {
|
||||||
|
return await response.json()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AjaxAutocompleteMultiple extends BaseAjax {
|
class BaseServerAjax extends BaseAjax {
|
||||||
initSelectedContainer() {
|
URL = '/agnocomplete/AutocompleteUser/?q={q}'
|
||||||
return DomUtil.after(
|
initRequest() {
|
||||||
this.input,
|
this.server = new ServerRequest()
|
||||||
DomUtil.element({ tagName: 'ul', className: 'umap-multiresult' })
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
async _search(url) {
|
||||||
displaySelected(result) {
|
const [{ data }, response] = await this.server.get(url)
|
||||||
const result_el = DomUtil.element({
|
return data
|
||||||
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 {
|
export const SingleMixin = (Base) =>
|
||||||
|
class extends Base {
|
||||||
initSelectedContainer() {
|
initSelectedContainer() {
|
||||||
return DomUtil.after(
|
return DomUtil.after(
|
||||||
this.input,
|
this.input,
|
||||||
|
@ -305,3 +306,36 @@ export class AjaxAutocomplete extends BaseAjax {
|
||||||
this.hide()
|
this.hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const MultipleMixin = (Base) =>
|
||||||
|
class extends Base {
|
||||||
|
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 AjaxAutocompleteMultiple extends MultipleMixin(BaseServerAjax) {}
|
||||||
|
|
||||||
|
export class AjaxAutocomplete extends SingleMixin(BaseServerAjax) {}
|
||||||
|
|
|
@ -42,7 +42,11 @@ export default class Importer {
|
||||||
parent: this.container,
|
parent: this.container,
|
||||||
textContent: translate('Import from:'),
|
textContent: translate('Import from:'),
|
||||||
})
|
})
|
||||||
const plugins = L.DomUtil.element({tagName: 'div', className: 'umap-multiplechoice by2', parent: this.container})
|
const plugins = L.DomUtil.element({
|
||||||
|
tagName: 'div',
|
||||||
|
className: 'umap-multiplechoice by2',
|
||||||
|
parent: this.container,
|
||||||
|
})
|
||||||
for (const plugin of this.map.plugins) {
|
for (const plugin of this.map.plugins) {
|
||||||
const { name, callback } = plugin.addImporter()
|
const { name, callback } = plugin.addImporter()
|
||||||
L.DomUtil.createButton('flat', plugins, name, () => callback.bind(plugin)(this))
|
L.DomUtil.createButton('flat', plugins, name, () => callback.bind(plugin)(this))
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
import { DomUtil, DomEvent, stamp } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
import { DomUtil, DomEvent, stamp } from '../../../vendors/leaflet/leaflet-src.esm.js'
|
||||||
import { translate } from '../i18n.js'
|
import { translate } from '../i18n.js'
|
||||||
import { AjaxAutocomplete } from '../autocomplete.js'
|
import { BaseAjax, SingleMixin } from '../autocomplete.js'
|
||||||
import { Request } from '../request.js'
|
import { Request } from '../request.js'
|
||||||
import Alert from '../ui/alert.js'
|
import Alert from '../ui/alert.js'
|
||||||
import Dialog from '../ui/dialog.js'
|
import Dialog from '../ui/dialog.js'
|
||||||
|
|
||||||
class Autocomplete extends AjaxAutocomplete {
|
class Autocomplete extends SingleMixin(BaseAjax) {
|
||||||
constructor(request, el, options) {
|
URL = 'https://geodatamine.fr/boundaries/search?text={q}'
|
||||||
super(el, options)
|
|
||||||
this.request = request
|
|
||||||
}
|
|
||||||
|
|
||||||
createResult(item) {
|
createResult(item) {
|
||||||
return super.createResult({
|
return super.createResult({
|
||||||
|
@ -17,24 +14,6 @@ class Autocomplete extends AjaxAutocomplete {
|
||||||
label: `${item.name} (${item.ref})`,
|
label: `${item.name} (${item.ref})`,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
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 response = await this.request.get(
|
|
||||||
`https://geodatamine.fr/boundaries/search?text=${encodeURIComponent(val)}`
|
|
||||||
)
|
|
||||||
if (response && response.ok) {
|
|
||||||
const data = await response.json()
|
|
||||||
this.handleResults(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Plugin {
|
export class Plugin {
|
||||||
|
@ -83,7 +62,7 @@ export class Plugin {
|
||||||
className: 'edit-owner',
|
className: 'edit-owner',
|
||||||
on_select: (choice) => this.onSelect(choice),
|
on_select: (choice) => this.onSelect(choice),
|
||||||
}
|
}
|
||||||
this.autocomplete = new Autocomplete(this.request, container, options)
|
this.autocomplete = new Autocomplete(container, options)
|
||||||
const confirm = () => {
|
const confirm = () => {
|
||||||
importer.urlInput.value = `${this.baseUrl}/data/${select.value}/${this.options.boundary}?format=geojson`
|
importer.urlInput.value = `${this.baseUrl}/data/${select.value}/${this.options.boundary}?format=geojson`
|
||||||
importer.typeInput.value = 'geojson'
|
importer.typeInput.value = 'geojson'
|
||||||
|
|
Loading…
Reference in a new issue