v-for loop. i will get same value at each checkbox - vue.js

i'm going to show a loop for user's favourite music genres. but i want to read them from a property inside my Vue instance. here is my code:
<div id="app">
<form method="post" action="">
<fieldset>
<legend>Genres</legend>
<!-- Item in Collection -->
<div v-for="genre in genres">
<input type="checkbox" v-model="selectedGenres" value="genre"> {{genre}}
</div>
</fieldset>
<input type="submit" value="submit">
</form>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
genres: ['jazz', 'pop', 'blues', 'classic', 'country'],
selectedInterests: []
}
});
</script>
but at the end i will get following image and value attribute of checkboxes will not change! why i will get same values at each checkbox?

i am not sure but i think you should change your code in where it says:
value="genre"
and change it to:
v-bind:value="genre" or :value="genre"

You need to bind the genre variable.
<input type="checkbox" v-model="selectedGenres" :value="genre">
Will compute genre instead of just giving the string genre

Related

Modify checkbox behavior in vue js

I have this checkbox
<div class="form-check form-check-inline col-lg-2">
<input v-model="propertyData.fitness_centre" type="checkbox" class="form-check-input" id="dc_li_u" />
<label class="form-check-label" for="dc_li_u">Fitness Centre</label>
</div>
and i am saving the state in a database so when editing the state is restored and displays whether the checkbox was checked or not.
However, i need the checkbox to have a string value that is saved to the database when the checkbox is clicked such that when a checkbox has a string value, its checked and when the string value is empty the checkbox is not checked.
I have many checkboxes and so, i wanted the entire logic to be contained inside the checkbox. How can i modify the checkbox to do this?
You can use true-value and false-value attributes, to assign specific values when checking/unchecking.
new Vue({
el: "#app",
data: {
fitness_centre: "true value"
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="form-check form-check-inline col-lg-2">
<input v-model="fitness_centre" true-value="true value" false-value="" type="checkbox" class="form-check-input" id="dc_li_u" />
<label class="form-check-label" for="dc_li_u">Fitness Centre</label>
<div>Value: {{ fitness_centre }}</div>
</div>
</div>
You could use a change-event handler to set propertyData.fitness_centre to the desired value based on the checked state. Also bind <input>.checked to propertyData.fitness_centre so that the checked state is bound to the model's truthiness (empty string is false, otherwise true).
<template>
<input type="checkbox"
#change="onChange"
:checked="propertyData.fitness_centre"
value="fitness_centre">
</template>
<script>
export default {
data() {
return {
propertyData: { fitness_centre: '' }
}
},
methods: {
onChange(e) {
this.propertyData.fitness_centre = e.target.checked ? e.target.value : ''
}
}
}
</script>
demo

Can you add more than one modifier to vue js v-model?

Can you add more than one modifier?
For example:
<input v-model.trim="name.first"/>
<input v-model.lazy="name.first"/>
into something along the line
<input v-model.{lazy,trim}="name.first"/>
Possible or not possible?
Yes!
followup question:
What is the concept behind it?
I understand it works,
but ".lazy.trim" sounds like trim is a part of lazy object
Yes,we can add more than one modifier to Vue js v-model.
new Vue({
'el': '#app',
data: {
val: 'default value',
num: 0,
trimExample: ''
},
methods: {
handleBtnClick() {
console.log(this.trimExample, this.num)
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input type="text" v-model.lazy="val">
<br> {{val}}
<br><br>
<input type="text" v-model.number="num">
<input type="text" v-model.trim.lazy="trimExample">
<button v-on:click="handleBtnClick">
check console
</button>
</div>
Fiddle Link
Yes you can use it !
for example you can see this link which v-model.trim.lazy is used in it !
https://vuelidate.js.org/#sub-basic-form
<input class="form__input" v-model.trim.lazy="$v.age.$model"/>

Get value of multiple input fields in v-for loop [Vue.js]

I have a couple of fields, that are rendered through v-for loop:
<div v-for="element in elements" class="uk-form-row uk-margin-small-top">
<input class="uk-width-1-1 uk-form-small" type="text" placeholder="element" style="width:50%">
</div>
And I need to pass them through a POST request.
elements is just an array, that contains a different number of:
value: ""
and after submitting the form, an array is just a collection of empty objects
How can I change my code to pass an array of values from those fields?
Try to bind your inputs to your array items using v-model directive like :
<div v-for="element in elements" class="uk-form-row uk-margin-small-top">
<input v-model="element.value" class="uk-width-1-1 uk-form-small" type="text" placeholder="element" style="width:50%">
</div>
after that you could use your elements array directly in the POST request.
new Vue({
el: '#app',
data: {
elements: []
},
methods: {
addElement: function() {
this.elements.push({
value: ''
});
}
}
});
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<h1>Elements</h1>
<div v-for="element in elements">
<input class="form-control" v-model="element.value" type="text" />
</div>
<button class="btn btn-primary" #click="addElement">
New Element
</button>
<pre>{{ $data | json }}</pre>
</div>

Binding vue components to class name

Alright so I am trying to bind this vue components to a class name so it triggers on every element that has this class but what happens is that it only works with the first element and not with other ones
<div class="__comment_post">
<textarea></textarea>
<input type="submit" v-on:click="submitComment" /> <!-- submit comment being only triggered on this one -->
</div>
<div class="__comment_post">
<textarea></textarea>
<input type="submit" v-on:click="submitComment" />
</div>
<div class="__comment_post">
<textarea></textarea>
<input type="submit" v-on:click="submitComment" />
</div>
As you can see above, I've got 3 divs with class __comment_post so naturally submitComment should be bound to all these 3 divs but what happens is that submitComment is being triggered only on the first one
var app = new Vue({
el:".__comment_post",
data: {
comment: ""
},
methods: {
submitComment: function() {
console.log("Test");
}
}
});
Here is a little example you and others can follow in order to bind vue instance to class names.
Lets say, you would like to bind Vue to multiple existing <div class="comment"> element in HTML.
HTML:
<div class="comment" data-id="1">
<div>
<div class="comment" data-id="2">
<div>
Now, you can try the following logic/code to your example.
JS:
var comments = {
"1": {"content": "Comment 1"},
"2": {"content": "Comment 2"}
}
$('.comment').each(function () {
var $el = $(this)
var id = $el.attr('data-id')
var data = comments[id]
new Vue({
el: this,
data: data,
template: '<div class="comment">{{ content }}<div>'
})
})
I hope this will answer your question :)
The vue instance is mounted on the first found DOM element with the css selector passed to the el option. So the rest two div have no vue instances mounted on them.
So wrap your divs with a wrapper div and mount the vue instance on that wrapper
<div id="app">
<div class="__comment_post">
<textarea></textarea>
<input type="submit" v-on:click="submitComment" /> <!-- submit comment being only triggered on this one -->
</div>
<div class="__comment_post">
<textarea></textarea>
<input type="submit" v-on:click="submitComment" />
</div>
<div class="__comment_post">
<textarea></textarea>
<input type="submit" v-on:click="submitComment" />
</div>
script
var app = new Vue({
el:"#app",
data: {
comment: ""
},
methods: {
submitComment: function() {
console.log("Test");
}
}
});

VueJS - how to show different div on radio button select

How to show different component on radio button select.
<input type="radio" name="book" value="One" checked="checked">
<input type="radio" name="book" value="Round">
<div> // this should show show default, One is selected
<p>Value One</p>
</div>
<div> // this should show show on radio change to Round selected
<p>Value Round</p>
</div>
How about something like this?
new Vue({
el: '#app',
data: {
x: 'one',
},
});
<script src="https://rawgit.com/vuejs/vue/dev/dist/vue.js"></script>
<div id="app">
<input type="radio" v-model="x" value="one">
<input type="radio" v-model="x" value="two">
<div v-show="x === 'one'">One</div>
<div v-show="x === 'two'">Two</div>
</div>
i have done it with javascript .onclick it calls each function which hides & show element vice versa
function rdone(){
document.getElementById('one').style.display ='block';
document.getElementById('round').style.display ='none';
}
function rdround(){
document.getElementById('round').style.display = 'block';
document.getElementById('one').style.display ='none';
}
#round{
display:none;
}
<input type="radio" name="book" value="One" checked="checked" onclick="rdone();">
<input type="radio" onclick="rdround();" name="book" value="Round">
<div id=one> // this should show show default, One is selected
<p>Value One</p>
</div>
<div id=round> // this should show show on radio change to Round selected
<p>Value Round</p>
</div>