I can't figure out how to properly select (set active class) when I do v-for loop and one class is already selected. Let me share the code and with further explanation
These are my available subscriptions and one is already selected, based on user data
<ul>
<li v-for="(s, key, index) in subscriptions"
:class="checkIfClassActive(s.subscription_key)"
@click="setActive(key, index)">
{{ s.name }}
</li>
</ul>
and my js code
checkIfClassActive(userSubscriptionKey) {
if (userSubscriptionKey === this.userSubscription.subscription_key) {
return 'active';
}
},
setActive(key, index) {
},
And this is how is displayed
Now the next step is when I click on one li element it should become active and all other li elements should lose active class, but the problem is that I can't figure out how to properly write setActive function. Can you please help me out, how to do this.
If you need any additional informations, let me know and I will provide. Thank you!
Add a data
property called activeIndex
:
data() {
return {
activeIndex: undefined
}
},
and your setActive
method:
methods: {
setActive(subscription, index) {
this.activeIndex = index;
this.userSubscription.subscription_key = subscription.subscription_key
},
getSubscriptions() {
.....
// fetch subscriptions in this.subscriptions var
.....
// select preselected subscription, when fetching subscriptions
let userSubscriptionKey = this.userSubscription.subscription_key;
let indexOfObject = this.subscriptions.findIndex(
o => o.subscription_key === userSubscriptionKey
);
this.setActive(this.userSubscription, indexOfObject);
}
}
with a slight modification to your template:
<ul>
<li v-for="(s, index) in subscriptions"
:class="{ 'active': activeIndex === index }" :key="s.id"
@click="setActive(s, index)">
{{ s.name }}
</li>
</ul>
You basically set an index that should be active and that's it. active
css class is added when list element's index is the same as activeIndex
.
As for setting activeIndex
to existing choice before the user changes it, you can set activeIndex
when fetching subscriptions data to user's current subscription.
Fiddle: http://jsfiddle.net/eywraw8t/256701/
Change your this.userSubscription.subscription_key
variable everytime a tab is selected. For this pass it through setActive(s.subscription_key)
You can do something like this,
<li v-for="(s, key, index) in subscriptions"
:class="checkIfClassActive(s.subscription_key)"
@click="setActive(s.subscription_key)">
{{ s.name }}
</li>
Js
checkIfClassActive(userSubscriptionKey) {
if (userSubscriptionKey === this.userSubscription.subscription_key) {
return 'active';
}
},
setActive(subscription_key) {
this.userSubscription.subscription_key=subscription_key;
},
this is quicly
if you use v-for:
<template>
<div>
<ul>
<li
class="anyThings"
v-for="cat in cats"
:key="cat.index"
@click="itemActive(cat.index)"
:class="[(itemA == cat.index) ? 'active':'']"
>{{ cat.yourObjectKey }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
itemA:'0' // for first load and in curent path
}
},
computed: {
cats() {
...
}
},
methods: {
itemActive(e) {
this.itemA = e;
}
},
}
</script>
<style>
.active {
...
}
</style>
if you don't need use v-for and use router-link in element:
<template>
<div>
<ul>
<li @click="itemActive($route.path)">
<router-link to="/" class="anyThings"
:class="[(itemA == '/') ? 'active':'']"
>your text
</router-link>
</li>
<li @click="itemActive($route.path)">
<router-link to="/article" class="anyThings"
:class="[(itemA == '/article') ? 'active':'']"
>your text
</router-link>
</li>
.
.
.
</ul>
</div>
</template>
<script>
export default {
data() {
return {
itemA:this.$route.path // for first load and in curent path
}
},
methods: {
itemActive(e) {
this.itemA = e;
}
},
}
</script>
<style>
.active {
...
}
</style>
A simple example showing the logic:
html part:
<div id="app">
<ul>
<li
v-for="item in items"
:key="item.id"
:class="item.class"
@click="set_active_id(item.id)"
>{{ item.text }}</li>
</ul>
</div>
Js part:
new Vue({
el: "#app",
data: {
items: [
{ id: 1, text: 'text1', class: 'active' }, //default active
{ id: 2, text: 'text2', class: '' },
{ id: 3, text: 'text3', class: '' }
],
previous_active_id: 1
},
methods: {
set_active_id(id) {
if (this.previous_active_id === id) return //no need to go further
this.items.find(item => item.id === this.previous_active_id).class = '' //remove the active class from old active li
this.items.find(item => item.id === id).class = 'active' //set active class to new li
this.previous_active_id = id //store the new active li id
}
}
})
See it in action
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With