Search code examples
vue.jsvuetify.jsv-autocomplete

Vuetify Autocomplete with slots, no autocomplete suggestion when typing


I'm trying to make a small tool where someone would fill in some data, this would be either a name or id and the field displays an autocomplete list. (The end result would contain 100+ results, an autocomplete function is needed.)

I've tried to use Vuetify's autocomplete, but I'm struggling to let it filter correctly. I'm using the following code provided by Vuetify, without the Edit button (https://vuetifyjs.com/en/components/autocompletes#custom-filter-on-autocomplete) - and I was able to add in the ID and show it in the results with a scoped slot.

However, if you type something into the input field, it doesn't show any suggestions at all.

I've been looking at this for a few hours and I must be overlooking something. I emptied the slots, checked the method, changed the || and went back to them. I have no clue at this moment.

Codepen fiddle

HTML:

<div id="app">
  <v-app id="inspire">
    <v-card
      class="overflow-hidden"
      color="blue lighten-1"
      dark
    >
      <v-toolbar
        flat
        color="blue"
      >
        <v-icon>mdi-account</v-icon>
        <v-toolbar-title class="font-weight-light">Title</v-toolbar-title>
      </v-toolbar>
      <v-card-text>      
        <v-combobox                      
          :items="states"
          :filter="customFilter"
          color="white"
          label="State"
          clearable
        >

          <template slot="selection" slot-scope="data">
            {{ data.item.id }} - {{ data.item.abbr }} {{ data.item.name }}
          </template>
          <template slot="item" slot-scope="data">
            {{ data.item.id }} - {{ data.item.abbr }} {{ data.item.name }}
          </template>

        </v-combobox>
      </v-card-text>
    </v-card>
  </v-app>
</div>

Vue:

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      model: null,
      states: [
        { name: 'Florida', abbr: 'FL', id: '1' },
        { name: 'Georgia', abbr: 'GA', id: '2' },
        { name: 'Nebraska', abbr: 'NE', id: '3' },
        { name: 'California', abbr: 'CA', id: '4' },
        { name: 'New York', abbr: 'NY', id: '5' },
      ],
    }
  },
  methods: {
    customFilter (item, queryText, itemText) {
      const filterName = item.name.toLowerCase()
      const filterAbbr = item.abbr.toLowerCase()
      const filterId = item.id.toLowerCase()
      const searchText = queryText.toLowerCase()

      return 
      filterName.indexOf(searchText) > -1 ||
      filterAbbr.indexOf(searchText) > -1 ||
      filterId.indexOf(searchText) > -1
    },
  },
})

Solution

  • Just use a single line for the last return and it works

    return filterName.indexOf(searchText) > -1 || filterAbbr.indexOf(searchText) > -1 || filterId.indexOf(searchText) > -1;
    

    or

    return ( 
      filterName.indexOf(searchText) > -1 || 
      filterAbbr.indexOf(searchText) > -1 || 
      filterId.indexOf(searchText) > -1
    )