77 lines
2.0 KiB
Vue
77 lines
2.0 KiB
Vue
<template>
|
|
<div class="control">
|
|
<datalist :id="listId">
|
|
<template v-for="item in items" :key="item.path">
|
|
<option :value="item[field]"></option>
|
|
</template>
|
|
</datalist>
|
|
<input type="text" :name="name" :placeholder="placeholder"
|
|
:list="listId" @keyup="onKeyUp"/>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
// import debounce from 'lodash/debounce'
|
|
|
|
export default {
|
|
props: {
|
|
url: String,
|
|
model: Function,
|
|
placeholder: String,
|
|
name: String,
|
|
field: String,
|
|
valueField: {type: String, default: 'id'},
|
|
count: {type: Number, count: 10},
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
value: '',
|
|
items: [],
|
|
selected: null,
|
|
isFetching: false,
|
|
listId: `autocomplete-${ Math.random() }`.replace('.',''),
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
select(option, value=null) {
|
|
if(!option && value !== null)
|
|
option = this.items.find(item => item[this.field] == value)
|
|
|
|
this.selected = option
|
|
this.$emit('select', option)
|
|
},
|
|
|
|
onKeyUp: function(event) {
|
|
const value = event.target.value
|
|
if(value === this.value)
|
|
return
|
|
|
|
if(value !== undefined && value !== null)
|
|
this.value = value
|
|
|
|
if(!value)
|
|
return this.select(null)
|
|
|
|
this.fetch(value)
|
|
},
|
|
|
|
fetch: function(query) {
|
|
if(!query || this.isFetching)
|
|
return
|
|
|
|
this.isFetching = true
|
|
return this.model.fetch(this.url.replace('${query}', query), {many:true})
|
|
.then(items => { this.items = items || []
|
|
this.isFetching = false
|
|
this.select(null, query)
|
|
return items },
|
|
data => {this.isFetching = false; Promise.reject(data)})
|
|
},
|
|
},
|
|
}
|
|
|
|
</script>
|
|
|