Skip to content
Snippets Groups Projects
Autocomplete.vue 4.3 KiB
Newer Older
<template>
  <div class="autocomplete-container" :class="$vuetify.breakpoint.name">
    <v-combobox aria-label="søkefelt"
Ole Voldsæter's avatar
Ole Voldsæter committed
        v-model="select"
        :loading="loading"
        :items="items"
        :search-input.sync="search"
        item-text="label"
Henrik Askjer's avatar
Henrik Askjer committed
        :menu-props="{maxHeight: $vuetify.breakpoint.name === 'xs' ? 190 : 500, transition: 'fade-transition', allowOverflow: true}"
Ole Voldsæter's avatar
Ole Voldsæter committed
        prepend-inner-icon="search"
Ole Voldsæter's avatar
Ole Voldsæter committed
        return-object
        rounded
Ole Voldsæter's avatar
Ole Voldsæter committed
        hide-no-data
Henrik Askjer's avatar
Henrik Askjer committed
        auto-select-first
Ole Voldsæter's avatar
Ole Voldsæter committed
        no-filter
        hide-details
        label="Søk..."
        solo
Ole Voldsæter's avatar
Ole Voldsæter committed
        placeholder="Søk her"
Ole Voldsæter's avatar
Ole Voldsæter committed
        ref="autocomplete"
        :dense="$vuetify.breakpoint.smAndDown"
Ole Voldsæter's avatar
Ole Voldsæter committed
      >
      <template v-slot:item="data">
Henrik Askjer's avatar
Henrik Askjer committed
      <span class="search-hit">
Henrik Askjer's avatar
Henrik Askjer committed
        {{data.item.label}}
      </span>
Henrik Askjer's avatar
Henrik Askjer committed
      ({{data.item.lang? data.item.lang[1] ? "bm, nn" : {"bob": "bm", "nob": "nn"}[data.item.lang[0]] : 'fritekstsøk'}})
Ole Voldsæter's avatar
Ole Voldsæter committed
      </template>
Henrik Askjer's avatar
Henrik Askjer committed
    </v-combobox>
Ole Voldsæter's avatar
Ole Voldsæter committed
  </div>
</template>

<script>
  import axios from "axios"

  export default {
    props: {
Henrik Askjer's avatar
Henrik Askjer committed
      endpoint: String,
    },
    data: function() {
      return {
        loading: false,
        items: [],
        search: null,
Henrik Askjer's avatar
Henrik Askjer committed
        suggesting: null,
      }
    },
    watch: {
      search (val) {
        if (! val) {
          this.items = []
        } else {
          this.run_query(val)
        }
      },
      select(item) {
Henrik Askjer's avatar
Henrik Askjer committed
        if (item) {
Henrik Askjer's avatar
Henrik Askjer committed
          if (typeof item != 'string') {
            let self = this
Henrik Askjer's avatar
Henrik Askjer committed
            /*
Henrik Askjer's avatar
Henrik Askjer committed
            if (item.articles) {
            axios.get(self.endpoint + 'articles?', {params: {lord: item.match,
                                                             dict: self.$parent.lang}})
              .then(
                function(response) {
                    ['bob', 'nob'].forEach((dict_tag) => {
                      response.data[dict_tag].forEach((article_id) => {
                        let article = {}
                        article.article_id = article_id
                        article.dictionary = dict_tag
                        article.match = item.match
                        item.articles.push(article)
                        })
                      })
                    }
                  )
              }
Henrik Askjer's avatar
Henrik Askjer committed
              */
Henrik Askjer's avatar
Henrik Askjer committed
              this.items = []
              this.suggesting = false

              self.$emit('submit', item)
Henrik Askjer's avatar
Henrik Askjer committed
              setTimeout(() => {
                self.$refs.autocomplete.$refs.input.select()
                this.items = []
                this.suggesting = false
                }, 1)
Henrik Askjer's avatar
Henrik Askjer committed
          }
          // If blurred
          else {
            this.items = []
          }
Henrik Askjer's avatar
Henrik Askjer committed
        }
      }
    },
    methods: {
      run_query(q) {
Henrik Askjer's avatar
Henrik Askjer committed
        this.suggesting = true
Henrik Askjer's avatar
Henrik Askjer committed
        // Put full text search in the list while processing suggestions
        if (this.items[0]) {
          if (this.items[0].lang) {
          this.items.unshift({q: q, label: q})
        }
          else {
            this.items[0] = {q: q, label: q}
          }
        }
Henrik Askjer's avatar
Henrik Askjer committed
        let self = this
        axios.get(self.endpoint + 'suggest?', { params: {q: q,
                                                         dict: self.$parent.lang,
                                                         n: 9}} )
            .then(
                  function(response) {
                        if (self.$refs.autocomplete.searchInput == q & self.suggesting) {

                          let hits = []
                          response.data.forEach((item, i) => {
                            let hit = {q: q, match: item[0], label: item[0], articles: []}
                            hit.lang = item[1]
                            hits.push(hit)

                          });
                          // whitespace necessary because duplicates aren't allowed in the dropdown
                          hits.push({q: q, label: q + ' '})
                          self.items = hits
                        }

                      self.loading = false
                    })

<style scoped>
  .search-hit {
    font-weight: bold;
    margin-right: 5px;
    color: var(--v-primary-base);
Ole Voldsæter's avatar
Ole Voldsæter committed

  .autocomplete-container {
</style>