Get text from select element using vue 2, when options has value attribute - vuejs2

I have a select element within a vue component that looks like this:
<template>
<select v-model="item.value" >
<option value="1">A</option>
<option value="2">B</option>
</select>
<div>
You selected {{item.text}} with a value of {{item.value}}
<div>
</template>
<script>
export default {
data() {
return {
item: {
text: '',
value: 0
}
}
}
}
</script>
If I make a selection, on A, I get a value of 1, if I make a selection on B. I get a value of 2. So item.value will be populated. How do I fill up item.text?
If I remove the value attribute from the options, I get the answer, but now my value wouldn't be populated.

I'd recommend using an array of objects that hold both the value and text for each <option>. For example
data() {
return {
// ...
options: [
{ value: 1, text: 'A' },
{ value: 2, text: 'B' }
]
}
}
Then you can use a v-for to iterate this list and simply bind the selected item with v-model
<select v-model="item">
<option v-for="opt in options" :key="opt.value" :value="opt">
{{opt.text}}
</option>
</select>
See https://v2.vuejs.org/v2/guide/forms.html#Select-Options

Related

Issues binding Dropdown selection with VueJs2

I have a dropdown list containing document types, in which I need the selected type to be stored in a data property, specifically the type.name , so I can reference it in a child component. However, my choice is not being stored. Am I going about this wrong?
Expected Result: type.name is available to me in a data variable.
<b-select
:v-model="documentType" >
<option
v-for="type in group.documentTypes"
:key="type.id"
:value="type.id"
:v-model="selected"
>
{{(type.name)}}
</option>
</b-select>
data() {
return {
waiting: {},
timer: null,
selected: ''
}
},
Just put your v-model on your select-tag. With an input-event you can pass your selection to methods.
UPDATE FROM HERE: There you can work with the name you've selected and pass it to your child.vue or do whatever you want.
But be aware - don't write :v-model it's only v-model !
CODE
TEMPLATE
<select v-model="selected_DT" #input="storeSelect(selected_DT)>
<option v-for="type in documentTypes" :key="type.id">
{{type.name}}
</option>
</select>
SCRIPT:
data() {
return {
selected_DT: null,
documentTypes: [
{"id": 1, "name": "Test1"},
{"id": 2, "name": "Test2"},
{"id": 3, "name": "Test3"},
]
}
},
methods: {
storeSelect(selected_DT) {
console.log(selected_DT) //it's selected name you can pass to your child.vue
}
},
You are very close but your v-model needs to be placed on your select html element. Then when one of the options are selected the value of the option will be passed to it
<select v-model="selected">
<option
v-for="type in group.documentTypes"
:key="type.id"
:value="type.id">
{{type.name}}
</option>
</select>

Vue.js custom component with HTML <select> and v-model (W3C compliant)

I'm new to Vue.js (using Nuxt.js) and what I'm trying to achieve is to have a Select component that I can reuse everywhere and is W3C compliant.
With the help of #Jasmonate answers, I managed to create this component, it's working. But the value attribute is still visible in the source code and so isn't W3C compliant. Maybe the problem is coming from somewhere else in the project ?!
Parent component
<custom-select
:options="options"
v-model="selectedOption"
></custom-select>
<span>Selected : {{ selectedOption }}</span>
<script>
data() {
return {
selectedOption: "A",
options: [
{ label: "One", value: "A" },
{ label: "Two", value: "B" },
{ label: "Three", value: "C" }
],
};
}
</script>
custom-select.vue
<template>
<select :value="value" #input="clicked">
<option
v-for="option in options"
:key="option.label"
:value="option.value"
>
{{ option.label }}
</option>
</select>
</template>
<script>
export default {
props: {
value: {
required: true
},
options: {
type: Array,
required: true
}
},
methods: {
clicked($event) {
this.$emit("input", $event.target.value);
}
}
};
</script>
I read those documentation pages:
Form Input Bindings
Components Basics
And also looked around the web to find example of v-model in a custom component, but it's always about the input tag. The only example I found about a custom select with v-model isn't actually a select tag, like the Vue Select plugin or this thread on StackOverflow.
v-model is syntax sugar. By default, the value is a prop that has the name value, and it changes (two-way-binding) whenever the event input is emitted.
Also, v-model is bound on the select element, not option.
Your code can be modified as such:
<template>
<select :value="value" #input="clicked">
<option
v-for="option in options"
:key="option.label"
:value="option.value"
>
{{ option.label }}
</option>
</select>
</template>
<script>
export default {
props: {
value: {
required: true
},
options: {
type: Array,
required: true
}
},
methods: {
clicked($event) {
this.$emit('input', $event.target.value);
}
}
};
</script>
Documentation here: https://v2.vuejs.org/v2/guide/components.html#Using-v-model-on-Components
You can also change the prop name and event name that v-model uses, see: https://v2.vuejs.org/v2/guide/components-custom-events.html#Customizing-Component-v-model

VueJS show multiple input fields conditionally

