widgets: fix map search widget on mobile (#74634) #127
|
@ -634,13 +634,27 @@ div.file-button .widget-message {
|
|||
width: 100%
|
||||
}
|
||||
|
||||
&--input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&--result-list {
|
||||
background-image: none;
|
||||
padding-right: 0.7em;
|
||||
background: white;
|
||||
}
|
||||
|
||||
&--result-item {
|
||||
text-wrap: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
cursor: pointer;
|
||||
padding: 6px;
|
||||
font-size: 1.2em;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover, &.selected {
|
||||
color: white;
|
||||
background-color: #5897fb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ class SearchControl extends L.Control {
|
|||
this._map = map
|
||||
this._container = L.DomUtil.create('div', 'leaflet-search')
|
||||
this._resultLocations = []
|
||||
this._selectedIndex = -1
|
||||
|
||||
this._buttonBar = L.DomUtil.create('div', 'leaflet-bar', this._container)
|
||||
|
||||
|
@ -35,14 +36,15 @@ class SearchControl extends L.Control {
|
|||
this._control = L.DomUtil.create('div', 'leaflet-search--control', this._container)
|
||||
this._control.style.visibility = 'collapse'
|
||||
|
||||
this._searchInput = L.DomUtil.create('input', '', this._control)
|
||||
this._searchInput = L.DomUtil.create('input', 'leaflet-search--input', this._control)
|
||||
this._searchInput.placeholder = this.options.labels.hint
|
||||
|
||||
this._feedback = L.DomUtil.create('div', '', this._control)
|
||||
|
||||
this._resultList = L.DomUtil.create('select', 'leaflet-search--result-list', this._control)
|
||||
this._resultList.size = this.options.maxResults
|
||||
this._resultList.style.visibility = "collapse"
|
||||
this._resultList = L.DomUtil.create('div', 'leaflet-search--result-list', this._control)
|
||||
this._resultList.style.visibility = 'collapse'
|
||||
this._resultList.tabIndex = 0
|
||||
this._resultList.setAttribute('aria-role', 'list')
|
||||
|
||||
L.DomEvent
|
||||
.on(this._container, 'click', L.DomEvent.stop, this)
|
||||
|
@ -52,8 +54,6 @@ class SearchControl extends L.Control {
|
|||
.on(this._toggleButton, 'click', this._onToggleButtonClick, this)
|
||||
.on(this._searchInput, 'keydown', this._onSearchInputKeyDown, this)
|
||||
.on(this._searchInput, 'input', this._onSearchInput, this)
|
||||
.on(this._resultList, 'change', this._onResultListChange, this)
|
||||
.on(this._resultList, 'click', this._onResultListClick, this)
|
||||
.on(this._resultList, 'keydown', this._onResultListKeyDown, this)
|
||||
|
||||
return this._container
|
||||
|
@ -62,16 +62,16 @@ class SearchControl extends L.Control {
|
|||
onRemove (map) {
|
||||
}
|
||||
|
||||
_showControl() {
|
||||
this._container.classList.add("open")
|
||||
_showControl () {
|
||||
this._container.classList.add('open')
|
||||
this._buttonBar.style.visibility = 'collapse'
|
||||
this._control.style.removeProperty('visibility')
|
||||
this._initialBounds = this._map.getBounds()
|
||||
setTimeout(() => this._searchInput.focus(), 50)
|
||||
}
|
||||
|
||||
_hideControl(resetBounds) {
|
||||
this._container.classList.remove("open")
|
||||
_hideControl (resetBounds) {
|
||||
this._container.classList.remove('open')
|
||||
if (resetBounds) {
|
||||
this._map.fitBounds(this._initialBounds)
|
||||
}
|
||||
|
@ -79,7 +79,6 @@ class SearchControl extends L.Control {
|
|||
this._buttonBar.style.removeProperty('visibility')
|
||||
this._control.style.visibility = 'collapse'
|
||||
this._toggleButton.focus()
|
||||
this._resultList.selectedIndex = -1
|
||||
}
|
||||
|
||||
_onControlFocusIn (event) {
|
||||
|
@ -92,16 +91,12 @@ class SearchControl extends L.Control {
|
|||
this._hideTimeout = setTimeout(() => this._hideControl(), 50)
|
||||
}
|
||||
|
||||
_getSelectedLocation() {
|
||||
let selectedIndex = this._resultList.selectedIndex
|
||||
if(selectedIndex == -1) {
|
||||
if(this._resultLocations.length === 0) {
|
||||
return null
|
||||
}
|
||||
selectedIndex = 0
|
||||
_getSelectedLocation () {
|
||||
if (this._selectedIndex === -1) {
|
||||
return null
|
||||
}
|
||||
|
||||
return this._resultLocations[selectedIndex]
|
||||
return this._resultLocations[this._selectedIndex]
|
||||
}
|
||||
|
||||
_focusLocation (location) {
|
||||
|
@ -130,16 +125,27 @@ class SearchControl extends L.Control {
|
|||
this._showControl()
|
||||
}
|
||||
|
||||
_selectIndex(index) {
|
||||
this._resultList.selectedIndex = index
|
||||
const selectedLocation = this._getSelectedLocation()
|
||||
this._focusLocation(selectedLocation)
|
||||
this._resultList.focus()
|
||||
_selectIndex (index) {
|
||||
for (const resultItem of this._resultList.children) {
|
||||
resultItem.classList.remove('selected')
|
||||
}
|
||||
|
||||
this._selectedIndex = index
|
||||
|
||||
if (index === -1) {
|
||||
this._map.fitBounds(this._initialBounds)
|
||||
this._searchInput.focus()
|
||||
} else {
|
||||
this._focusLocation(this._resultLocations[index])
|
||||
const selectedElement = this._resultList.children[index]
|
||||
selectedElement.classList.add('selected')
|
||||
this._resultList.focus()
|
||||
}
|
||||
}
|
||||
|
||||
_onSearchInputKeyDown (event) {
|
||||
const results = this._resultList.options
|
||||
if (results.length == 0) {
|
||||
const results = this._resultLocations
|
||||
if (results.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -152,7 +158,7 @@ class SearchControl extends L.Control {
|
|||
}
|
||||
}
|
||||
|
||||
_clearResults() {
|
||||
_clearResults () {
|
||||
while (this._resultList.lastElementChild) {
|
||||
this._resultList.removeChild(this._resultList.lastElementChild)
|
||||
}
|
||||
|
@ -170,27 +176,28 @@ class SearchControl extends L.Control {
|
|||
this._clearResults()
|
||||
|
||||
this._feedback.innerHTML = this.options.labels.searching
|
||||
this._feedback.classList.remove("error")
|
||||
this._feedback.classList.remove('error')
|
||||
|
||||
$.ajax({
|
||||
url: this.options.searchUrl,
|
||||
data: { q: searchString },
|
||||
success: (data) => {
|
||||
this._feedback.innerHTML = ""
|
||||
this._feedback.innerHTML = ''
|
||||
this._resultLocations = []
|
||||
var firstResults = data.slice(0, this.options.maxResults)
|
||||
const firstResults = data.slice(0, this.options.maxResults)
|
||||
|
||||
if(firstResults.length == 0) {
|
||||
if (firstResults.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
this._resultList.style.removeProperty('visibility')
|
||||
this._resultList.size = Math.max(2, firstResults.length)
|
||||
|
||||
for (const result of firstResults) {
|
||||
const resultItem = L.DomUtil.create('option', 'leaflet-search--result-item', this._resultList)
|
||||
const resultItem = L.DomUtil.create('div', 'leaflet-search--result-item', this._resultList)
|
||||
resultItem.innerHTML = result.display_name
|
||||
resultItem.title = result.display_name
|
||||
resultItem.setAttribute('aria-role', 'list-item')
|
||||
L.DomEvent.on(resultItem, 'click', this._onResultItemClick, this)
|
||||
|
||||
const bbox = result.boundingbox
|
||||
|
||||
|
@ -205,7 +212,7 @@ class SearchControl extends L.Control {
|
|||
},
|
||||
error: () => {
|
||||
this._feedback.innerHTML = this.options.labels.error
|
||||
this._feedback.classList.add("error")
|
||||
this._feedback.classList.add('error')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -219,24 +226,24 @@ class SearchControl extends L.Control {
|
|||
}
|
||||
}
|
||||
|
||||
_onResultListChange (event) {
|
||||
const selectedLocation = this._getSelectedLocation()
|
||||
this._focusLocation(selectedLocation)
|
||||
}
|
||||
|
||||
_onResultListClick (event) {
|
||||
_onResultItemClick (event) {
|
||||
const elementIndex = Array.prototype.indexOf.call(this._resultList.children, event.target)
|
||||
this._selectIndex(elementIndex)
|
||||
const selectedLocation = this._getSelectedLocation()
|
||||
this._validateLocation(selectedLocation)
|
||||
}
|
||||
|
||||
_onResultListKeyDown (event) {
|
||||
const results = this._resultList.options
|
||||
if (
|
||||
(event.keyCode === 38 && this._resultList.selectedIndex === 0) ||
|
||||
(event.keyCode === 40 && this._resultList.selectedIndex === results.length - 1)
|
||||
) {
|
||||
this._searchInput.focus()
|
||||
this._resultList.selectedIndex = -1
|
||||
const results = this._resultLocations
|
||||
if (event.keyCode === 38) {
|
||||
this._selectIndex(this._selectedIndex - 1)
|
||||
event.preventDefault()
|
||||
} else if (event.keyCode === 40) {
|
||||
if (this._selectedIndex === results.length - 1) {
|
||||
this._selectIndex(-1)
|
||||
} else {
|
||||
this._selectIndex(this._selectedIndex + 1)
|
||||
}
|
||||
event.preventDefault()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue