First
This commit is contained in:
104
htdocs/Autocomplete.vue
Normal file
104
htdocs/Autocomplete.vue
Normal file
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div class="autocomplete">
|
||||
<input type="text" @input="option_open" v-model="xvalue" @keydown.down="option_down" @keydown.up="option_up" @keydown.enter="option_enter" />
|
||||
<ul id="autocomplete-results" v-show="open" class="autocomplete-results">
|
||||
<li class="loading" v-if="!items">Loading results...</li>
|
||||
<li v-else v-for="(result, i) in results" :key="i" @click="option_click(result)" class="autocomplete-result" :class="{ 'is-active': i === index }">{{ result }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.autocomplete {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.autocomplete-results {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: 1px solid #eeeeee;
|
||||
height: 120px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.autocomplete-result {
|
||||
list-style: none;
|
||||
text-align: left;
|
||||
padding: 4px 2px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.autocomplete-result.is-active,
|
||||
.autocomplete-result:hover {
|
||||
background-color: #4AAE9B;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
items: {
|
||||
type: Array,
|
||||
required: false,
|
||||
default: () => [],
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
xvalue: '',
|
||||
results: [],
|
||||
open: false,
|
||||
index: -1,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
this.xvalue = val;
|
||||
},
|
||||
xvalue(val) {
|
||||
this.$emit('update:value', val);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.xvalue = this.value;
|
||||
document.addEventListener('click', this.option_close)
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener('click', this.option_close)
|
||||
},
|
||||
methods: {
|
||||
option_open() {
|
||||
if(this.items) {
|
||||
this.results = this.items.filter((item) => item.toLowerCase().indexOf(this.xvalue.toLowerCase()) > -1);
|
||||
this.open = true;
|
||||
}
|
||||
},
|
||||
option_down() {
|
||||
if(this.index < this.results.length) this.index++;
|
||||
},
|
||||
option_up() {
|
||||
if(this.index > 0) this.index--;
|
||||
},
|
||||
option_enter() {
|
||||
this.xvalue = this.results[this.index];
|
||||
this.open = false;
|
||||
this.index = -1;
|
||||
},
|
||||
option_click(result) {
|
||||
this.xvalue = result;
|
||||
this.open = false;
|
||||
},
|
||||
option_close(evt) {
|
||||
if(!this.$el.contains(evt.target)) {
|
||||
this.open = false;
|
||||
this.index = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
Reference in New Issue
Block a user