HTML
<div :class="classes">
<input v-model="compValue"
type="text"
class="form-control"
@keydown.enter = 'enter'
@keydown.down = 'down'
@keydown.up = 'up'
@input = "change"
>
<ul :class="dropDownClasses">
<li v-for="(suggestion, index) in matches"
v-html="suggestion"
v-on:mouseover="mouseOverLi(index)"
:class="{'active': isActive(index)}"
@click="suggestionClick(index)"
>
</li>
</ul>
</div>
Script
<script>
export default {
data: function() {
return {
compValue: this.value,
current: 0,
open: false,
}
},
props: {
value: {
type: String,
default: '',
},
suggestions: {
type: Array,
default: []
},
disabled: {
type: Boolean,
default: false,
},
readonly: {
type: Boolean,
default: false,
},
},
computed: {
classes: function() {
return {
'br-auto-complete': true,
'open': this.openSuggestion
};
},
dropDownClasses: function() {
return {
'dropdown-menu': true,
};
},
matches: function() {
return this.suggestions.filter((str) => {
return str.toUpperCase().indexOf(this.compValue.toUpperCase()) >= 0;
});
},
openSuggestion() {
return this.compValue !== "" &&
this.matches.length != 0 &&
this.open === true;
},
},
methods: {
//When enter pressed on the input
enter: function() {
this.compValue = this.matches[this.current];
this.open = false;
},
//When up pressed while suggestions are open
up: function() {
if(this.current > 0)
this.current--;
},
//When up pressed while suggestions are open
down: function() {
if(this.current < this.matches.length - 1)
this.current++;
},
//For highlighting element
isActive: function(index) {
return index === this.current;
},
mouseOverLi: function(index){
this.current = index;
},
//When the user changes input
change: function() {
if (this.open == false) {
this.open = true;
this.current = 0;
}
this.$emit('input', this.compValue);
},
//When one of the suggestion is clicked
suggestionClick: function(index) {
this.compValue = this.matches[index];
this.open = false;
this.$emit('input', this.compValue);
},
},
}
</script>