Vue Datalist Component
with vue 2.6
by jorgeluis
HTML
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<link rel="stylesheet" href="https://unpkg.com/buefy/dist/buefy.min.css">
<script src="https://unpkg.com/buefy/dist/buefy.min.js"></script>
<div id="app">
<tags-datalist :list="scopes" :selected="itemScopes"></tags-datalist>
</div>
<template id="tags-datalist">
<div>
<div class="tags">
<b-tag
v-for="tag in localSelected"
:key="tag"
closable
aria-close-label="Close tag"
@close="removeItem(tag)">
{{ tag }}
</b-tag>
</div>
<div class="field">
<label v-if="label" class="label">{{ label }}</label>
<div class="control">
<input v-model="term" list="item-list" class="input" @change="addItem"
name="item-selection" id="item-selection"/>
<small ref="hint" class="is-size-7 has-text-grey"></small>
<datalist id="item-list">
<option v-for="option in localList" v-bind:value="option" v-bind:label="option"></option>
</datalist>
</div>
</div>
</div>
</template>
JavaScript
Vue.component('tags-datalist', {
template: '#tags-datalist',
name: 'tags-datalist',
props: {
label: null,
list: {
type: Array,
default: []
},
selected: {
type: Array,
default: []
}
},
data () {
return {
localList: [],
localSelected: [],
term: ''
}
},
created () {
this.localList = this.list
this.localSelected = this.selected
},
methods: {
addItem: function(e) {
this.$refs.hint.innerHTML = ''
let newItem = e.target.value;
if (!this.localSelected.includes(newItem)) {
this.localSelected.push(newItem)
} else {
this.$refs.hint.innerHTML = 'Already listed'
}
this.term = ''
},
removeItem: function(item) {
this.$refs.hint.innerHTML = ''
this.localSelected = this.localSelected.filter(i => i !== item)
}
}
});
// parent data to use for child props
var vm = new Vue({
el: '#app',
data () {
return {
scopes: [
'one', 'two', 'three'
],
itemScopes: [
'one', 'three', 'and some other random one from the API?'
]
}
}
});