I write two inputs by same change function in Vue but when inputs changed, birthday_changed method works just on one input. What should I do to resolve this problem ?
<select v-model="client.day" id="birthday_day">
<option v-for="day in 31" :key=day :value="('0' + day).slice(-2)">{{ ("0" + day).slice(-2) }}</option>
</select>
<select v-model="client.year" #change="birthday_changed" id="birthday_year">
<option v-for="year in 81" :key=year :value="1320 + year"> {{ 1320 + year }} </option>
</select>
birthday_changed: function () {
alert('changed');
},
Just add your onchange #change event to the first select.
<select v-model="client.day" id="birthday_day" #change="birthday_changed" >
<option v-for="day in 31" :key=day :value="('0' + day).slice(-2)">{{ ("0" + day).slice(-2) }}</option>
</select>
const { createApp } = Vue;
const App = {
data() {
return {
client: { day: 1, year: 1}
}
},
methods: {
birthday_changed: function () {
alert('changed: ' + JSON.stringify(this.client));
},
}
};
createApp(App).mount("#app");
<div id="app">
<select v-model="client.day" #change="birthday_changed" id="birthday_day">
<option v-for="day in 31" :key=day :value="('0' + day).slice(-2)">
{{ ("0" + day).slice(-2) }}
</option>
</select>
<select v-model="client.year" #change="birthday_changed" id="birthday_year">
<option v-for="year in 81" :key=year :value="1320 + year"> {{ 1320 + year }} </option>
</select>
</div>
<script src="https://unpkg.com/vue#3/dist/vue.global.prod.js"></script>
Related
I have two select boxes, for the second the values can be disabled depending on the first
<div id="app">
<h2>Todos:</h2>
<select v-model="hoursDayB" #change='disableOptions()'>
<option v-for='dataB in hours' :value='dataB.id'>{{ dataB.name }}</option>
</select>
<select v-model="hoursDayE">
<option v-for='dataE in hours' :disabled="dataE.id < hoursDayB" :value='dataE.id'>{{ dataE.name }}</option>
</select>
</div>
new Vue({
el: "#app",
data: {
hours:[],
hoursDayB: 0,
hoursDayE: 0,
},
methods: {
getHoursDays: function(){
this.hours = JSON.parse('[{"id":"0","name":"00:00","disabled":1},{"id":"1","name":"01:00","disabled":1},{"id":"2","name":"02:00","disabled":1},{"id":"3","name":"03:00","disabled":1},{"id":"4","name":"04:00","disabled":1},{"id":"5","name":"05:00","disabled":1},{"id":"6","name":"06:00","disabled":1},{"id":"7","name":"07:00","disabled":1},{"id":"8","name":"08:00","disabled":1},{"id":"9","name":"09:00","disabled":1},{"id":"10","name":"10:00","disabled":0},{"id":"11","name":"11:00","disabled":0},{"id":"12","name":"12:00","disabled":0},{"id":"13","name":"13:00","disabled":0},{"id":"14","name":"14:00","disabled":0},{"id":"15","name":"15:00","disabled":0},{"id":"16","name":"16:00","disabled":0},{"id":"17","name":"17:00","disabled":0},{"id":"18","name":"18:00","disabled":0},{"id":"19","name":"19:00","disabled":0},{"id":"20","name":"20:00","disabled":0},{"id":"21","name":"21:00","disabled":0},{"id":"22","name":"22:00","disabled":0},{"id":"23","name":"23:00","disabled":0}]');
},
disableOptions: function(){
},
},
created: function(){
this.getHoursDays();
}
})
The problem that the values is disabled randomly
https://jsfiddle.net/hams123/1w6u8q4h/1/
The comparison was in string, so we must cast to integer
<div id="app">
<select v-model="hoursDayB" #change='disableOptions()'>
<option v-for='dataB in hours' :value='dataB.id'>{{ dataB.name }}</option>
</select>
<select v-model="hoursDayE">
<option v-for='dataE in hours' :disabled="(parseInt(dataE.id)) < (parseInt(hoursDayB))" :value='dataE.id'>{{ dataE.name }}</option>
</select>
</div>
https://jsfiddle.net/hams123/1w6u8q4h/7/
I'm trying to figure out how to do this in vue, I'm stuck trying to bind the value of the "selected" in the options.
In the simplified code below, I get exactly what I want, but only for the first product. It binds correctly with the first computed property:
<template>
<div>
<div v-for="index in 2" :key="index">
<select>
<option :selected="product1 === ''">Empty</option>
<option
v-for="(product, index) of products"
:key="index"
:selected="product1 === product.name"
>{{product.name}}</option>
</select>
</div>
</div>
</template>
<script>
// chosen products come from vuex store
computed: {
product1() {
return store.state.product1;
},
product2() {
return store.state.product2;
},
}
</script>
But then how can I change this to be automatic in the v-for loop, probably using the index?
What I need is actually a loop that will render this:
<template>
<div>
<select>
<option :selected="product1 === ''">Empty</option>
<option
v-for="(product, index) of products"
:key="index"
:selected="product1 === product.name"
>{{product.name}}
</option>
</select>
<select>
<option :selected="product2 === ''">Empty</option>
<option
v-for="(product, index) of products"
:key="index"
:selected="product2 === product.name"
>{{product.name}}
</option>
</select>
</div>
</template>
I've tried using something like:
:selected="`product${index}` === product.name"
but that gives a string, not the computed property value...
you can pass parameter to your computed property:
<template>
<div>
<div v-for="index in 2" :key="index">
<select>
<option :selected="getProduct(index) === ''">Empty</option>
<option
v-for="(product, index) of products"
:key="index"
:selected="getProduct(index) === product.name"
>{{product.name}}</option>
<script>
// chosen products come from vuex store
computed: {
getProduct() {
return index=>
store.state['product'+index];
},
}
</script>
You can put the selected products in an array and then access it by index:
computed: {
selectedProducts () {
return [store.state.product1, store.state.product2];
}
}
And then you can do :selected="selectedProducts[index] === product.name".
I want to set values as selected at initial loading of my page but I'm not able to set them.
Here is my HTML markup:
<select multiple id="access_rights">
<option value="default" disabled selected>Choose your options</option>
<option value="create">Create</option>
<option value="read">Read</option>
<option value="update">Update</option>
<option value="delete">Delete</option>
</select> <label>Select Access Rights</label>`
Now I want 'Create' and 'Update' as default selected at first loading of page.
How can I do that?
See Working Demo :
$(document).ready(function() {
$('select').material_select();
});
var selectedOptions=[
"create",
"update"
];
$.each(selectedOptions, function(i,e){
$("#access_rights option[value='" + e + "']").prop("selected", true);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<label for="access_rights">Select Access Rights</label>
<select id="access_rights" multiple>
<option value="default" disabled>Choose your options</option> <option value="create">Create</option> <option value="read">Read</option> <option value="update">Update</option> <option value="delete">Delete</option> </select>
Just use selected in create and update option. For Ex:-
<select multiple id="access_rights">
<option value="default" disabled>Choose your options</option>
<option value="create" selected>Create</option>
<option value="read">Read</option>
<option value="update" selected>Update</option>
<option value="delete">Delete</option> </select>
<label>Select Access Rights</label>
$( document ).ready(function() {
$(".select-wrapper").each(function() {
var wrapper = this;
$(this).find("ul>li").each(function() {
var li = this;
var option_text = $(this).text();
$(wrapper).find("select option:selected").each(function() {
var selected_text = $(this).text();
if(option_text == selected_text) {
//$(li).addClass("active selected");
//$(li).find("input").prop('checked', true);
$(li).click();
}
});
});
});
});
Using v-for, I am looping through a component. The component is for each client. In this component, I have same form for each client and when a select value is selected for the first component (client 1), I want to select this value for every client.
Do I need to pass the data to the root and create a single source of truth variable?
I tried setting up a basic version:
<div id="app">
<my-comp v-for="x in 2" v-bind:val="x"></my-comp>
</div>
Vue.component('my-comp', {
props: ['val'],
template: `
<div>
<div>
<label>Status</label>
<select :data-client="val" #change="statusChanged">
<option selected="" disabled="" value="0"></option>
<option value="xxx">Xxx</option>
<option value="yyy">Yyy</option>
<option value="zzz">Zzz</option>
</select>
</div>
</div>
`,
methods: {
statusChanged(e) {
var client = e.target.getAttribute('data-client')
if (client == 1) {
alert('set same value for client 2')
}
}
}
})
new Vue({
el: '#app',
})
Here is a fiddle: https://jsfiddle.net/w53164t2/
I considered a little bit after my original answer and have come up with something I think is a little bit more real world than the example fiddle provided in the original question; specifically it is easy to make all the selects reflect the same value if they are all using the same source value, however I expect in a real world scenario each component would be independently bound to a single client. Each client would want their individual value to change, with the one caveat that if a "master" client changed, then all non-master clients should change to the master client's value.
To that end, this might be a case where I think a component specific bus is appropriate. The master would emit an event when it's value changed and the the other clients would set their value with respect to the master.
console.clear()
const MyCompBus = new Vue()
Vue.component('my-comp', {
props: ['val', 'master'],
computed:{
selected:{
get(){return this.val},
set(v){
this.$emit('update:val', v)
if (this.master)
MyCompBus.$emit("master-updated", v)
}
}
},
methods:{
onMasterUpdated(newMasterValue){
if (this.master) return
this.selected = newMasterValue
}
},
created(){
MyCompBus.$on('master-updated', this.onMasterUpdated)
},
beforeDestroy(){
MyCompBus.$off('master-updated', this.onMasterUpdated)
},
template: `
<div>
<div>
<label>Status</label>
<select v-model="selected">
<option selected="" disabled="" value="0"></option>
<option value="xxx">Xxx</option>
<option value="yyy">Yyy</option>
<option value="zzz">Zzz</option>
</select>
</div>
</div>
`,
})
new Vue({
el: '#app',
data:{
masterValue: null,
clients:[
{id: 1, selectedValue: null, master: true},
{id: 2, selectedValue: null},
{id: 3, selectedValue: null},
{id: 4, selectedValue: null},
]
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<my-comp v-for="client in clients"
:val.sync="client.selectedValue"
:master="client.master"
:key="client.id">
</my-comp>
{{clients}}
</div>
Original Answer
Bind them all to the same value using v-model.
Vue.component('my-comp', {
props: ['value'],
computed:{
selected:{
get(){return this.value},
set(v){this.$emit('input', v)}
}
},
template: `
<div>
<div>
<label>Status</label>
<select v-model="selected">
<option selected="" disabled="" value="0"></option>
<option value="xxx">Xxx</option>
<option value="yyy">Yyy</option>
<option value="zzz">Zzz</option>
</select>
</div>
</div>
`,
})
And in the template:
<my-comp v-for="x in 2" v-model="selectedValue" :key="x"></my-comp>
Here is the updated fiddle.
If you want to stick with val as the property you can use .sync instead.
Vue.component('my-comp', {
props: ['val'],
computed:{
selected:{
get(){return this.val},
set(v){this.$emit('update:val', v)}
}
},
template: `
<div>
<div>
<label>Status</label>
<select v-model="selected">
<option selected="" disabled="" value="0"></option>
<option value="xxx">Xxx</option>
<option value="yyy">Yyy</option>
<option value="zzz">Zzz</option>
</select>
</div>
</div>
`,
})
And in the template:
<my-comp v-for="x in 2" :val.sync="selectedValue" :key="x"></my-comp>
Example fiddle.
If you want just one of them designated as a "master" select, then add a property that does so.
Vue.component('my-comp', {
props: ['val', 'master'],
computed:{
selected:{
get(){return this.val},
set(v){if (this.master) this.$emit('update:val', v)}
}
},
template: `
<div>
<div>
<label>Status</label>
<select v-model="selected">
<option selected="" disabled="" value="0"></option>
<option value="xxx">Xxx</option>
<option value="yyy">Yyy</option>
<option value="zzz">Zzz</option>
</select>
</div>
</div>
`,
})
And in the template:
<my-comp v-for="x in 5" :val.sync="selectedValue" :master="1 == x" :key="x"></my-comp>
Example fiddle.
You can see my case below
My vue component is like this :
<template>
<select class="form-control" :name="elementName" v-model="selected" :required="module === 'addProduct'" >
<option>Choose</option>
<option v-for="option in options" v-bind:value="option.id" >{{ option.name }}</option>
</select>
</template>
<script>
...
export default {
...
props: ['elementName', 'module'],
data() {
return {
selected: 'Choose'
};
},
...
};
</script>
The result is like this :
I don't select anything. I click button submit, the required not working. It not display the required
I try like this :
<option value="">Choose</option>
It works. But, when accessed first time, option choose not show
How can I solve this problem?
See their example: https://v2.vuejs.org/v2/guide/forms.html#Select
It doesn't display anything because you have: selected: 'Choose' but you have no option with value="Choose". (the value is the empty string, "Choose" is just the inner text of the option element).
Try this:
<template>
<select class="form-control" :name="elementName" v-model="selected" :required="module === 'addProduct'" >
<option disabled value="">Choose</option>
<option v-for="option in options" v-bind:value="option.id" >{{ option.name }}</option>
</select>
</template>
<script>
...
export default {
...
props: ['elementName', 'module'],
data() {
return {
selected: ''
};
},
...
};
</script>