首页 > 解决方案 > Vuetify Autocompletes: How to search for multiple attributes of the object?

问题描述

Vue code:

<template>
  <div>
    <v-card
      color="grey darken-2"
      dark
    >
      <v-card-text>
        <v-autocomplete
          spellcheck="false"
          v-model="model"
          :items="items"
          :loading="isLoading"
          :search-input.sync="search"
          @change="search=''"
          color="white"
          hide-no-data
          hide-selected
          clearable
          item-text="CodeAndName"
          item-value="Code"
          placeholder="Search stock symbols and names"
          prepend-icon="mdi-account-search"
          return-object
          autofocus
          dense
        >
          <template v-slot:item="{ item }">
            <v-list>
            <v-list-item-title class="justify-center">{{item.Code}}</v-list-item-title>
            <v-list-item-subtitle>{{item.Name}}</v-list-item-subtitle>
            <v-list-item-subtitle>{{item.Exchange}}</v-list-item-subtitle>
            </v-list>
          </template>
        </v-autocomplete>
      </v-card-text>
      <v-divider></v-divider>
    </v-card>
    <Chart v-if="model" :exchangeCode="model.Exchange" :symbol="model.Code"/>
  </div>
</template>

JS code:

import Chart from './GChart.vue'
export default {
  name: "Search",
  components: {
    Chart,
  },
  data: () => ({
    symbolsExchangesNames: [],
    isLoading: false,
    model: null,
    search: null
  }),

  computed: {
    items () {
      return this.symbolsExchangesNames
    }
  },
  methods: {
    fetchData() {
      if (this.isLoading && this.model) return
      this.isLoading = true
      this.model = null
      this.symbolsExchangesNames = []
      let hostname = window.location.hostname
      fetch(`http://${hostname}/backend/search/${this.search}`)
        .then(res => res.json())
        .then(res => {
          for(let i of res){
            this.symbolsExchangesNames.push({
              Code: i.Symbol,
              Exchange: i.Exchange,
              Name: i.Name,
              CodeAndName: `${i.Symbol} ${i.Name}`
            })
          }
        })
        .catch(err => {
          console.log(err)
        })
        .finally(() => (this.isLoading = false))
    },
    fetchDebounced() {
      clearTimeout(this._timerId)
      this._timerId = setTimeout(() => {
        this.fetchData()
      }, 200)

    }
  },
  watch: {
    search (val) {
      if(val == null || val == "") return
      if(this.model){
        if(val == this.model.CodeAndName) return
      }
      this.fetchDebounced()
    },
  }
}

As you can see in the item-text property of the autocomplete component, I'm passing "CodeAndName" which is an attribute I made so that it would search for both Code and Name of the item. This means it will show both in the search bar after a selection is made. However I want it to show only name, while searching for both code and name. I have tried passing an array into item-text but that didn't work either. I also don't know what item-value is for, the docs don't specify.

Also I don't know if this matters, but when the API is called, it will return the first 10 results where

if searchterm in item.Code or searchterm in item.Name

标签: vue.jsvuetify.js

解决方案


As mentioned in docs You can define your custom filter method like

  customFilter (item, queryText, itemText) {
      const textOne = item.CodeAndName.toLowerCase()
      const searchText = queryText.toLowerCase()

      return textOne.indexOf(searchText) > -1 
  }

and pass it in
 <v-autocomplete
     spellcheck="false" 
     :filter="customFilter"
...
</v-autocomplete>


推荐阅读