Issues binding Dropdown selection with VueJs2 - vue.js

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>

Related

VueJS Multiple Dropdowns - Rendered Options depends on first selected value

I am facing some issues here trying to render a second select dropdown. I currently am fetching data with axios from an API. The options of the second select dropdown is depending on what is selected in the first dropdown.
The JSON looks like this:
{
"citizens": [
{
"id": 1,
"name": "Boy1",
"contact": [
{
"id": "1",
"name": "Mother1"
},
{
"id": "2",
"name": "Father1"
}
]
},
{
"id": 2,
"name": "Boy2",
"contact": [
{
"id": "1",
"name": "Mother2"
},
{
"id": "2",
"name": "Father2"
}
]
}
],
}
Based on the JSON, In the first select dropdown, I am rendering correctly {{citizen.name}}, which in this case will be: Boy1 and Boy2.
But, in the second dropdown, I want to render the citizen.contact.name available in the first selected dropdown (v-model). For example, I choose Boy1, the second dropdown should have Mother1 and Father1. If I select Boy2, then it should be Mother2 and Father2.
<select v-model="selectOne">
<option v-for="citizen of citizens" :key="citizen.id">{{citizen.name}}</option>
</select>
<select v-model="selectTwo">
<option>Mother1</option>
<option>Father1</option>
</select>
I am returning data() for citizens: [] and selectOne: "". I tried adding v-models on both select tags (selectOne and selectTwo) and a computed property:
computed: {
selectTwo() {
return console.log(this.selectOne);
},
},
Just bind the whole selected citizen from your select, for example called selected. Use the value of the whole citizen object, then you can in your second select iterate through selected.contact:
<select v-model="selected">
<option :value="citizen" v-for="citizen of citizens" :key="citizen.id">{{citizen.name}}</option>
</select>
<!-- Maybe need a v-model here too so you can keep track of choice -->
<select v-model="selectedContact">
<option v-for="contact of selected.contact" :key="contact.id">{{contact.name}}</option>
</select>
and to the script, of course add selected (and selectedContact) as variable.
If you want to keep your first select as a string and not bind the whole object, you can as you attempted use a computed property like:
contacts() {
return this.selected ? this.citizens.find(x => x.name === this.selected).contact : []
}
and template:
<select v-model="selected">
<option v-for="citizen of citizens" :key="citizen.id">{{citizen.name}}</option>
</select>
<select v-model="selectedContact">
<option v-for="contact of contacts" :key="contact.id">{{contact.name}}</option>
</select>

Vue: getting default value for select when using objects

I have a select where I am trying to set the :selected value to data from my server on page load. All the data is accessible but I am not sure what I am missing. My prop customer is an object that is passed in from the parent and comes from the backend. The value of customer.state is the abbreviated state , so "CA" for example. I tried doing :selected="this.customer.state" but that didn't work either.
data() {
return {
this.states = [
{text: "California", value: "CA"},
{text: "New Jersey", value: "NJ"},
//etc
],
}
},
props: {
customer: {type: Object}
}
<select name="state" autocomplete="address-level1" #change="optionDropdown">
<option v-for="x in optionsReturned" :value="x.value" :selected="???">
{{ x.text }}
</option>
</select>
value of selected must be true when the currently looped option is equal to customer's state (and false otherwise): :selected="customer.state === x.value"

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

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

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

Pass selected value to vuejs function

How can I pass selected value to a vuejs function?
v-model won't help I guess.
I need to set values for the filter after
item: items | orderBy sortKey reverse
where reverse and sortKey are dynamic values.
html
<select class="sort-filter" v-on="change: sortBy(???)">
<option value="title asc">Title (A-Z)</option>
<option value="title desc">Title (Z-A)</option>
<option value="price asc">Price (Min. - Max.)</option>
<option value="price desc">Price (Max. - Min.)</option>
</select>
js
methods: {
sortBy: function (sortKey) {
console.log(sortKey)
}
}
You have several ways to do it.
Edit: Improved 2)
It is possible to use v-model just like in 2) but instead of using the value directly in your orderBy filter, you can use computed properties
computed: {
sortKey: {
get: function() {
return this.sorting.split(' ')[0]; // return the key part
}
},
sortOrder: {
get: function() {
return this.sorting.split(' ')[1]; // return the order part
}
}
}
This way, sortKey and sortOrder will be available like a normal property in you filter:
v-repeat="items | orderBy sortKey sortOrder"
1) Use javascript event:
If you don't specify any parameter, the native event object will be passed automatically
<select class="sort-filter" v-on:change="sortBy">
You can then use it like this:
methods: {
sortBy: function(e) {
console.log(e.target.value);
},
}
2) Using v-model
You can add the v-model directive
<select name="test" v-model="sorting" v-on:change="sortBy">
This way the sorting value will be updated on every change.
You can add this value in the data object of you ViewModel to be more clear:
data: {
sorting: null // Will be updated when the select value change
}
You can then access the value like in your method:
methods: {
sortBy: function() {
console.log(this.sorting);
},
}
If you just need to update the sortKey value, this method is not even necessary.
3) Other weird way
You can apparently use your model value as a parameter.
<select name="test" v-model="sortKey" v-on:change="sortBy(sortKey)">
This is working but I don't really see the point.
methods: {
sortBy: function(sortKey) {
console.log(sortKey);
},
}
This should work if you want to loop with dynamic values and can not use v-model
<select name="option" v-on:change="selectedOption($event.target.value)">
<option value="0">SELECT</option>
<option v-for="i in 10" :value="i">{{ i }}</option>
</select>
If you want to pass selected value to a vuejs function, Please do the following :
you need to use v-model directive in select tag as v-model = variableName
pass that variable as parameter like #on-change=sortBy(variableName);
So your code will look like :
<select class="sort-filter" v-model="sortingVariable" #on-change="sortBy(sortingVariable)">
<option value="title asc">Title (A-Z)</option>
<option value="title desc">Title (Z-A)</option>
<option value="price asc">Price (Min. - Max.)</option>
<option value="price desc">Price (Max. - Min.)</option>
</select>
try
<select name="option" #change="myFunction($event.target.value)">
<option v-for="item in list" :value="item.code" :key="item.code">{{ item.name }}</option>
</select>
// Function
myFunction(value) {
console.log(value);
}