'Vuetify autocomplete component: set value
We use vuetify autocomplete component https://vuetifyjs.com/ru/components/autocompletes to display key/value pairs.
When I open page to create new entity all works fine but when when I open page to modify entity where fields must be filled in with saved values then autocomplete field does not display value.
Here is the example of entity model:
{name : "name", legalId : "123", mcc : {id : "1", description : "text"}}. Items variable has format
[{id : "1", description : "text"}, {id : "2", description : "text"}]
So how it is possible to display "description" property value from model.mcc.description?
<template>
<div>
<v-form class="mt-5">
<v-text-field
v-validate="'required|max:255'"
v-model="model.name"
:error-messages="errors.collect('name')"
:class="inputClass('name')"
label="Name"
data-vv-name="name"
required
></v-text-field>
<v-text-field
v-validate="'required|max:255'"
v-model="model.legalId"
:error-messages="errors.collect('legalId')"
:class="inputClass('legalId')"
label="Legal ID"
data-vv-name="legalId"
required
></v-text-field>
<v-autocomplete
v-model="model.mcc"
:items="items"
:loading="isLoading"
:search-input.sync="searchMccCodes"
:class="inputClass('mccCode')"
color="white"
hide-no-data
hide-selected
item-text="description"
item-value="id"
label=""
placeholder="MCC Code"
></v-autocomplete>
</v-form>
</div>
</template>
<script>
import axios from 'axios';
import queries from '../../utils/queries';
export default {
name: 'MPayMerchantEditor',
props: ['merchant', 'loading', 'showCancel'],
components: {},
data: () => ({
model: {},
isLoading: false,
items: [],
searchMccCodes: null,
required: true,
}),
computed: {
isFormValid() {
return !Object.keys(this.fields)
.some(key => this.fields[key].invalid);
},
isNew() {
return !this.merchant;
},
},
methods: {
submit() {
this.$validator.validateAll()
.then((isValid) => {
if (isValid) {
this.$validator.reset();
this.$emit('submit', this.model);
} else {
this.showValidationErrorMessage();
}
});
},
cancel() {
this.$validator.reset();
this.$emit('cancel', this.model);
},
inputClass(name) {
if (this.fields[name]) {
const changed = this.fields[name].changed;
return { 'merchants-editor__input__not-changed': !changed };
}
return {};
},
storeMerchant() {
if (this.merchant) {
Object.keys(this.merchant)
.forEach((key) => {
this.model[key] = this.merchant[key];
});
this.items.push(this.model.mcc);
this.$validator.reset();
}
},
},
mounted() {
this.storeMerchant();
},
created() {
merchant);
},
watch: {
merchant() {
this.storeMerchant();
},
searchMccCodes(value) {
if (!value) {
return;
}
this.isLoading = true;
axios.get(queries.merchantMccCodes(value))
.then((response) => {
this.items = response.data;
this.isLoading = false;
})
.catch((e) => {
this.showError(e);
this.isLoading = false;
});
},
},
};
</script>
Solution 1:[1]
You need to use the "selection" scoped slot.
<v-autocomplete
v-model="model.mcc"
:items="items"
:loading="isLoading"
:search-input.sync="searchMccCodes"
:class="inputClass('mccCode')"
color="white"
hide-no-data
hide-selected
item-text="description"
item-value="id"
label=""
placeholder="MCC Code"
return-object
>
<template slot="selection" slot-scope="data">
{{ data.item.description }}
</template>
</v-autocomplete>
And you should probably add return-object param to the autocomplete tag.
Solution 2:[2]
As you can see in this snippet, you must ensure the property mcc is created before the render the component. it should throw an error in console telling you mcc is undefined
<!DOCTYPE html>
<html>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>
<div id="app">
<v-app>
<v-main>
<v-container>
<v-autocomplete
v-model="model.mcc"
:items="items"
color="white"
hide-no-data
hide-selected
item-text="description"
item-value="id"
placeholder="MCC Code"
/>
</v-container>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
model: {mcc: {description: ''}},
items: [{id:0, description: 'test 1'}, {id:1, description: 'test 2'}]
})
})
</script>
</body>
</html>
Solution 3:[3]
Have you tried to add return-object to your autocomplete tag ?
Solution 4:[4]
Following snippet worked for me:
<v-autocomplete
[...]
:filter="filter"
:return-object="true"
>
<template slot="selection" slot-scope="data">
{{ data.item.description}}
</template>
<template slot="item" slot-scope="data">
<div>{{ data.item.description}}</div>
</template>
</v-autocomplete>
and add following script:
methods: {
filter (item, queryText, itemText) {
if (queryText != null && item != null && item.description) {
return item.description.toLocaleLowerCase().indexOf(queryText.toLocaleLowerCase()) > -1
}
return -1
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jon Teeter |
| Solution 2 | Pedro Mora |
| Solution 3 | Charles G |
| Solution 4 |
