Here is my vue instance:
new Vue({
el: '#app',
data: {
showPerson: true,
persons:
[
{id: 1, name: 'Alex'},
{id: 2, name: 'Bob'},
{id: 3, name: 'Chris'}
],
},
methods: {
nextPerson: function(){
this.showPerson = false;
}
}
});
I am trying to walk the persons array of objects. I want the list to start with the first element of the array and below it should be a button which is responsible for hiding the previous element and showing the next element of the array. Once the user reaches the last element, the Next button should not go back to the first element.
Here is the HTML:
<div id="app">
<ul v-for="person in persons">
<li v-if="showPerson">{{person.name}}</li>
</ul>
<button #click="nextPerson">Next Person</button>
</div>
And the JSBin Link. At this moment I can only show and hide the items all at once and not one at a time. How can I implement this?
One of the ways of doing so would be to keep an index for the person being shown on screen. I've named this variable as shownPersonIndex.
Then, you need to show the next person on click of button. So in the click event handler, you need to increment the index by 1. Also, you need to ensure that the index value does not exceed the length of the array. So I've modified the click handler as follows:
nextPerson: function() {
if(this.shownPersonIndex < (this.persons.length - 1)) {
this.shownPersonIndex++;
}
}
Finally, you can either use a computed to display the currently shown person or an inline expression like this.persons[this.shownPersonIndex].name to show the person on screen.
I am using v-if="this.shownPersonIndex != this.persons.length - 1" to hide the "next" button as you reach the last element on the array.
new Vue({
el: '#app',
data: {
shownPersonIndex: 0,
persons: [{
id: 1,
name: 'Alex'
},
{
id: 2,
name: 'Bob'
},
{
id: 3,
name: 'Chris'
}
],
},
methods: {
nextPerson: function() {
if(this.shownPersonIndex < (this.persons.length - 1)) {
this.shownPersonIndex++;
}
}
},
computed: {
shownPerson: function() {
return this.persons[this.shownPersonIndex];
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>
<div id="app">
Person: {{ shownPerson.name }}
<button v-if="this.shownPersonIndex != this.persons.length - 1" #click="nextPerson">Next Person</button>
</div>
Related
So, i tried to dynamically toggle className, based on computed property, but it looks like pug doesn't have access to computed properties. I tried to manually set true to a className, then it's working.
I tried to reassign computed property to pug variable, but it still doesn't work
When using pure html, classes dynamically toggle correctly
Pug:
main#app.container
- var isPinkDefinitely = isPink ? 'pink' : 'gray';
div.section(
v-bind:class=[
'custom-section',
{
'custom-section--pink': isPink
}
]
v-bind:style=[
{
'background-color': isPinkDefinitely
}
]
) {{ isPink }}
form(#submit.prevent="addItem")
label.label Add another
div.field.has-addons
div.control
input.input(required, autofocus, v-model="newItem", placeholder="Remake this in React")
button(type="submit").button.is-info
i.fa.fa-plus
span Add
transition(name="slide")
div(v-show="items.length > 0")
hr
ul
transition-group(name="slide")
li(v-for="(item, index) in items", :key="item.id")
button(#click="removeItem(index)").button.is-danger
i.fa.fa-trash
span(v-text="item.desc")
hr
span(v-text="'Total: ' + items.length")
JS:
new Vue({
el: '#app',
data: {
items: [
{id: 1, desc: "Lorem"},
{id: 2, desc: "Ipsum"},
{id: 3, desc: "Dolor"},
],
newItem: '',
},
computed: {
isPink() {
return true;
}
},
methods: {
addItem () {
const id = this.items.length + 1
this.items.push({id, desc: this.newItem})
this.newItem = ''
},
removeItem (index) {
this.items.splice(index, 1)
},
},
})
https://codepen.io/itprogressuz/pen/qBoePob?editors=1010
UPD:
SO the basically solution was to just write all classes in one line inside just an object. see solution of #aykut
I just tried to solve your problem and I think i successed. You could use variable like me. If you want change it in computed function, it will change dynamically. You could also change it in methods functions when get users events. Here, my solution.
main#app.container
div.section(
class="default-style"
:class="{'bg-pink': isPink }"
) {{ setIsPink }}
form(#submit.prevent="addItem")
label.label Add another
div.field.has-addons
div.control
input.input(required, autofocus, v-model="newItem", placeholder="Remake
this in React")
button(type="submit").button.is-info
i.fa.fa-plus
span Add
transition(name="slide")
div(v-show="items.length > 0")
hr
ul
transition-group(name="slide")
li(v-for="(item, index) in items", :key="item.id")
button(#click="removeItem(index)").button.is-danger
i.fa.fa-trash
span(v-text="item.desc")
hr
span(v-text="'Total: ' + items.length")
// css file
.default-style{
background-color: gray;
}
.bg-pink{
background-color: pink;
}
// js file
new Vue({
el: '#app',
data: {
isPink: false,
items: [
{id: 1, desc: "Lorem"},
{id: 2, desc: "Ipsum"},
{id: 3, desc: "Dolor"},
],
newItem: '',
},
computed: {
setIsPink() {
this.isPink = !this.isPink;
return this.isPink;
}
},
methods: {
addItem () {
const id = this.items.length + 1
this.items.push({id, desc: this.newItem})
this.newItem = ''
},
removeItem (index) {
this.items.splice(index, 1)
},
},
})
<script>
import { datalist } from "./datalist";
export default {
name: "HelloWorld",
components: {},
data() {
return {
items: datalist,
};
},
methods: {
deleteEvent(id) {
this.items = this.items.filter((e) => e.id !== id);
},
},
};
</script>
My data...
export const datalist = [
{ id: 1, val: "11", kk: "potter" },
{ id: 2, val: "22", kk: "james" },
{ id: 3, val: "55", kk: "limda" },
{ id: 4, val: "77", kk: "stepen" }
];
<div>
<div v-for="item in items" :key="item.id">
<b>{{ item.id }}.</b>
<router-link :to="{ name: 'UserWithID', params: { id: item.id } }">
{{ item.kk }}
</router-link>
<input type="checkbox" :value="item.id" />
<button #click="deleteEvent(item.id)">Delete</button>
</div>
</div>
My complete code;- https://codesandbox.io/s/wild-flower-rssg0?file=/src/components/datalist.js
I want to delete the array item, When user click on checkbox beside each item. and then click on delete button then the array item record need to be deleted.
But now i am getting as, Directly if I click on delete button, i am able to delete the array. But that should happen only after the checkbox click and then delete button.
For this process, I have taken click event in button and added a method to delete array record but its not working.... Can u please help me what is wrong with the code...
You should maintain an array of items to delete. Bind the checkbox to this array so that if the checkbox is checked, the item ID is added to this array. Then, simply add a delete button somewhere to delete all selected items.
See example here: https://codesandbox.io/s/elated-lake-ws2wn
i have a scenario where I am triggering an event on button click after selecting elements from the grid when the button is clicked I need to remove that element from the current modal/grid
CheckedNames:["a","b","c"],
CheckedNamesId:[1,2,3],
DeletefromArray(){
this.CheckedNames.forEach(element => {
this.deleteItem(this.CheckedNamesId,this.CheckedNamesId.length);
});
},
deleteItem(index,length) {
this.List.splice(index, length)
},
check: function(e,row) {
this.CheckedNamesId.push(row.id)
console.log(this.CheckedNamesId)
},
Now if I select "a","b","c" by the check box, I need to remove it from the array,
If I understood you correctly try something like following snippet:
new Vue({
el: '#demo',
data() {
return {
names: [{id: 1, name: 'a'},{id: 2, name: 'b'}, {id: 3, name: 'c'}, {id: 4, name: 'd'}, {id: 5, name: 'e'}, {id: 6, name: 'f'}, {id: 7, name: 'g'}],
checkedNames: []
}
},
methods: {
check(item) {
if (!this.checkedNames.length || !this.checkedNames.find(f => item.id === f.id)) {
this.checkedNames.push(item)
} else {
this.checkedNames = this.checkedNames.filter(f => item.id !== f.id)
}
},
del() {
this.names = this.names.filter(a => !this.checkedNames.includes(a))
this.checkedNames = []
}
}
})
Vue.config.productionTip = false
Vue.config.devtools = false
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<ul>
<li v-for="item in names" :key="item.id">
{{ item.name }}
<input type="checkbox" #click="check(item)" />
</li>
</ul>
<button #click="del">Delete</button>
</div>
You can try like the code below. When looping in List array check if id of the element is present in checkedNameID array by using indexof. If present add that element's index in a array defined outside loop. Then you can slice it away using another loop from array. When you slice use 1 as second parameter it will remove 1 element at a a time in loop.
const arr = []
deleteFromArray(){
this.List.forEach((element,index) => {
if(this.checkedNameID.indexOf(element.id) !== -1){
this.arr.push(index);
}
});
arr.forEach(item => {
this.List.splice(index,1);
}
},
I have a list of strings in Vue, and I'm using v-for to list all of them in "list-group" with Bootstrap. I want to set the "active" state on click on one of the items, but I can't find a way to ID a specific item on the list with the for loop.
HTML -
<div class="list-group" id="ServersList">
{{Server.text}}
</div>
VueJS -
var ServersList = new Vue({
el: '#ServersList',
data: {
Servers: [
{ text: '1' },
{ text: '2' },
{ text: '3' },
{ text: '4' },
{ text: '5' },
{ text: '6' }
})
You can use v-for="(Server, index) in Servers". Index will store the current index for each element. With this you can then call a defined method like so:
In your viewmodel definition add this:
data: {
currentIndex: 0
},
methods: {
myClick(index) {
this.currentIndex = index
}
}
modify your a tag in your template:
<a href="#"
v-for="(server, index) in Servers"
:class="{yourActiveClass: currentIndex === index, yourInactiveClass: currentIndex !== index}"
#click="myClick(index)">
Im trying to make a form where you have buttons to add children inputs but after adding one child the button no longer works and it returns to error in the cole as to why but if i output the data it looks like it is being adding just the DOM isn't being updated with the new input box
var default_item = {
value: 0,
reps: 0,
sets: 0
}
var deafult_exercise = {
exercise_name: '',
item_data: [default_item]
};
new Vue({
el: '#app',
data: {
log_data: [
{
log_name: 'log #1',
log_day: 1,
exercise_data: [
{
exercise_name: 'exercise #1',
item_data: [
{
value: 50,
reps: 5,
sets: 5
}
]
}
]
}
]
},
methods: {
addLog: function(){
this.log_data.push({log_name: '', log_day:0, exercise_data: deafult_exercise});
},
addExercise: function(index_id) {
this.log_data[index_id].exercise_data.push(deafult_exercise);
},
addItem: function(index_id, log_id) {
this.log_data[log_id].exercise_data[index_id].item_data.push(default_item);
}
}
})
JSfiddle: https://jsfiddle.net/renlok/5mpace1q/3/
Your issue is that you are pushing the same items and referencing the same items so essentially you are only ever adding 1 item
You need to use
Object.assign({}, default_item)
To use new instances of the items see updated fiddle https://jsfiddle.net/5mpace1q/4/