Background: I have a list of checkboxes that is bound to a names array. I am trying to change the class of the specific name once the checkbox is clicked.
Problem: Once a checkbox is clicked it changes the class of all the names instead of the specific name attached to the checkbox.
JSFiddle of the issue:
JSFiddle
HTML
<div id="app">
<ul>
<li v-for="name in names" :key="index">
<input #click="available = !available" type="checkbox">
<label :class="{available:available}" >{{name.name}}</label>
</li>
</ul>
</div>
Vue instance
var app = new Vue({
el: '#app',
data: {
available: false,
names: [{'name':'Jerry'},{'name':'Eddie'},{'name':'Kerry'},{'name':'Jane'}]
}
})
Css
.available{
text-decoration: line-through;
}
Ad the available variable to each name object and use a method to update the available property:
var app = new Vue({
el: '#app',
data: {
names: [
{'name':'Jerry', 'available': false},
{'name':'Eddie', 'available': false},
{'name':'Kerry', 'available': false},
{'name':'Jane', 'available': false}
]
},
methods: {
updateAvailable(index) {
// Update the available property on the specific object with its index
this.names[index].available = !this.names[index].available
}
}
})
Then in your template, call the method updateAvailable:
<div id="app">
<ul>
<li v-for="(name, index) in names" :key="index">
<input #click="updateAvailable(index)" type="checkbox">
<label :class="{available: name.available}" >{{name.name}}</label>
</li>
</ul>
</div>
Move the available property in to each name element and toggle name.available in your template. You can even use v-model on your checkboxes.
const names = [{'name':'Jerry'},{'name':'Eddie'},{'name':'Kerry'},{'name':'Jane'}]
const app = new Vue({
el: '#app',
data: () => ({
names: names.map(name => ({ ...name, available: false }))
})
})
.available {
text-decoration: line-through;
}
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<div id="app">
<ul>
<li v-for="(name, i) in names">
<input :id="`name_${i}`" v-model="name.available" type="checkbox">
<label :for="`name_${i}`" :class="{ available: name.available }">
{{name.name}}
</label>
</li>
</ul>
</div>
Related
I have a code in Vue that creates the elements of a menu using a v-for, and each element must have a different method when it's clicked.
So far I have this:
<span v-for="(menuItem, index) in menuItems" :key="index">
<li>
<a id="listItem">
<i class="bx" :class="menuItem.icon || 'bx-square-rounded'" />
<span class="links_name" v-on:click=menuItem.click>{{ menuItem.name }}</span>
</a>
<span class="tooltip">{{
menuItem.tooltip || menuItem.name
}}</span>
</li>
</span>
How can I assign different funcions on the v-on?
You can make the listener function as a node in the object list.
Sample Implementation
const app = new Vue({
el: '#app',
data() {
return {
list: [{
name: 'lg',
age: 27,
onClick: function() {
console.log("First Item Clicked");
}
}, {
name: 'camile',
age: 27,
onClick: function() {
console.log("Second Item Clicked");
}
}]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.0/vue.js"></script>
<body>
<div id="app">
<ul>
<li v-for="(item, index) in list" :key="item.name">
{{item.name}} - {{item.age}}
<button #click="item.onClick()">
Click Me
</button>
</li>
</ul>
<input type="text" v-model="list[0].name">
</div>
</body>
const app = new Vue({
el: "#app",
name: 'aselect',
data: {
value: 'Select a Fruit',
list: ["Orange", "Apple", "Kiwi", "Lemon", "Pineapple"],
visible: false
},
methods: {
toggle() {
this.visible = !this.visible;
},
select(option) {
this.value = option;
}
}
})
<div id="app">
<h1>Custom Select Dropdown</h1>
<div class="aselect" :data-value="value" :data-list="list">
<div class="selector" #click="toggle()">
<div class="label">
<span>{{ value }}</span>
</div>
<div class="arrow" :class="{ expanded : visible }"></div>
<div :class="{ hidden : !visible, visible }">
<ul>
<li :class="{ current : item === value }" v-for="item in list" #click="select(item)">{{ item }}</li>
</ul>
</div>
</div>
</div>
</div>
I am using the reference from https://www.npmjs.com/package/vue-click-outside
This is my codepen link https://codepen.io/santoshch/pen/gOmvvmN In the codepen link, i have a dropdown, where after toggling down the dropdown i am unable to close the dropdown list.
So i have searched for some reference i vuejs, And finally found npm package called vue-click-outside, Itried to place event but not sure how to proceed.
I found out a solution to your problem. Follow below steps
At first Add box class to every element that lies inside the box that toggle the dropdown
<div id="app">
<h1>Custom Select Dropdown</h1>
<div class="aselect" :data-value="value" :data-list="list">
<div class="selector box" #click="toggle()">
<div class="label box">
<span class="box">{{ value }}</span>
</div>
<div class="arrow box" :class="{ expanded : visible }"></div>
<div :class="{ hidden : !visible, visible }">
<ul>
<li :class="{ current : item === value }" v-for="item in list" #click="select(item)">{{ item }}</li>
</ul>
</div>
</div>
</div>
</div>
Then add click listener to window in vue.js
const app = new Vue({
el: "#app",
name: 'aselect',
data: {
value: 'Select a Fruit',
list: ["Orange","Apple","Kiwi", "Lemon", "Pineapple"],
visible: false
},
methods: {
toggle() {
this.visible = !this.visible;
},
select(option) {
this.value = option;
},
handleClick(e){
const classname = e.target.className;
if(this.visible && !classname.includes("box")){
this.visible = false;
}
}
},
created () {
window.addEventListener('click', this.handleClick);
},
destroyed () {
window.removeEventListener('click', this.handleClick);
},
})
Check this pen: https://codepen.io/salim-hosen/pen/xxqYYMQ
I want my list to be rendered like this:
A
B
C
Right now its being rendered like this:
1: A 2: B 3: C
Heres the code:
Todos:
<input type="text" class = "todo" placeholder = "Next Item" v-on:keyup.enter="addItem()">
<ol>
<li v-for="(todo, index) in todos" class ="todos">
{{index}}: {{ todo.text }}
</li>
</ol>
Heres the javascript portion:
addItem(){
var text = event.target.value;
this.todos.push({text, done: false, id: Date.now()})
text = '';
}
Any help would be very appreciated!
Not entirely sure why yours is displaying any different, but here's a rough example:
new Vue({
el: '#app',
data() {
return {
todos: ['derek', 'was', 'here'],
newTodo: ''
}
},
methods: {
addTodo() {
this.todos.push(this.newTodo);
this.newTodo = '';
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div>
<input v-model="newTodo" />
<button #click="addTodo">add</button>
<ol>
<li v-for="(todo, index) in todos" :key="index">{{todo}}</li>
</ol>
</div>
</div>
The only other thing I can think of is that you have some special CSS styling set that's causing the issue.
I'm new to Vue, and am playing around with v-model to see what I can create. I want to make an editable array of names. Here is my code so far:
var app = new Vue({
el: '#app',
data: {
names: ['Josh', 'Tom']
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
Editable list:
<ul>
<li v-for="name in names"><input type="text" v-model="name"></li>
</ul>
{{ names }}
</div>
When this is run, the inputs show up, and each one contains the correct value. However, typing in the inputs doesn't update the names array as I would have expected.
What am I doing wrong?
You're trying to use v-model to operate on a value, whereas you need to operate on a vue data field. For example, try the following:
var app = new Vue({
el: '#app',
data: {
people: [{name: 'Josh'}, {name: 'Tom'}]
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
Editable list:
<ul>
<li v-for="person in people"><input type="text" v-model="person.name"></li>
</ul>
{{ people }}
</div>
Alternatively, you could do:
var app = new Vue({
el: '#app',
data: {
names: ['Josh', 'Tom']
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
Editable list:
<ul>
<li v-for="(name, index) in names"><input type="text" v-model="names[index]"></li>
</ul>
{{ names }}
</div>
So I just started playing around with Vue.js. But I am having some problems with simple tasks like adding new "news item" to the array. JSFiddle included so if someone can tell me what I am doing wrong..
http://jsfiddle.net/pL5taqp6/
HTML
<div id="app">
<input type="text" v-model="news.title">
<input type="text" v-model="news.url">
<ul>
<li v-for="n in news">
{{ n.title }} - {{ n.url }}
</li>
</ul>
</div>
JS
new Vue({
el: '#app',
data: {
news: [
{ title: 'Test Title', url: '/test-title'}
]
}
});
You need a separate method to add items to news array. I added super simple variant of such function.
http://jsfiddle.net/00953sor/
HTML:
<div id="app">
<form #submit="addItem">
<input type="text" v-model="itemTitle">
<input type="text" v-model="itemUrl">
<button type="submit">Add</button>
</form>
<ul>
<li v-for="n in news">
{{ n.title }} - {{ n.url }}
</li>
</ul>
<pre>{{ $data | json }}</pre>
</div>
JavaScript:
new Vue({
el: '#app',
data: {
news: [{
title: 'Test Title',
url: '/test-title'
}]
},
methods: {
addItem: function(e) {
e.preventDefault(); // prevent page refresh
this.news.push({
"title": this.itemTitle,
"url": this.itemUrl
});
this.itemTitle = this.itemUrl = '';
}
}
});