Search code examples
javascriptcssvue.jsvuetify.jsv-autocomplete

Style v-autocomplete in vuetify


I have a search bar and an autocomplete component. What I'd like is to be able to style the way the autocomplete renders. At the moment, when I type letters, it displays every word that contains those letters and what I'd like is for it to only show the words which begin with the letters I'm typing. Also, is there a way not to highlight the letters, but to display them in bold ?

enter image description here

Here's what my code looks like

<template>
  <div class="inspire" style="background-color:red">
    <v-app-bar style="padding: 10px 0px;"
      color="rgba(33,33,33,255)" 
      elevation="0" 
      height="64px"
    > 
      <div style="width:100%" v-if="$route.name == 'Mapping'">
        <template>
          <v-autocomplete
            v-model="valuesActor"
            :items="actorArray"
            :search-input.sync="searchActor"
            filled
            @blur="toggleSearch"
            background-color="#313131"
            append-icon=""
            color="var(--textLightGrey)"
            :menu-props="{maxWidth: 1600}"
            placeholder="Search for actors"
            active
          >
          </v-autocomplete>
        </template>
      </div>  
    </v-app-bar>
  </div>
</template>

Solution

  • Bold the matching text:

    add an item slot to the autocomplete that uses a method to render the item text the way you want it. You can use regex to get the partial text of an item that matches the query string and surround it with a <strong> tag.

    <v-autocomplete>
     <template v-slot:item="data">
        <div v-html="boldHighlight(data.item)"></div>
      </template>
    </v-autocomplete>
    
    boldHighlight(text) {
      return text.replace(new RegExp(this.searchActor, 'gi'), match => {
        return '<strong>' + match + '</strong>';
      });
    }
    

    Filter only if start of string is a match

    Use the filter prop with the autocomplete to make your own custom filter function. The function will run for every item in the autocomplete list and should return true or false based on the given query.

    <v-autocomplete
      :filter="customFilter"
    />
    
    customFilter(item, queryText) {
      const itemText = item.toLowerCase();
      const searchText = queryText.toLowerCase();
    
      return itemText.startsWith(searchText);
    }
    

    Focus input on page load

    This is done using standard Vue functionality, not specifically Vuetify. Add a ref to the element, which will give you a programmatic way of accessing the DOM element in your code, and then in the mounted hook of your component call the focus function.

    <v-autocomplete
      ref="auto"
    />
    
    mounted() {
      this.$refs.auto.focus()
    }
    

    Here's a codepen putting it all together.