How to add class on different if statement in vue - vue.js

I want to change to color of my element each time it clicks the element, (to show start, in-progress and finished). For this I made a variable and increasing its value each time user clicks it and then applying different classes for styling.
<div v-for="error in errors" :key="error" class="element" > <span #click="modify()"> {{error}}</span></div>
I declare a variable step in data
modify () {
step = step + 1
}
now I want to change styling base of this step (1, 2, 3).
Any idea, how can I do this?

you can try :
<div class="element" v-for="error in errors" :key="error" :class="step==1 ? 'class1' :
step==2 ? 'class2':'class3'">
....
</div>

I would suggest an approach like this:
<div v-for="error in errors" :key="error" :class="`class_${step}`" >
<span #click="modify()"> {{error}}</span>
</div>
Or if you don't want to name your classes that way:
<div v-for="error in errors" :key="error" :class="getClass" >
<span #click="modify()"> {{error}}</span>
</div>
...
methods: {
getClass() {
if (this.step === 1) return 'classA';
if (this.step === 2) return 'classB';
// etc.
}
}

Related

Get all selected values on change with VueJS 3

I have these lines inside my component:
<li
v-for="(c, i) in choice[messagesRobot[numMessage].choice]"
:key="`choice-${choice[messagesRobot[numMessage].choice]}-${i}`">
<input
#change="changeValue($event, messagesRobot[numMessage].choice)"
:value="c.id"
type="checkbox"
:name="choix[messagesRobot[numMessage].choice]"
:id="`c-${choix[messagesRobot[numMessage].choice]}-${i}`">
<label :for="`c-${choix[messagesRobot[numMessage].choice]}-${i}`">
{{ c.nom }}
</label>
</li>
As you can see, there are a lot of computed properties. What I would like is to update the model when the user changes the value. The problem is that I can't use something like :v-model="xxx", so I have to capture the #change event. I wrote this:
function changeValue(e, v) {
console.log(v);
console.log(JSON.stringify(e.target.value));
}
The second line only gives me the last element the user selected or unselected, what I would like is to get ALL the values of the checkboxes, in an array, as it would do if I could use a v-model.
Thanks in advance for your help :)
I think you could do something like this
<li
v-for="(c, i) in choice[messagesRobot[numMessage].choice]"
:key="`choice-${choice[messagesRobot[numMessage].choice]}-${i}`">
<input
#change="changeValue($event, messagesRobot[numMessage].choice, i)"
:value="c.id"
type="checkbox"
:name="choix[messagesRobot[numMessage].choice]"
:id="`c-${choix[messagesRobot[numMessage].choice]}-${i}`">
<label :for="`c-${choix[messagesRobot[numMessage].choice]}-${i}`">
{{ c.nom }}
</label>
</li>
data() {
return {
valuesArray: []
}
}
function changeValue(e, v, index) {
this.valuesArray[index] = e.target.value;
console.log(v);
console.log(JSON.stringify(e.target.value));
}
then your valuesArray would have all the checked values.
Why can't you just use v-model?

Set focus to first item in v-for using vue

I have a vue app and I'm trying to set the focus to the first item in my v-for list but struggling
HTML
<div class="input-group-append">
<button class="btn btn-light" type="submit" style="border: 1px solid lightgray" #click.prevent="findTest">
<i class="fas fa-search"></i>
</button>
</div>
<div v-if="this.Tests.length >= 2" class="list-group accList">
<a v-for="(test, i) in tests" :key="i" class="list-group-item list-group-item-action" :ref="i" :class="{ 'active': i === 0 }" #click.prevent="selectTest(test)">
{{ test.test1 }} ({{ test.test2 | capitalize }})
</a>
</div>
Note the word 'test' has replaced my actual values
I have tried using the following in my method which is called on button click but I keep getting get an error
methods: {
findTest() {
axios.get(END_POINT).then((response) => {
...SOMEOTHER CODE
//this.$refs.0.$el.focus()
//this.$refs.0.focus();
//this.$refs.a.$el.children[0].focus();
}
}
}
Error
I am relativly new to vue but I have been able to set my focus using:
this.$refs.[INPUT_NAME].$el.focus()
But it doesn't like me using a number
this.$refs.0.$el.focus() //0 being the index number
As WebStorm complains saying:
Expecting newline or semicolon
console.log(this.$refs)
When using v-for, ref maybe array of refs.
Template: use ref="tests" instead of :ref="i"
<a v-for="(test, i) in tests" :key="i" class="list-group-item list-group-item-action" ref="tests" :class="{ 'active': i === 0 }" #click.prevent="selectTest(test)">
{{ test.test1 }} ({{ test.test2 | capitalize }})
</a>
Script
this.$refs.tests[0]
I guess its undefined because you try to access the element while the v-for loop didnt finished its rendering
Try this:
methods: {
findTest() {
axios.get(END_POINT).then((response) => {
...SOMEOTHER CODE
this.$nextTick(()=> {
//put your code here
//this.$refs.0.$el.focus()
//this.$refs.0.focus();
//this.$refs.a.$el.children[0].focus();
})
}
}
}
Put your code into $nextTick() that should ensure that its get executed when the loop is done

Vue inline click event `this` is undefined

i'm getting an error in the below code saying this is undefined.
<div class="location-list__item" v-for="(value, key) in locations.data">
<div class="location-list__item--text"
:class="{ selected: selected === key }"
#click="() => { this.selected = key; this.manageSurrounding = false }">
<i class="fas fa-compass"></i> {{ value.name }}
<span v-if="value.changed" class="has-text-danger"> Changed</span>
</div>
</div>
However if I change this line:
#click="() => { this.selected = key; this.manageSurrounding = false }"
to this
#click="selected = key"
It works fine, however I need to change manageSurrounding at the same time and I don't want to create a method for such a simple thing.
You can do multiple assignments by using semicolon like the above statement which you have written.
<div class="location-list__item" v-for="(value, key) in locations.data">
<div class="location-list__item--text"
:class="{ selected: selected === key }"
#click="selected = key;manageSurrounding = false"> # Like this
<i class="fas fa-compass"></i> {{ value.name }}
<span v-if="value.changed" class="has-text-danger"> Changed</span>
</div>
</div>
You can use a anonymous function like,
<div onclick="return function()
{ selected = key; manageSurrounding = false }'
</div>
Just create a method and put in the update lines, you are better off on the long run, if your list is changing/reordering/re-rendering often.
It’s an optimization opportunity, so don’t try to force it in just because it seems small. Have a look at this answer: anonymus function in template

Using vue, determine which radio input is selected by accessing $refs

I populate some radio buttons from an array of options. I would like to determine which radio button was select using $refs, however when I log out the $refs it gives me all of the radio buttons.
Is it possible to just grab the select radio button using $refs? Can you some how combine event.target with the $refs or something? Furthermore how to I access parts of that ref like the class of the element that was selected. I am trying to use just vue to do this but has proven difficult.
thanks for any help you can provide.
<li
class="mc-option"
v-for="(option, i) in options"
:key="i">
<input
ref="mcOption"
type="radio"
name="option"
:id="'option-' + i"
class=""
#click="radioSelected($event)">
</li>
methods: {
radioSelected: function () {
let mcOption = this.$refs.mcOption
console.log(mcOption)
},)
}
X is your ID:
<ul>
<li v-for="x in 5">
<label :for="`radio${x}`">radio{{x}}</label>
<input type="radio" name="radio" :id="`radio${x}`" #change="getRef(`radio${x}`)" :ref="`radio${x}`">
</li>
</ul>
methods: {
getRef (ref) {
console.log(this.$refs[ref])
}}
This is happening since all the generated options are having the same ref ids. You could come over this with the following code.
TEMPLATE
<li class="mc-option" v-for="(option, i) in options" :key="i">
<input :ref="['mcOption',i].join('-')" type="radio" name="option" :id="'option-' + i" class="" #click="radioSelected(i)"> {{i+1}}
</li>
JS
methods: {
radioSelected: function (i) {
let mcOption = this.$refs[['mcOption', i].join('-')]
console.log(mcOption)
}
}
Points to note are:
:ref
a variable ref id by using ['mcOption', i].join('-'). This actually can be anything you want (but should change for every v-for iteration).
Please let me know if it does NOT work for you.

How to concat text class with Vuejs 2

How do I dynamically concat a text with vuejs 2
Here is what I have now:
<span class="label" :class="label-{{account.Segment}}">{{account.Segment}}</span>
account.Segment == "ABC"
What I need rendered is that
<span class="label label-ABC">ABC</span>
Here is one possible way.
<span class="label" :class="'label-' + account.Segment">{{account.Segment}}</span>
You can add more classes using an array of string
computed: {
classNames() {
// add more logic here
let classNames = ['label'];
classNames.push(`label-${this.contextType}`);
return classNames;
},
},
and then you can use it like this
<div :class="classNames">
...
</div>