<template> <div class="autocomplete-container" :class="$vuetify.breakpoint.name"> <v-combobox accesskey="s" aria-label="søkefelt" 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', allowOverflow: true}" prepend-inner-icon="search" :append-icon="null" return-object rounded hide-no-data auto-select-first no-filter hide-details label="Søk..." solo full-width flat outlined placeholder="Søk her" ref="autocomplete" color="primary" :dense="$vuetify.breakpoint.smAndDown" > <template v-slot:item="data"> <span class="search-hit"> {{data.item.label}} </span> ({{data.item.lang? data.item.lang[1] ? "bm, nn" : {"bob": "bm", "nob": "nn"}[data.item.lang[0]] : data.item.mode}}) </template> <template slot="no-data"> <div></div> </template> </v-combobox> </div> </template> <script> export default { props: { api: Function, }, data: function() { return { loading: false, items: [], search: null, select: null, suggesting: null, } }, watch: { search (val) { const time = Date.now() if (! val) { this.items = [] } else { this.run_query(val, time) } }, select(item) { if (item) { this.items = [] if (typeof item != 'string') { this.suggesting = false this.submit(item) } } } }, methods: { run_query(q, time) { this.suggesting = true // Keep full text search in the list while requesting suggestions if (this.items[0]) { if (this.items[0].time < time) { this.items.splice(0,1, {q: q, label: q, time: time, mode: 'fritekst'}) } } else { this.items.push({q: q, label: q, time: time}) } let self = this self.api.get('suggest?', {params: {q: q, dict: self.$parent.lang, n: 80, scope: 'nf'}}) .then(async (response) => { if (self.$refs.autocomplete.searchInput == q & self.suggesting) { let word_hits = response.data.a.n.map(item => ({q: q, match: item[0], label: item[0], time: time, lang: item[1]})) let text_hits = response.data.a.f.map(item => ({q: q, match: item[0], label: item[0], time: time, mode: 0})) let hits = [] if( q.charAt(q.length-1) === '!') hits = text_hits.concat(word_hits) else hits = word_hits.concat(text_hits) if (/_|\*|\|/.test(q)) { hits.push({q: q, label: q + ' ', time: time, mode: "mønster"}) } response.data.a.n.forEach((item) => { let match = item[0] let hit = {q: q, match: match, label: match, time: time, lang: item[1]} hits.push(hit) }); response.data.a.f.forEach((item) => { let match = item[0] let hit = {q: q, match: match, label: match, time: time, mode: "fulltekst"} hits.push(hit) }); // whitespace necessary because duplicates aren't allowed in the dropdown hits.push({q: q, label: q + ' ', time: time, mode: "fritekst"}) self.items = hits } self.loading = false }) }, submit(item) { this.$emit('submit', item) let self = this setTimeout(() => { self.$refs.autocomplete.$refs.input.select() this.items = [] this.suggesting = false }, 1) } }, } </script> <style scoped> .search-hit { font-weight: bold; margin-right: 5px; color: var(--v-primary-base); } .autocomplete-container { padding-left: 10px; padding-right: 10px; } </style>