VueJS and Drop down values - vue.js

Am I grabbing the value of the selection incorrectly in this Vue template form?
<select class="form-control" v-model="object.property">
<option selected="selected" value="Option 1">Option 1</option>
<option value="Option 2">Option 2</option>
</select>

You are binding the value of object.property to the select element correctly.
But, Vue is going to ignore the selected attribute on the first option element.
Here's the warning you will get if you try to use this template:
inline selected attributes on <option> will be ignored when using v-model. Declare initial values in the component's data option instead.
So, if you want the initial value of the select to be the first option, set object.property to that value when you define it in the data method.
Here's an example:
new Vue({
el: '#app',
data() {
return { object: { property: "Option 1" } }
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
<select class="form-control" v-model="object.property">
<option value="Option 1">Option 1</option>
<option value="Option 2">Option 2</option>
</select>
{{ object.property }}
</div>

Related

How to initialize a select with a selected value?

I have a parent component which calls a child component.
The parent :
<select-school-type class="form-control" required value="this.school_type_id" #selected="changeSchoolTypeId">></select-school-type>
The child :
<select v-on:change="$emit('selected', $event.target.value)" v-model="value">
<option value="">{{ placeholder }}</option>
<option :value="schoolType.id" v-for="(schoolType, index) in schoolTypes" :key="index">{{ schoolType.id }}</option>
</select>
The parent can "send" a value to the child (it is the props I called 'value'). And the child must add the "selected" option to the correct item.
I tried a lot of things without success. It is my first components.
value="this.school_type_id"
this is not defined in the template area:
<select-school-type class="form-control" required value="school_type_id" #selected="changeSchoolTypeId"></select-school-type>
If you pass the prop without using:, (value="school_type_id") school_type_id will be type of string. But here we like to pass the variable school_type_id → :value="school_type_id"
v-model in the child changes the prop value, which isn't allowed by vue. You should see a warning in the console: "Avoid changing props directly ....". Change it this way and perhaps it works as expected:
<select #change="$emit('selected', $event.target.value)" :selected="value">
<option value="">{{ placeholder }}</option>
<option :value="schoolType.id" v-for="(schoolType, index) in schoolTypes" :key="index">{{ schoolType.id }}</option>
</select>
If you like to use v-model instead, you can bind a computed getter/setter to it's value: https://v2.vuejs.org/v2/guide/computed.html#Computed-Setter
In the setter, you emit the new value:
computed: {
selectedValue: {
get() {
return this.value;
},
set(newValue) {
this.$emit('selected', newValue);
},
},
},
<select v-model="selectedValue">
<option value="">{{ placeholder }}</option>
<option :value="schoolType.id" v-for="(schoolType, index) in schoolTypes" :key="index">{{ schoolType.id }}</option>
</select>

VueJS: How do you provide a context variable to #change handler?

I have a select widget inside a loop:
<div v-for="(item, index) in items" :key="index">
<select #change="handleChange">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
</div>
When handleChange is triggered, I want to get following pieces of information:
index of the parent loop
value of the selected option
Above code only gives me #2. How do I get #1?
There are several ways that you can do this:
Solution 1: Bind index to an arbitrary HTML5 data- attribute
This approach involves using :data-index="index" on your select element, and then using the e.target.dataset.index to retrieve the bound index of the element
new Vue({
el: '#app',
data: {
items: ['lorem', 'ipsum', 'dolor', 'sit', 'amet']
},
methods: {
handleChange(e) {
console.log(e.target.value, e.target.dataset.index);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
<div v-for="(item, index) in items" :key="index">
<select #change="handleChange" :data-index="index">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
</div>
</div>
Of course, you can store the index as any other arbitrarily-named data- attribute, e.g. <select #change="handleChange" :data-abc="index"> and then simply accessing it in your JS using e.target.dataset.abc.
Solution 2: Pass index as an argument to the #click callback
This method involves passing $event and index as parameters to your handleChange callback. The $event variable in VueJS allows you to pass the original JS event to the handler:
new Vue({
el: '#app',
data: {
items: ['lorem', 'ipsum', 'dolor', 'sit', 'amet']
},
methods: {
handleChange(e, idx) {
console.log(e.target.value, idx);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
<div v-for="(item, index) in items" :key="index">
<select #change="handleChange($event, index)">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
</div>
</div>
for parent loop index,
<select #change="handleChange(index)">
for value of selected option, use v-model for two way binding

Vue.js v-bind:value to empty object

I have a dropdown that is populated with an array of objects.
<select v-model="selectedLeague" v-on:change="chooseLeague()">
<option v-for="league in model.leagues" v-bind:value="league">
{{ league.name }}
</option>
</select>
At initialization, selectedLeague is {}
I want to add a default option that is selected when the object is empty. I tried adding
<option disabled v-bind:value=null>Choose League</option>
But that will not work because it is never null. What can I add to check if the object is empty using data binding? I am using version 2.4.4 btw
Since selectedLeague is initially {}, you can use:
<option disabled v-bind:value="{}">Choose League</option>
Demo:
new Vue({
el: '#app',
data: {
selectedLeague: {},
model: {
leagues: [{name: 'leagueOne'},{name: 'leagueTwo'}]
}
},
methods: {
chooseLeague() { console.log('chooseLeague()', this.selectedLeague); }
}
})
<script src="https://unpkg.com/vue#2.4.4"></script>
<div id="app">
<select v-model="selectedLeague" v-on:change="chooseLeague()">
<option disabled v-bind:value="{}">Choose League</option>
<option v-for="league in model.leagues" v-bind:value="league">
{{ league.name }}
</option>
</select>
</div>
Note: you can also add hidden if you want to hide that option from the dropdown:
<option disabled v-bind:value="{}" hidden>Choose League</option>

How can I add class="required" in the following select v-model?

<div v-for="value in day" class="checkboxFour">
<input type="checkbox" id="need" value="value.val" v-model="value.selected" style="width: 10%!important;">
<label for="need" style=" width: 30%!important;">{{value.name}}</label>
<select v-model="value.from" class="select-style">From
<option value="08:00">08.00</option>
<option value="12:00">12.00</option>
<option value="20:00">20.00</option>
<option value="23:00">23.00</option>
</select>
<select v-model="value.to" class="select-style">To
<option value="08:00">08.00</option>
<option value="12:00">12.00</option>
<option value="20:00">20.00</option>
<option value="23:00">23.00</option>
</select>
<br>
</div>
This is select option. When I use required="". I am getting getAttribute error. How can I able to correct the same?
Also how can I use selected in the following case? My target is select a particular value previously and then user can change according to his need? Please help me to obtain the same?
The required attribute is a boolean (an not a class). You don't need to give it a value; if it is present in the select tag, the select is required.
You can also bind it to a boolean value to change whether the select is required.
new Vue({
el: '#app',
data: {
isRequired: false
}
});
[required] {
outline: thin solid red;
}
<script src="//unpkg.com/vue#latest/dist/vue.js"></script>
<div id="app">
<select required>
<option>An option</option>
</select> This one is always required
<div>
<select :required="isRequired">
<option>Whatever</option>
</select>
<input type="checkbox" v-model="isRequired"> Is Required: {{isRequired}}
</div>
</div>
As it mentioned in Vue.JS docs you can use v-bind:class to achieve what you wanted:
<select v-model="value.from" v-bind:class="{required: isRequired}">
which required is data, computed field in your app/component.
Update 1:
new Vue({
el: "#myApp",
data: {
// you should define a variable in your data
isRequired: false
},
methods: {
doSomething: function(){
this.isRequired = true;
}
}
});

How to return boolean and not string when using select?

I have this:-
<div class="form-group">
<label for="">Allow Multiple</label>
<select class="form-control" v-model="allowMultiple">
<option value=true>Yes</option>
<option value=false>No</option>
</select>
</div>
I set allowMultiple=true when I initialize it, but when I select No then allowMultiple='false' So its no longer a Boolean but a String? How to get it to be Boolean?
In HTML, if you set attribute value in a tag, the value will be default type--string.So you can use vue v-model to bind it to other type value, for example, Boolean, Number and etc.
Following code is working, the result is what you want
new Vue({
el:'#app',
data: {
allowMultiple: false
},
methods: {
print: function () {
alert(this.allowMultiple);
}
}
})
<div class="form-group" id='app'>
<label for="">Allow Multiple</label>
<select class="form-control" v-model="allowMultiple" #change='print'>
<option :value='true'>Yes</option>
<option :value='false'>No</option>
</select>
</div>
<script src="https://unpkg.com/vue#2.4.2/dist/vue.min.js"></script>
Here is a way to do it in Vue.
Instead of hard coding your options in html. Use the Vue way, set an array of options in your Vue data then use v-for to render all the options from the array.
Each option should have 2 properties: a text and a value. The value should be the boolean you are looking for.
Now whenever the user changes the selected option, it will always be boolean.
new Vue({
el: '#app',
data: {
allowMultiple: true,
options: [
{text: 'Yes', value: true},
{text: 'No', value: false},
],
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
<div class="form-group">
<div>Allow multiple: {{allowMultiple}} [Type: {{typeof allowMultiple}}]</div><br>
<label for="">Allow Multiple</label>
<select class="form-control" v-model="allowMultiple">
<option v-for="option in options" :value="option.value">{{option.text}}</option>
</select>
</div>
</div>
The easier and quicker way I found that works for me is this:
<select id="selected" v-model="item.selected">
<option :value=0>No</option>
<option :value=1>Yes</option>
</select>
Maybe it's useful for anyone.
Try this:
<option value=1>Yes</option>
<option value=0>No</option>