Reputation: 15219
I saw some documentation on v-select and slots, but didn't really understand if I can apply it for my example codepen.
I just need to get the selected text (not the value), and use it somewhere in the code:
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: {
state: {},
selectedText: "",
states: [
{ value: "a", text: "alpha" },
{ value: "b", text: "beta" },
{ value: "g", text: "gamma" }
]
},
methods: {
change: (newValue) => {
// do something with the text
// "alpha", "beta", or "gama"
console.log(newValue);
}
}
});
<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"/>
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
<div id="app">
<v-app id="inspire">
<v-container fluid>
<label>my selected text is: {{state}}</label>
<v-row align="center">
<v-col cols="3">
<v-select v-model="state" :items="states" @change="change" :text="selectedText"></v-select>
</v-col>
</v-row>
</v-container>
</v-app>
</div>
Upvotes: 1
Views: 796
Reputation: 15219
EDIT:
The best option I found is to use a computed
property for the selected text, without changes to the current code (go in FullPage after lauching the snippet to correctly see the output):
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: {
countries: [
{ code: "a", name: "Ameriga Fatela" },
{ code: "b", name: "Bolivia Grande" },
{ code: "c", name: "Comore Potentia" }
],
country: "b"
},
methods: {
getCountryCode() {
return "c"; // have no c.name here!
},
change() {
this.country = this.getCountryCode();
}
},
computed: {
countryName() {
return this.countries.find((c) => c.code === this.country).name;
}
}
});
<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" />
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
<div id="app">
<v-app>
<v-container>
<div>current code is >{{country}}<</div>
<div>current name is >{{countryName}}<</div>
<v-row>
<v-col cols="12">
<v-select v-model="country" :items="countries" item-text="name" item-value="code"></v-select>
<v-btn @click="change">change by script to '{{getCountryCode()}}'</v-btn>
</vcol>
</v-row>
</v-container>
</v-app>
</div>
Another option is (Codepen here) the suggestion of Anurag Srivastava to use return-object
, I returned the object. However, it have some drawbacks, cause actually I am not able to properly change the value by code:
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: {
country: "c",
countries: [
{ code: "a", name: "Ameriga Fatela" },
{ code: "b", name: "Bolivia Grande" },
{ code: "c", name: "Comore Potentia" }
]
},
methods: {
getCountryCode() {
return "b"; // have no c.name here!
},
change() {
var newCode = this.getCountryCode();
this.country = newCode;
}
}
});
<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" />
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
<div id="app">
<v-app>
<v-container>
<div>current code is >{{country.code}}<</div>
<div>current name is >{{country.name}}<</div>
<v-row>
<v-col cols="12">
<v-select v-model="country" :items="countries" item-text="name" item-value="code" return-object></v-select>
<v-btn @click="change">change by script to 'b'</v-btn>
</vcol>
</v-row>
</v-container>
</v-app>
</div>
However, in both cases we should recalculate the country name. That is not good. Imagine to build the combobox we have to do a heavy operation... recalculating it each time is time-consuming and really not optimal....
Upvotes: 0
Reputation: 14413
You need to add return-object
prop to <v-select>
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: {
state: null,
selectedText: "",
states: [
{ value: "a", text: "alpha" },
{ value: "b", text: "beta" },
{ value: "g", text: "gamma" }
]
},
methods: {
change: (newValue) => {
// do something with the text
// "alpha", "beta", or "gama"
console.log(newValue.text);
}
}
});
<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"/>
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
<div id="app">
<v-app id="inspire">
<v-container fluid>
<label>my selected text is: {{state && state.text}}</label>
<v-row align="center">
<v-col cols="3">
<v-select :items="states" v-model="state" @change="change" item-text="text" return-object></v-select>
</v-col>
</v-row>
</v-container>
</v-app>
</div>
Edit: Ok so based on your approach, the solution would be to use the country code to find appropriate country object in the country list and set that.
Here is how you would solve it:
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: {
country: "c",
countries: [{
code: "a",
name: "Ameriga Fatela"
},
{
code: "b",
name: "Bolivia Grande"
},
{
code: "c",
name: "Comore Potentia"
}
]
},
methods: {
getCountryCode() {
return "b"; // have no c.name here!
},
change() {
var newCode = this.getCountryCode();
// Since we were getting objects when changing options, we must also set objects
this.country = this.countries.filter(country => country.code === newCode)[0];
}
}
});
<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" />
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
<div id="app">
<v-app>
<v-container>
<div>current code is >{{country.code}}<</div>
<div>current name is >{{country.name}}<</div>
<v-row>
<v-col cols="12">
<v-select v-model="country" :items="countries" item-text="name" item-value="code" return-object></v-select>
<v-btn @click="change">change by script to 'b'</v-btn>
</vcol>
</v-row>
</v-container>
</v-app>
</div>
Upvotes: 1
Reputation: 752
Your states
objects contain both value
and text
properties. If you change value
to key
v-select recognizes the change and you can access the text
property via this.state
. Like so:
new Vue({
el: "#app",
vuetify: new Vuetify(),
data: {
state: {},
selectedText: "",
states: [
{ key: "a", text: "alpha" },
{ key: "b", text: "beta" },
{ key: "g", text: "gamma" }
]
},
methods: {
change: (newValue) => {
// do something with the text
// "alpha", "beta", or "gama"
console.log(newValue); // Also returns text attribute instead of key
}
}
});
<div id="app">
<v-app id="inspire">
<v-container fluid>
<label>my selected text is: {{state}}</label>
<v-row align="center">
<v-col cols="3">
<v-select v-model="state" :items="states" @change="change"></v-select>
</v-col>
</v-row>
</v-container>
</v-app>
</div>
Upvotes: 0