I have a computed setter:
rating: {
get() {
return this.$store.state.rating;
},
set(value) {
console.log(value);
this.$store.commit('updateFilter', {
name: this.name,
value
});
}
}
This is linked to my rating like so:
<label>
<input type="checkbox" :value="Number(value)" v-model="rating">
{{ index }}
</label>
I expect the computed setter to log an array because when I use a watcher to watch for changes on the rating model I am getting an array.
Except whenever I use a computed setter like above it simply outputs true when a checkbox is selected or false when they are all deselected.
What is going on here, should I just be getting an array just as like with a watcher?
v-model has somewhat "magical" behavior, particularly when applied to checkboxes. When bound to an array, the checkbox will add or remove the value to/from the array based on its checked state.
It is not clear in your example what value is in Number(value). It should be a value that you want included in the array when the box is checked.
Taking the example from the Vue docs linked above, I have modified it to use a computed, and it works as you might expect, with the set getting the new value of the array.
new Vue({
el: '#app',
data: {
checkedNames: []
},
computed: {
proxyCheckedNames: {
get() {
return this.checkedNames;
},
set(newValue) {
this.checkedNames = newValue;
}
}
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>
<div id="app">
<input type="checkbox" id="jack" value="Jack" v-model="proxyCheckedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="proxyCheckedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="proxyCheckedNames">
<label for="mike">Mike</label>
<br>
<span>Checked names: {{ checkedNames }}</span>
</div>
Related
I was wondering which is the best practise to trigger input validation in Vue JS, using events such as onchange, keyup or having watchers on each property? Let`s assume that you only have around 20 inputs to deal with.
As you said you might have n number of inputs in your form on which you want to add validation. I think watcher is a good feature to use as it will update every time any changes happen in the form data.
In your data object, You can create one formData object which will contain all the input field properties and then you can put a watcher on formData.
Live Demo :
var App = new Vue({
el: '#app',
data() {
return {
formData: {
name: 'Alpha',
age: 30
}
}
},
watch: {
'formData': {
deep: true,
handler(val) {
console.log(val)
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<form>
<label for="name">Name
<input id="name" type="text" v-model="formData.name">
</label>Age
<label for="age">
<input id="age" type="number" v-model="formData.age">
</label>
</form>
</div>
I have tried all that I have read in other questions and they did not answer me the problem.
I have a checkbox like this in a list
<input type="checkbox" v-model="selected" :value="post.rut">
I have the model defined like this:
data: function() {
return {
selected: []
}
}
The problem is that If I add checked as default.. it does not change at all I mean it keeps the checkbox not checked
<input type="checkbox" v-model="selected" :value="post.rut" checked>
If I remove the v-model, it works BUT I can not send the value to the controller because I need the v-model to bind so I wonder how can I set as default checked in that checkbox input like that?
Thanks
you have the input value as post.rut you can put it in selected array in data like :
data: function() {
return {
selected: [this.post.rut]
}
}
If you already know which field you want to selected based on the post you can do like so:
data: function() {
return {
selected: [this.post.rut]
Here is a working example of what you asked for.
Note: You need not use v-model and :value at the same time since v-model itself is a two way binder.
var app = new Vue({
el: '#app',
data() {
return {
selected: true
};
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input type="checkbox" v-model="selected"/>
</div>
I'm trying to display a 2000.00 in an input field in vuejs but it strips the .00.
<div id="app">
<input
class="form-control"
type="number"
v-model="solicitorsFees"/>
</div>
new Vue({
el: "#app",
data: {
solicitorsFees: 2000.00,
},
})
How do I get the input field to display 2000.00?
jsfiddle
I can do this with a calculated property. But I need to apply this to multiple input fields.
solicitorsFeesDecimal: function(){
return(this.solicitorsFees.toFixed(2))
},
<input class="form-control" type="number" v-model="solicitorsFeesDecimal"/>
Solution:
<input class="form-control" type="number" :value="(this.solicitorsFees).toFixed(2)"/>
The appropriate solution is to use a computed property with a custom getter and setter, as well as using the v-model.number modifier:
Template
<div id="app">
<input
class="form-control"
type="number"
v-model.number="solicitorsFeesDisplay"/>
</div>
Script
new Vue({
el: "#app",
computed: {
solicitorsFeesDisplay: {
get: function() {
return this.solicitorsFees.toFixed(2)
},
set: function(newValue) {
this.solicitorsFees = newValue
}
}
},
data() {
return {
solicitorsFees: 2000.00
}
},
})
See a working example on CodeSandbox.
you should you step in input field:
<input type="number" v-model="solicitorsFees" step="0.01">
This solves the problem:
<input class="form-control" type="number" :value="(this.solicitorsFees).toFixed(2)"/>
You can simply use parseFloat and toFixed together to define the number of decimal places you want.
v-model= parseFloat(solicitorsFees).toFixed(2)
Also, another suggestion is to make the data object as a function, as in your fiddle you are using an object.
data () {
return {
solicitorsFees: 2000.00
}
}
I am having two components and i am trying to update the component and i am trying to change value of property based on the checkbox checked or unchecked. I am unable to change the value of the property.
Here is my code:
ComponentA.vue
**Template**
<div class="column" v-for="car in cars">
<label class="label">
<input type="checkbox" v-model="carsSelected" #change="onChange" >
{{ car }}
</label>
</div>
**Script**
data () {
return {
carsSelected: {},
cars: {
hyundai,
maruthi,
audi,
}
}
...
onChange(){
this.$emit('input', this.carsSelected) .---> For updating
}
ComponenrB.vue
<component-a v-model="fourWheeler.brands" />
...
fourWheeler: {}
And here is how fourWheeler.brands looks like:
**It is an object**
{
hyundai: false,
maruti: false,
audi: true,
}
I want to change the values of the car brands ie fourWheeler.brands based on checked or unchecked, if checkbox is unchecked then false, if it is checked then true. Please let me know how to update the values and better way of binding.
Since the checkbox only indicates if it is selected or not, you can't select multiple values with just one checkbox, however you can use your cars object to render the options:
<template>
<main>
<label v-for="(value,key) in cars" :key="key" :for="key">
{{key}}
<input type="checkbox" :id="key" v-model="cars[key]" #change="onChange"/>
</label>
</main>
</template>
<script>
export default {
data(){
return {
cars: {
hyundai:false,
maruthi:false,
audi:false,
}
}
},
methods:{
onChange(){
console.log(this.cars)
}
}
}
</script>
As you can see what I'm doing is iterating through the cars properties and showing a checkbox for each of the properties (each car) and then v-model is changing the specific property of the cars object, so if you do a console.log of the cars object in the onChange now you see the cars object with the selections. Worth notice that I changed the cars object so it holds the car names and true/false for selected.
I have a list of checkboxes:
<ul>
<li v-for="system in payment_systems">
<input type="checkbox" :id="'ps-' + system.id" v-bind:value="system" v-model="checked_payment_systems">
<label :for="'ps-' + system.id">{{ system.translated.name }}</label>
</li>
</ul>
And I need to store checked items to Vuex so I use computed properties like this:
computed: {
checked_payment_systems: {
get() {
return this.$store.state.program.payment_systems;
},
set(payment_systems) {
console.log(payment_systems)
}
}
},
The problem is that in setter I get only true/false instead of object or array of objects.
the computed property you defined v-models with an input value. the set property will be called on with the input value.
in your example, you are binding the same get-set to all of your checkboxes. it should be done differently.
if i where you, i would remove the v-model and manually declare a function to happen onchange and a value, and pass them the a key, yo get the specific value in my object.
i made for you an example: https://jsfiddle.net/efrat19/p87ag0w3/1/
const store = new Vuex.Store({
state: {
program:{
payment_systems:{'paypal':false,'tranzila':false},
}
},
mutations:{
setPayment(state,{system,value}){
state.program.payment_systems[system]=value;
}
},
actions:{
setPayment({commit},{system,value}){
commit('setPayment',{system,value})
}
}
})
const app = new Vue({
store,
el: '#app',
data() {
},
computed: {
checked_payment_systems(){
return system=>
this.$store.state.program.payment_systems[system]
}
},
methods:{
setValue(system,value){
this.$store.dispatch('setPayment',{system,value})
}
}});
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="
https://cdnjs.cloudflare.com/ajax/libs/vuex/3.1.0/vuex.js"></script>
<div id="app">
<li v-for="(value,system) in $store.state.program.payment_systems">
<input type="checkbox" :id="'ps-' + system.id" :checked="checked_payment_systems(system)" #change="setValue(system,$event.target.checked)">
<label :for="'ps-' + system.id" >{{system}}</label>
</li>
<br>
values in the store:
<br>
<br>
{{$store.state.program.payment_systems}}
</div>