Reputation: 552
I require a lookup dropdown where I should be able to watch for multiple data changes. Currently I have this in my html:
<input list="allUsernames" type="text" v-model="selectedUser">
<datalist id="allUsernames">
<option v-for="(user, index) in allUsers"
:id="user.USERID"
:value="user.USERNAME"
:email="user.EMAIL">
</option>
</datalist>
My script data tag looks like this:
data(){
return{
allUsers: [],
selectedUserID: '',
selectedUserEmail: '',
selectedUser: '',
}
}
allUsers
gets filled by an SQL call containing USERID
, USERNAME
and EMAIL
.
I want a watch
to be able to get the :id
and the :email
part of the option tag, but right now I can only seem to retrieve the value by default:
watch: {
selectedUser(val, oldval)
{
console.log('this only returns the :value binding:' + val);
//how do I get :id and :email values?
}
},
I want to set selectedUserID
and selectedUserEmail
based on the dropdown option selection made, using the vbindings
:id
and :email
(so that I get the user.USERID
and user.EMAIL
values), how do I do this?
Upvotes: 1
Views: 163
Reputation: 63099
You can do this more cleanly with only the v-model
data, and no watch is necessary:
data(){
return{
allUsers: [],
selectedUser: ''
}
}
Only the value
binding is necessary on the options:
<option v-for="(user, index) in allUsers" :value="user.USERNAME"></option>
Use a computed to track the full object of the selected user:
computed: {
selected() {
return this.allUsers.find(user => user.USERNAME === this.selectedUser);
}
}
The selected
computed refers to the whole object of the selected user, so you can use selected.USERID
and selected.EMAIL
in both the instance and the template.
Here's a demo:
new Vue({
el: "#app",
data(){
return{
allUsers: [
{ USERID: 1, USERNAME: 'name1', EMAIL: 'email1' },
{ USERID: 2, USERNAME: 'name2', EMAIL: 'email2' },
{ USERID: 3, USERNAME: 'name3', EMAIL: 'email3' },
],
selectedUser: ''
}
},
computed: {
selected() {
return this.allUsers.find(user => user.USERNAME === this.selectedUser);
}
}
});
.display {
margin-top: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input list="allUsers" type="text" v-model="selectedUser">
<datalist id="allUsers">
<option v-for="(user, index) in allUsers" :value="user.USERNAME"></option>
</datalist>
<div v-if="selected" class="display">
<div>ID: {{ selected.USERID }}</div>
<div>EMAIL: {{ selected.EMAIL }}</div>
</div>
</div>
A good key to remember is that a watch is only necessary if you want to perform an async or time-based action when data changes. Otherwise, in most cases, use a computed.
Upvotes: 1