0

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.

Aaron
  • 4,380
  • 19
  • 85
  • 141
  • I don't understand, there can be many emails for one name ? Or is it a oneToOne relationship and you want the email or the person displayed in the second v-autocomplete if you select one or another ? Or do you want to do a search and both autocomplete show you the possible results at the same time ? – Double Bang Feb 09 '21 at 07:29
  • @Polybius yes it it a one to one relationship. I pull the users info from the back end and divide it out between allExternalUsers which has the user name and allExternalUserEmails which contains the emails. I created a codepen that might explain more https://codepen.io/aaronk488/pen/MWbKNOq?editors=1011 – Aaron Feb 09 '21 at 17:36

1 Answers1

2

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!

SneakyLenny
  • 428
  • 4
  • 12