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>
Related
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>
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"
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
I have form and select components.
In fact things are simple: I need two binding model.
The parent component:
Vue.component('some-form', {
template: '#some-form',
data: function() {
return {
countryNameParent: ''
}
}
});
The child component with items:
Vue.component('countries', {
template: '#countries',
data: function () {
return {
items: {
"0": {
"id": 3,
"name": "Afghanistan"
},
"1": {
"id": 4,
"name": "Afghanistan2"
},
"2": {
"id": 5,
"name": "Afghanistan3"
}
},
countryName: ''
}
},
props: ['countryNameParent'],
created: function() {
var that = this;
this.countryName = this.countryNameParent;
},
methods: {
onChange: function (e) {
this.countryNameParent = this.countryName;
}
}
});
I'm using v-model to incorporate components above.
Templates like this:
<template id="some-form">
{{ countryNameParent }}
<countries v-model="countryNameParent"></countries>
</template>
<template id="countries">
<label for="">
<select name="name" #change="onChange" v-model="countryName" id="">
<option value="0">Select the country!</option>
<option v-for="item in items" v-bind:value="item.name">{{ item.name }}</option>
</select>
</label>
</template>
My target is getting data in parent component to send it to server (real form is much bigger), however I can't get the value of the countryName in countryNameParent. Moreover, Parent should setting data in successor if not empty.
Here you go link where I've been attempting to do it several ways (see commented part of it).
I know that I need to use $emit to set data correctly, I've even implemented model where I get image as base64 to send it by dint of the same form, hence I think solution is approaching!
Also: reference where I've built sample with image.
Here is your countries component updated to support v-model.
Vue.component('countries', {
template: `
<label for="">
<select v-model="countryName">
<option value="0">Select the country!</option>
<option v-for="item in items" v-bind:value="item.name">{{ item.name }}</option>
</select>
</label>
`,
data: function () {
return {
items: {
"0": {
"id": 3,
"name": "Afghanistan"
},
"1": {
"id": 4,
"name": "Afghanistan2"
},
"2": {
"id": 5,
"name": "Afghanistan3"
}
},
}
},
props: ['value'],
computed:{
countryName: {
get() { return this.value },
set(v) { this.$emit("input", v) }
}
},
});
v-model is just sugar for setting a value property and listening to the input event. So to support it in any component, the component needs to accept a value property, and emit an input event. Which property and event are used is configurable (documented here).
I am able to populate the value to the dropdown as under
app.js
export class App {
constructor() {
this.countryCollection = [
{
"CountryID": "1",
"CountryName": "Japan"
},
{
"CountryID": "2",
"CountryName": "USA"
},
{
"CountryID": "3",
"CountryName": "Canada"
},
{
"CountryID": "4",
"CountryName": "Sweden"
}
];
}
}
app.html
<template>
<h2>
<select>
<option value="">-Choose Country-</option>
<option value="${country.CountryID}"
repeat.for="country of countryCollection">${country.CountryName}</option>
</select>
</template>
But to get the selected Country ID on Change event of the drop down ?
add a selectedCountryId to the app.js and then change the select to
<select value.bind="selectedCountryId">
<option model.bind="null">-Choose Country-</option>
<option model.bind="country.CountryID"
repeat.for="country of countryCollection">${country.CountryName}</option>
</select>
which will bind the country id that has been selected to the selectedCountryId property of your .js file. This is pulled straight from their documentation here.