Vue.js Autocomplete
by jessekinsman
HTML
<div id="compContainer">
<autocomplete :items="testData"></autocomplete>
</div>
CSS
* {
box-sizing: border-box;
}
.autocomplete {
position: relative;
width: 100%;
}
.autocomplete-results {
padding: 0;
margin: 0;
border: 1px solid #eeeeee;
height: 120px;
overflow: auto;
}
.autocomplete-input {
width: 100%;
padding: .5em;
font-size: 1.2em;
}
.autocomplete-result, .close {
list-style: none;
text-align: left;
padding: 4px 2px;
cursor: pointer;
}
.autocomplete-result:hover {
background-color: #4AAE9B;
color: white;
}
.close {
text-decoration: underline;
position: absolute;
bottom: 5px;
}
JavaScript
Vue.component('autocomplete', {
props: ['items'],
methods: {
filter: function(e) {
this.results = this.items.filter((item) => {
return item.text.toLowerCase().indexOf(this.search.toLowerCase()) > -1;
});
if (this.results.length > 0) {
this.isOpen = true;
}
},
hide: function() {
this.isOpen = false;
},
setItem: function(item) {
this.selected = item;
this.search = item.text;
this.filter();
this.isOpen = false;
},
open: function() {
if (this.results.length > 0) {
this.isOpen = true;
}
}
},
data: function() {
return {
isOpen: false,
search: '',
results: [],
selected: {}
};
},
template: `
<div class="autocomplete">
<input class="autocomplete-input" type="text" v-model="search" @input="filter($event)" @click="open()" >
<div class="autocomplete-results-container" v-if="isOpen">
<ul class="autocomplete-results">
<li v-for="(item, i) in results" @click="setItem(item)" :key="i" class="autocomplete-result">{{item.text}}</li>
<li class="close" @click="hide()">Close</li>
</ul>
</div>
</div>
`
});
var testData = [
{id: 1, text: "Small false 1", updatedAt: 1558729871918},
{id: 2, text: "Small true 1", updatedAt: 1542840193473},
{id: 3, text: "Small false 2", updatedAt: 1542841969171},
{id: 4, text: "Small false 3", updatedAt: 1542841995792},
{id: 5, text: "Small true 2", updatedAt: 1542841995792},
{id: 6, text: "Small false 4", updatedAt: 1542840824567}
];
new Vue({el: '#compContainer', data:{testData: testData}});