I have a 'Add' button which adds a select box and when I select a value in the select box I want to display an input field so every time I click 'Add' it should show a select box and when I select a value in it I would like to display an input field.
I know I could use a flag 'selected' but when I already add one select box this would change the flag to true and show the input field immediately after I click 'Add' but I want the input field to show only when a value is selected.
<template>
<button #click="onBtnClick">Add<button>
<select>...</select> # This gets added when 'Add' button is clicked
<input v-if="selected" type="text" /> # This should show when a value is selected.
<select>
</template>
data(){
return {
selected: false
}
},
methods: {
onValueSelected(){
this.selected = true
}
}
Do you have any ideas how I could accomplish this?
Use v-for and push new fields onto the collection at will.
new Vue({
el: '#app',
data() {
return {
goods: []
}
},
methods: {
addSelect() {
let item = {
id: this.goods.length,
menus: [
{ value: '', text: '- select -' },
{ value: 1, text: 'Item 1' },
{ value: 2, text: 'Item 2' },
{ value: 3, text: 'Item 3' }
],
input: {
show: false
}
};
this.goods.push(item);
},
showInput(item, e) {
item.input.show = e.currentTarget.selectedIndex > 0;
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button #click="addSelect">Add to cart</button>
<div v-for="item in goods" :key="item.id" class="goods">
<select #change="showInput(item, $event)">
<option
v-for="opt in item.menus"
:key="opt.key"
value="opt.value">
{{opt.text}}
</option>
</select>
<input v-if="item.input.show" type="text" value="0" />
</div>
</div>
I figured out that I can render a new component and pass it props. Everytime a new component is rendered it gets selected flag as false by default and I can change it then by selecting a value in the select box.
<b-form-group
v-if="element.elementName === 'Some value'"
label="Select field *:"
label-for="benefitSelectField">
<SalaryField :element="element" />
</b-form-group>
SalaryField component
<template>
<div>
<select #change="onValueSelected" ></select>
<input v-if="selected" type="text" />
</div>
</template>
<script>
export default {
props: {
element: Object
},
data(){
return {
selected: false,
}
},
methods: {
onValueSelected() {
this.selected = true
}
}
}
</script>

How to get index data from object used in v-for in select

I have a component involving a select element. Below, opts is an array of objects.
Vue.component('atcf-select', {
props: [
'opts',
],
data() {
return {
element_index: '',
};
},
template: `
<div>
<select #change="onChange(opt,index)">
<option v-for="(opt,index) in opts">
{{ opt.text }} {{opt.index}}
</option>
</select>
</div>
`,
methods: {
onChange(opt,index) {
//Do something with opt and index...
}
}
};
The problem is obviously I cannot get the selected opt object and its index, and use it as a parameter for onChange method. What is the correct way to get the selected option's index and object?
You won't be able to pass the opt or index values to the change listener on the select element because it is outside the scope of the v-for.
If you don't specify any parameters for the onChange handler, Vue will implicitly pass an event object. From there, you can get the selectedIndex value via e.target.selectedIndex.
Here's an example:
new Vue({
el: '#app',
data() {
return {
opts: [
{ value: 'a', text: 'A' },
{ value: 'b', text: 'B' },
{ value: 'c', text: 'C' },
]
}
},
methods: {
onChange(e) {
let index = e.target.selectedIndex;
let option = this.opts[index];
console.log(index, option);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.8/vue.min.js"></script>
<div id="app">
<select #change="onChange">
<option v-for="(opt, index) in opts" :key="index" :value="opt.value">
{{ opt.text }}
</option>
</select>
</div>
You can use v-model
{{ option.value }} - {{ option.text }}
Index of {{valeureSelectionnee}} is : {{ IndexValeureSelectionnee }}

How can I add condition on v-model select ? vue.js 2

My vue component is like this :
<template>
<select class="form-control" v-model="selectedProvince"="level === 'province'" v-model="selectedProvince"="level === 'city'">
<option value="">Choose</option>
<option v-for="option in options" v-bind:value="option.id" >{{ option.name }}</option>
</select>
</template>
<script>
export default {
props: ['level'],
data() {
return {
selectedProvince: '',
selectedCity: '',
};
},
...
};
</script>
Select provinces and cities have 1 select. It is differentiated by level. I want to add condition
If level = province, it will run v-model = "selectedProvince"
If level = city, it will run v-model = "selectedCity"
I tried like the code above, but from the writing, it seems it is still wrong
How can I do it correctly?
Setting aside the issue that it seems odd that you would have two separate types of information in the same select, you would probably want to derive your values using computed values instead of what you're trying.
data(){
return {
selectedOption: null,
level: "province"
}
},
computed:{
selectedProvice(){
if (this.level === "province")
return this.selectedOption
else
return null
},
selectedCity(){
if (this.level === "city"
return this.selectedOption
else
return null
}
}
Then use selectedOption for your model.
<select class="form-control" v-model="selectedOption">