VueJs drop-down first item not selected on initial load - vuejs2

I have a drop-down option working with an array of items. I want to add the first selection/option as Select a Site.
When the element is rendered, the drop-down does not show the Select a Site initially. The drop-down element does have the array in the drop-down options.
The first image shows the initial state of the drop-down (looks
empty, but its not)
The second image is when the drop-down element is
when selected.
How can I the drop-down working with the Select a Site shown as the first option?
<select id="ddSite" name="ddSite" class="form-control m-b-10" v-on:change="onChangeSite($event)" v-model="ddSite">
<option :value="null">-- Select a Site --</option>
<option v-for="option in sites" v-bind:value="option.SiteId">
{{ option.SiteName }}
</option>
</select>
new Vue({
el: '#app',
data: {
sites: [],
ddSite:""
},
mounted() {
axios.get("/api/sites/" + this.companyid)
.then(response => {
this.sites = response.data
});
},
methods: {
onChangeSite: function (e) {
var self = this;
var siteid = e.target.value;
var sitename = e.target.options[e.target.options.selectedIndex].text;
},

In your code, you're binding the select's value to ddSite.
The -- Select a Site -- option has a value of null, but your ddSite data starts off as an empty string.
In order to have that option selected initially, you must init ddSite as null:
new Vue({
el: '#app',
data: {
ddSite: null,
sites: [{
SiteId: 1,
SiteName: 'Google',
},
{
SiteId: 2,
SiteName: 'Facebook',
},
{
SiteId: 3,
SiteName: 'StackOverflow',
},
]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<select id="ddSite" name="ddSite" v-model="ddSite">
<option :value="null">-- Select a Site --</option>
<option v-for="option in sites" :value="option.SiteId">
{{ option.SiteName }}
</option>
</select>
</div>

Related

How can i get :key value in v-for loop in a variable?

In Vuejs, how can i get :key value which stores value from v-for loop in a dropdown. I am trying to get id of dropdown along with the name. I can get name using #change>event.target.value but is there any possibility to get key value?
Thanks
<select #change="checkFirst($event)" v-model="firstDropdownValue">
<option value="none" selected="selected"> Select one...</option>
<option
v-for="data in getCategoriesDetail"
:key="data.id" :
:value="data.name">{{data.name}}</option>
</select>
As per my understanding, You want to get the value of :key which is data.id of the selected option from the dropdown. If Yes, You can use v-model to get the whole object instead of just name and then you can filtered out the properties you want in the script.
Demo :
new Vue({
el: '#app',
data: {
getCategoriesDetail: [{
id: 1,
name: 'Option 1'
}, {
id: 2,
name: 'Option 2'
}, {
id: 3,
name: 'Option 3'
}, {
id: 4,
name: 'Option 4'
}],
firstDropdownValue: 'none'
},
methods: {
checkFirst() {
console.log('id : ' + this.firstDropdownValue.id)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<select #change="checkFirst" v-model="firstDropdownValue">
<option value="none">Select one...</option>
<option
v-for="item in getCategoriesDetail"
:key="item.id"
:value="item">{{ item.name }}</option>
</select>
</div>
You can simply use the v-model you use in your select !
And you should use the entire object in the :value instead of just the name :value="data" and then use it in the template as firstDropdownValue.name
new Vue({
el: "#app",
data: () => ({
firstDropdownValue: null,
getCategoriesDetail: [
{id:1, name: "foo"},
{id:2, name: "bar"},
{id:3, name: "baz"},
]
}),
methods: {
checkFirst(){
console.log(this.firstDropdownValue)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<select #change="checkFirst" v-model="firstDropdownValue">
<option value="none" selected="selected"> Select one...</option>
<option
v-for="data in getCategoriesDetail"
:key="data.id"
:value="data"
>{{data.name}}</option>
</select>
Selected value : {{firstDropdownValue && firstDropdownValue.name}}
</div>

Item undefined - by page load but later by select event work without problem

I need to set "message" on page load and later update it by select box from array in data. But by page load, the item is undefined - what make I wrong? Thank you for advice.
the code is as well on: https://repl.it/#DaBor/find#index.html
let vueApp = new Vue({
el: '#app',
data: {
selected: '1',
options: [
{id:1, projectNAME:"bobx", note:"note-bobx"},
{id:2, projectNAME:"danx", note:"note-danx"},
{id:3, projectNAME:"barb", note:"note-barb"},
],
message: "start"
},
methods: {
foo: function(){
var item = this.options.find(item => item.id === this.selected);
alert(item);
this.message = item.note;
},
},
mounted() {
this.foo();
},
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<select v-model="selected" v-on:change="foo" >
<option v-for="option in options" v-bind:value="option.id">
{{ option.projectNAME }}
</option>
</select>
<span>Selected id:{{ selected }}</span>
<br />
<span v-html="message"></span>
</div>
The find() callback compares item.id (a Number) to selected (a String):
var item = this.options.find(item => item.id === this.selected);
^ ^
Number String
Strict equality (===) compares both type and value. Since the two types are different in this case, the comparison would always be false, resulting in undefined being returned from find().
One solution is to convert selected to a Number, and use that to compare:
var selectedId = Number(this.selected);
var item = this.options.find(item => item.id === selectedId);
updated repl.it

Vue multiple select form independent from each other

I need a solution how to make as many select form as my option data length and each form must be independent from each other. It means that if i chooce selected value in one form it must do not overide selected value in others form. Also i need pre-set selected value in each form (for the first form it need to show selected first choice, for second = second choice and so on.)
var app = new Vue({
el: "#app",
delimiters: ["[[", "]]"],
data: {
selected: '',
options: [
{ id: 20 , supp_name: 'test1' },
{ id: 21 , supp_name: 'test2' },
{ id: 34 , supp_name: 'supertest' },
]
},
})
<div margin="20px" v-for='option in options'>
<form action="">
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.supp_name">
[[option.supp_name]]
</option>
</select>
<span>Chosen: [[selected]]</span>
</form>
</div>
It display 3 forms but when I make a choice in on one form it override all forms. How could it be fixed?
You will need as many selected references as there are forms.
For example
var app = new Vue({
el: "#app",
delimiters: ["[[", "]]"],
data: {
selected: [], // make selected an array
options: [{"id":20,"supp_name":"test1"},{"id":21,"supp_name":"test2"},{"id":34,"supp_name":"supertest"}]
},
watch: {
options: {
immediate: true,
handler (options) {
// initialise to the "supp_name" from options
this.selected = options.map(({ supp_name }) => supp_name)
}
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<div id="app">
<div v-for="(_, i) in selected">
<form action="">
<select v-model="selected[i]">
<option v-for="option in options" :value="option.supp_name">
[[ option.supp_name ]]
</option>
</select>
<span>Chosen: [[ selected[i] ]]</span>
</form>
</div>
<pre>selected = [[ selected ]]</pre>
</div>
This synchronises the selected array to be the same length as options then binds each form's <select> to the array index.

vuejs inline editing with select box option call issues

Good Day, I'm working on a simple inline editing functionality with Vuejs. Please have a look at this jsbin.
Users info. listed with Edit buttons, when clicked i turn those into input/select fields and populate corresponding options with helper methods.
My issue here is once i populate select options, my helper methods being called even if i change select value. How can i change this to load them only once and use them. Also, how can i validate current row fields as required when clicked on save button?
Try this.
new Vue({
el: '#app',
data: {
users: [
{name: 'Jhon', city:'Newyork', country: 'US', country_id:'23', city_id:'4'},
{name: 'Ali', city:'London', country: 'UK', country_id:'13', city_id:'33'},
{name: 'Raj', city:'Delhi', country: 'IN', country_id:'3', city_id:'11'},
],
cities: [
{id:'4', val:'Newyork', country_id:'23'},
{id:'33', val:'London', country_id:'13'},
{id:'11', val:'Delhi', country_id:'3'},
],
countries: [
{id:'23', val:'US'},
{id:'13', val:'UK'},
{id:'3', val:'IN'},
]
},
computed:{
citiesByCountry(){
return this.countries.reduce((acc, country) => {
acc[country.id] = this.cities.filter(c => c.country_id == country.id)
return acc
}, {})
}
},
methods: {
edit :function(obj){
this.$set(obj, 'editmode', true);
},
save : function(obj){
this.$set(obj, 'editmode', false);
},
cloneLast:function(){
var lastObj = this.users[this.users.length-1];
lastObj = JSON.parse(JSON.stringify(lastObj));
lastObj.editmode = true;
this.users.push(lastObj);
},
}
})
And change your template to this.
<td>
<span v-if="user.editmode">
<select v-model="user.city_id" required>
<option v-for="option in citiesByCountry[user.country_id]" :value="option.id">{{option.val}}</option>
</select>
</span>
<span v-else>{{user.city}}</span>
</td>
<td>
<span v-if="user.editmode">
<select v-model="user.country_id" required>
<option v-for="option in countries" :value="option.id">{{option.val}}</option>
</select>
</span>
<span v-else>{{user.country}}</span>
</td>
Working example.

Retrieving text of select element

When binding a <select> element using vue.js's v-model, how would you get the selected option text as opposed to the selected option value?
In HTML:
<select v-model="selected" options="myOptions"></select>
In JS:
myOptions: [{ text: 'Blue', value: '1' }, { text: 'Green', value: '2' }]
What I would want to retrieve is both the text 'Blue' as well as the value '1' by doing something like {{ selected.text }} or {{ selected.value }}. However, you can only do {{ selected }} which returns the selected value by default.
Ref: Vue.js guide for Dynamic Select Options
You can just use a filter, like this:
html:
<div id='vm'>
Formatted value:<b> {{city | cityFormatter}} </b><br/>
<br/>
<select v-model="city" options="cities"></select>
</div>
js:
var vm = new Vue({
el: '#vm',
data: {
city: 'city1',
cities: [{text: 'Toronto', value: 'city1'},
{text: 'Orleans', value: 'city2'}]
},
filters: {
cityFormatter: function(val) {
var newVal = '';
this.cities.map(function(el){
if (val == el.value){
newVal = el.value + ' ' + el.text;
}
});
return newVal;
}
}
});
Working example:
http://jsfiddle.net/qfy6s9Lj/9/
Actually, you could try combine jquery or just native js code
The solution with jQuery
html:
<div id='example'>
<select v-model="selected" options="myOptions"></select>
</div>
js:
var vm = new Vue({
el: '#example',
data: {
...
},
computed: {
selectedtext: {
cache: false,
//get selectedtext by jquery
get: function(){ return $(this.$el).find(":selected").text();}
}
},
});
The solution without jquery
html:
<div id='example'>
<select ref="ddl" v-model="selected" options="myOptions"></select>
</div>
js:
var vm = new Vue({
el: '#example',
data: {
...
},
computed: {
selectedtext: {
cache: false,
//get selectedtext directly
get: function(){
var ddl = this.$refs.ddl;
return ddl.options[ddl.selectedIndex].text;
}
}
},
});
Moreover, you could create a component for reusing logic and achieve the purpose of accessing the selected value by {{ selected.text }} or {{ selected.value }}.
An answer for Vue 2+
I was interested to come across this question as I'm currently evaluating Vue and React, and researching the comparative ease of getting current selection (not just dropdowns, but the UI generally).
What I found was that things have changed a lot since these posts in May-July 2015, when the latest version of Vue was 0.12. The JSFiddle in #swift's answer still works today because it pulls in Vue 0.12.
Using today's Vue, currently version 2.6, I found a solution that's relevant to people facing the same question today. It's interesting that using 2.6, the markup under discussion won't even get as far as initializing the options:
<select v-model="selected" options="myOptions"></select>
After digging into this, I found that although options is a valid HTML DOM property of the select element, and hence is accessible from JavaScript, it seems Vue no longer supports initializing it in markup like this. Instead, we add traditional HTML option elements. Per https://v2.vuejs.org/v2/guide/forms.html:
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<span>Selected: {{ selected }}</span>
On first sight, this change seems a backward step. But in fact, remembering that we can use v-for and v-bind, I think it makes things more flexible. To demonstrate why I think that, I will first show the example given at the same linked page:
HTML
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
JS
new Vue({
el: '...',
data: {
selected: 'A',
options: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
]
}
})
It can be seen in the HTML that this binds the selected value of the dropdown to the Vue instance's selected property (using v-model="selected"), binds the individual option values to the value of each option (using v-bind:value="option.value"), and finally binds the individual option texts to the text that will be displayed (using {{ option.text }}).
It's only a small step further to bind selected to a different option property, be it text, id or whatever properties your option object may have, or--and here's the thing--to the option object itself. Being able to access the option itself as the selected value means we can access all of its properties, rather than only the property we chose to bind to:
HTML
<div id='vm'>
<select id="ddl1" v-model="ddl1selecteditem">
<option v-for="option in options1" v-bind:value="option">
{{ option.txt }}
</option>
</select>
<span>selected item: text='{{ ddl1selecteditem.txt }}', id={{ ddl1selecteditem.id }}</span>
</div>
JS
var vm = new Vue({
el: '#vm',
data: {
options1: [
{ txt: 'One', id: 1 },
{ txt: 'Two', id: 2 },
{ txt: 'Three', id: 3}
],
ddl1selecteditem: {}
}
});
vm.ddl1selecteditem = vm.options1[0];