Search code examples
vue.jsvuetify.jsv-autocomplete

Looking for a way to link two v-autocomplete boxes in Vuetify


enter image description here

In the above picture I have two v-autocomplete boxes one for name and the other for email. Is there a way to connect the two v-autocomplete boxes where when the user enters info for name or email it will also show the options for the other box.

In the example in the image the user inputed the name and got the results for that, how would I show the corresponding emails for the name?

Here is the code for two v-autocomplete boxes

  <v-autocomplete
          v-model="item.userId"
          :items="allExternalUsers"
          :search-input.sync="searchUser"
          label="Name"
          name="name"
          item-value="id"
          item-text="name"
          filled
          dense
          hide-details
          clearable
          autocomplete="off"
          @input="updateSelection"
          @change="triggerChange"
        ></v-autocomplete>
  <v-autocomplete
      v-model="item.email"
      :items="allExternalUserEmails"
      v-validate="'required|email'"
      :error-messages="veeErrors.collect(`${item.id}_email`)"
      :search-input.sync="searchEmail"
      label="Email"
      name="email"
      item-value="id"
      item-text="email"
      filled
      dense
      hide-details
      clearable
      autocomplete="off"
  ></v-autocomplete>

Here is my code for watch

 watch: {
    searchUser(prefix){
      if(prefix && prefix.length > 2){
         this.serviceInstance.userService
        .getExternalUsers(prefix)
        .then(({data}) => {
          this.allExternalUsers = data.externalUser.map(element => `${element.firstName} ${element.lastName}`);
          this.allExternalUserEmails = data.externalUser.map(element => element.email);
          this.over10Results = data.over10Results;
        }).catch(error => console.log(error));
      }else{
        // this.allExternalUsers = [];
        // this.clearExternalUsers();
      }
    },
    searchEmail(prefix){
      if(prefix && prefix.length > 2){
         this.serviceInstance.userService
        .getExternalUsers(prefix)
        .then(({data}) => {
       this.allExternalUsers = data.externalUser.map(element => `${element.firstName} ${element.lastName}`);
          this.allExternalUserEmails = data.externalUser.map(element => element.email);
          this.over10Results = data.over10Results;
        }).catch(error => console.log(error));
      }else{
        this.allExternalUserEmails = [];
        // this.clearExternalUsers();
      }
    },

And this is my backend call

async getExternalUsers(prefix) {
    const url = `/api/v1/external_user/prefix/${prefix}`;
    const method = "GET";
    return this.vue.$http.request({ method, url }).then(response => {
      return response;
    }).catch(error => console.log(error));
  }

I used Postman to make sure there are not issues with my backend call.


Solution

  • I've encountered the same issue and solved it like so:

    I used 1 prop to sync to, and defined what should be the text and what should be the value:

    <v-row>
      <v-col>
        <v-autocomplete
          label="name"
          v-model="autoCompleteInput" <--- syncs to the same prop
          :items="items" <--- uses the same items
          item-text="name" <--- but this one should show a name
          :item-value="(item) => item" <--- return whatever you like (in this case the whole object)
          clearable
        >
        </v-autocomplete>
      </v-col>
      <v-col>
          <v-autocomplete
            label="email"
            v-model="autoCompleteInput" <--- syncs to the same prop
            :items="items" <--- uses the same items
            item-text="email" <--- and this one should show the email
            :item-value="(item) => item" <--- return whatever you like (in this case the whole object)
            clearable
          >
        </v-autocomplete>
      </v-col>
    </v-row>
    

    Now what will happen is when you select a value in the names-autocomplete the same value would be used by the emails-autocomplete and vice versa. While the key difference between the components is: they show a different text. After setting this up correctly you can create your request with @input or @change accordingly. Note that this does require the user and email to be in the same object.

    I've created a sandbox for you so you can see it in action: https://codesandbox.io/s/vue-vuetify-sync-select-or-autocomplete-jjhbk?file=/src/App.vue

    I'm not sure if this will solve you problem, if not let me know!