Newer
Older
<div class="autocomplete-container" :class="$vuetify.breakpoint.name">
<v-autocomplete
v-model="select"
:loading="loading"
:items="items"
:search-input.sync="search"
item-text="label"
:menu-props="{maxHeight: $vuetify.breakpoint.name === 'xs' ? 190 : 500, transition: 'fade-transition'}"
:append-icon="null"
hide-no-data
no-filter
hide-details
label="Søk..."
solo
full-width
>
<template v-slot:item="data">
<span class="search-hit">{{data.item.label}} </span> ({{data.item.lang_set ? Array.from(data.item.lang_set).sort().join(', ') : 'fritekstsøk'}})
</template>
</v-autocomplete>
</div>
import debounce from "debounce"
export default {
props: {
endpoint: String
},
data: function() {
return {
loading: false,
items: [],
search: null,
select: null,
debounced: debounce(function(q, self) {
self.loading = true
return axios.get(self.endpoint + 'suggest?q=' + encodeURIComponent(q))
.then(
function(response) {
let hits = []
if (q == self.search) {
response.data.forEach((item, i) => {
let match = encodeURIComponent(item.match)
if (! hits[0] || hits[0].word != match) {
hits.splice(0, 0, {q: encodeURIComponent(q), lang_set: new Set(), word: match, articles: []})
}
hits[0].lang_set.add(item.dictionary == 'bob' ? 'bm' : 'nn')
hits[0].articles.push(item)
});
hits.forEach(function (hit) {
if (hit.lang_set) {
hit.label = decodeURIComponent(hit.word)
}
});
hits.reverse()
hits = hits.slice(0, 9)
hits.unshift({q: encodeURIComponent(q), label: q + ' '})
}
hits.sort( (h1, h2) => {
let val1 = h1.label.length * 10 + (h1.label[0].toLowerCase() === h1.label[0] ? 0 : 1)
let val2 = h2.label.length * 10 + (h2.label[0].toLowerCase() === h2.label[0] ? 0 : 1)
return val1 - val2
})
self.items = hits
self.loading = false
})
}
},
watch: {
search (val) {
if (! val) {
this.items = []
} else {
this.run_query(val)
}
},
select(item) {
this.$emit('submit', item)
let self = this
setTimeout(() => self.$refs.autocomplete.$refs.input.select(), 1)
}
},
methods: {
run_query(q) {
<style scoped>
.search-hit {
font-weight: bold;
margin-right: 5px;
color: var(--v-primary-base);
padding-left: 10px;
padding-right: 10px;