11<template >
22 <k-field :input =" _uid" v-bind =" $props" class =" k-locator-field" >
33 <div class =" k-input k-locator-input" data-theme =" field" >
4- <input ref =" input" v-model =" location" class =" k-text-input" :placeholder =" $t('locator.placeholder')" >
4+ <input ref =" input" v-model =" location" class =" k-text-input" :placeholder =" $t('locator.placeholder')" @input = " onLocationInput " >
55 <button :class =" [{disabled: !location.length}]" @click =" getCoordinates" ><svg ><use xlink:href =" #icon-locator-locate" /></svg > {{ $t('locator.locate') }}</button >
6+ <k-dropdown-content v-if =" autocomplete" ref =" dropdown" >
7+ <k-dropdown-item v-for =" (option, index) in dropdownOptions"
8+ :key =" index"
9+ @click =" select(option)"
10+ @keydown.native.enter.prevent =" select(option)"
11+ @keydown.native.space.prevent =" select(option)" >
12+ <span v-html =" option.name" />
13+ <span class =" k-location-type" v-html =" option.type" />
14+ </k-dropdown-item >
15+ </k-dropdown-content >
616 </div >
717 <k-dialog ref =" dialog" @close =" error = ''" >
818 <k-text >{{ error }}</k-text >
@@ -40,6 +50,8 @@ export default {
4050 tileLayer: null ,
4151 location: ' ' ,
4252 error: ' ' ,
53+ limit: 1 ,
54+ dropdownOptions: [],
4355 }
4456 },
4557 props: {
@@ -52,6 +64,7 @@ export default {
5264 geocoding: String ,
5365 liststyle: String ,
5466 draggable: Boolean ,
67+ autocomplete: Boolean ,
5568
5669 // general options
5770 label: String ,
@@ -118,10 +131,10 @@ export default {
118131 return ' https://nominatim.openstreetmap.org/search?format=jsonv2&limit=1&addressdetails=1&q=' + this .location
119132 }
120133 else if (this .geocoding == ' mapbox' ) {
121- return ' https://api.mapbox.com/geocoding/v5/mapbox.places/' + this .location + ' .json?types=address,country,postcode,place,locality&limit=1 &access_token=' + this .mapbox .token
134+ return ' https://api.mapbox.com/geocoding/v5/mapbox.places/' + this .location + ' .json?types=address,country,postcode,place,locality&limit=' + this . limit + ' &access_token=' + this .mapbox .token
122135 }
123136 else return ' '
124- }
137+ },
125138 },
126139 watch: {
127140 value () {
@@ -132,6 +145,47 @@ export default {
132145 this .initMap ()
133146 },
134147 methods: {
148+ onLocationInput () {
149+ if (! this .autocomplete ) return false
150+
151+ if (this .geocoding && this .location .length ) {
152+ if (this .geocoding != ' mapbox' ) return false
153+
154+ this .limit = 5
155+ fetch (this .searchQuery )
156+ .then (response => response .json ())
157+ .then (response => {
158+ // if places are found
159+ if (response .features .length ) {
160+ // keep the relevant ones
161+ let suggestions = response .features .filter (el => el .relevance == 1 )
162+ // make them the dropdown options
163+ this .dropdownOptions = suggestions .map (el => {
164+ return {
165+ name: el .place_name ,
166+ type: this .capitalize (el .place_type [0 ]),
167+ }
168+ })
169+ this .$refs .dropdown .open ()
170+ }
171+ else {
172+ this .$refs .dropdown .close ()
173+ }
174+ })
175+ .catch (error => {
176+ this .error = this .$t (' locator.error' )
177+ this .$refs .dialog .open ()
178+ this .$refs .dropdown .close ()
179+ })
180+ }
181+ else {
182+ this .$refs .dropdown .close ()
183+ }
184+ },
185+ select (option ) {
186+ this .location = option .name
187+ this .getCoordinates ()
188+ },
135189 translatedTitle (key ) {
136190 key = key .replace (' lon' , ' longitude' )
137191 key = key .replace (' lat' , ' latitude' )
@@ -185,8 +239,13 @@ export default {
185239 })
186240 },
187241 getCoordinates (e ) {
188- e .preventDefault ()
189- e .stopPropagation ()
242+ if (e) {
243+ e .preventDefault ()
244+ e .stopPropagation ()
245+ }
246+
247+ if (this .$refs .dropdown ) this .$refs .dropdown .close ()
248+ this .limit = 1
190249
191250 if (this .geocoding && this .location .length ) {
192251 fetch (this .searchQuery )
@@ -199,7 +258,6 @@ export default {
199258 else if (this .geocoding == ' mapbox' ) {
200259 this .setMapboxResponse (response)
201260 }
202-
203261 this .location = ' '
204262 }
205263 else {
@@ -240,6 +298,9 @@ export default {
240298 ' address' : response .text || ' ' ,
241299 }
242300 },
301+ capitalize (str ) {
302+ return str .charAt (0 ).toUpperCase () + str .slice (1 );
303+ }
243304 },
244305}
245306 </script >
0 commit comments