What's proper method to highlight one element? - vue.js

I want to show red on r.data2 by vue.js, but it can not work proper, any hint to debug it?
The data 'rows' is updated by a timer per second. The 'Status', 'data1', 'data2' are generated on server side.
vm = new Vue({
el: '#app',
data: {
rows: [{Status:1, data1:"d1", data2:"d2"}]
}
})
...
<tr v-for="r in rows">
<td><button class="st-{{r.Status}}">r.data1</button></td>
<td valign="top">
<div v-if="r.Status == 4">
<font color="red">{{r.data2}}</font>
</div>
<div v-else>
{{r.data2}}
</div>
</td>
</tr>

Did you try class and style bindings as given in Vue docs?
Ref: https://vuejs.org/guide/class-and-style.html#Object-Syntax-1
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
and your data:
data: {
activeColor: 'red',
fontSize: 30
}
That example is a copy-paste from the docs link above. Check it out!
Edited answer after comment #1:
The best way is to use array syntax for class bindings, as follows:
<div v-bind:class="['some-static-class-for-your-data', { 'danger-class' : data2 == 4 }]">
my data2 value = {{data2}}
</div>
And set a CSS like:
.danger-class {
color: red;
}
Now whenever your data2 has the value of 4, the 'danger-class' will be set on your div. Your CSS ensures that it is displayed in red, or whatever color you choose.
If you have other classes for your data, you can put it as shown in the above example with some-static-class
It is a good practice to set meaningful class names instead of hard-coding styles. So I would not recommend you to go for style bindings, though you can do it if you want. Check out the docs link for class and style bindings.

Related

v-if inside v-for is giving me Property or method "*" is not defined on the instance

I want to be able to compare two dates in vue and add a class to the div if the date is less then the today date. This is my code:
<tr v-for="car in cars">
<div v-if="Date.now() <= new Date(car.ContractDate)">if true, add class to this div</div>
</tr>
But I am getting this error instead:
[Vue warn]: Property or method "car" is not defined on the instance
but referenced during render. Make sure that this property is
reactive, either in the data option, or for class-based components, by
initializing the property.
When i try to execute <td>{{ car.ContractDate }}</td> inside my v-for i don't have any issues.
I created a rough example based on the information you gave:
new Vue({
el: '#app',
data() {
return {
cars: [{
name: 'Car X',
contractDate: '9/17/2016, 1:21:34 PM'
},
{
name: 'Car Y',
contractDate: '9/17/2020, 1:21:34 PM'
}]
}
},
methods: {
compareDate(d) {
return (new Date(d)).getTime() > (new Date()).getTime();
}
}
});
.active {
color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app" v-cloak>
<table>
<tbody>
<tr v-for="car in cars">
<td>{{car.name}}</td>
<td>
<div :class="{ active: compareDate(car.contractDate) }">
{{car.contractDate}}
</div>
</td>
</tr>
</tbody>
</table>
</div>
Notes
Instead of doing the comparison in the actual template, I elected to do it in a method - it felt cleaner
I'm using object syntax for the class bind, again, purely preference, you could use a ternary if you so chose to.
Hope this helps!
Based on your code : https://pastebin.com/MmBcp0Bx
you should remove this line:
<div v-if="Date.now() <= new Date(car.ContractDate)">if true, add class to this div</div>

use vue and v-model with a css specific checkbox

I am migrating some jQuery code to Vue. We have a part that is like the following:
<td>
<p>
<input class="select-one checkbox-default-input" type="checkbox" :value="placement.id" v-model="checkedPlacements">
<label for="select-clicks" class="checkbox-default" #click="setValue"></label>
</p>
</td>
ie I am using a label to adjust the UI of an input similar to this: Pure CSS Checkbox Image replacement
how would I associate my v-model with the correct input value?
<td>
<p>
<input id="select-clicks" class="select-one checkbox-default-input" type="checkbox" :checked="placement.id" #input="toggleCheckbox">
<label for="select-clicks" class="checkbox-default"></label>
</p>
</td>
I have added an id attribute to the input tag which corresponds to the label for attribute.
:checked="placement.id" - Here placement.id should correspond to a boolean value stored on your vue component's data property.
#input="toggleCheckbox" - this should be a simple method on your vue component that toggles the value. Something like this:
toggleCheckbox() {
this.placement.id = !this.placement.id;
},
You can then apply conditional classes to the element using the :class bindings. You can read more about them here: https://v2.vuejs.org/v2/guide/class-and-style.html
As #GustavMahler pointed out, Vue Guide: Form Input binding shows how to reach the goal.
#GustavMahler already provided the solution by v-bind and v-on (actually v-model is one syntax sugar which does similar things. one simple explanation at here),
Below is the steps uses v-model:
add attr=id for the checkbox, so label know which checkbox it links.
v-model to one data property which is one Array. (if default value is one Boolean, the value will be one Boolean value (true/false), it ignores the value it binds (please check the third checkbox).)
click the checkbox(label), it will toggle the values to the array.
Below is one demo (the CSS part is copied from the link in the question).
new Vue({
el: '#app',
data() {
return {
placement: {id: 'value1'},
checkedPlacements: [], // default is one Array
checkedPlacement: false // default is one Boolean
}
},
watch: {
checkedPlacements: function (newVal) {
console.log('changed', newVal)
},
checkedPlacement: function (newVal) {
console.log('changed', newVal)
}
}
})
input[type=checkbox] {
display:none;
}
input[type=checkbox] + label
{
background: #999;
height: 16px;
width: 16px;
display:inline-block;
padding: 0 0 0 0px;
}
input[type=checkbox]:checked + label
{
background: #0080FF;
height: 16px;
width: 16px;
display:inline-block;
padding: 0 0 0 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<p>
<input class="select-one checkbox-default-input" type="checkbox" :value="placement.id" v-model="checkedPlacements" id="select-clicks1">
<label for="select-clicks1" class="checkbox-default"></label>
<input class="select-one checkbox-default-input" type="checkbox" :value="'value2'" v-model="checkedPlacements" id="select-clicks2">
<label for="select-clicks2" class="checkbox-default"></label>
</p>
<p>
<input class="select-one checkbox-default-input" type="checkbox" :value="placement.id" v-model="checkedPlacement" id="select-clicks3">
<label for="select-clicks3" class="checkbox-default"></label>
</p>
</div>

vuejs - "editing" html inside variable

I've got a variable which has html inside. This is for my wysiwyg editor.
data () {
return {
HTMLtext: "<p style="text-align: center;"><b>Hospital</b></p><p>
</p><p style="text-align: center;"> <b>Physician</b></p>
<p></p><p style="text-align: center;"> City <b>New York</b>",
Place: "London"
}
}
Now, I want to change this HTMLtext variable in some places. For example I've got variable called place:
Place: "London"
and I want to replace <b>New York</b> with Place variable into <b>London</b>
What should I do?
What is the best approach?
Is it generally safe?
Is this a good practice?
If you make HTMLtext a computed, it can compose the text based on the variables. Template strings are a nice way to interpolate variables into strings.
Here's an example of what I'm suggesting. I don't know if that will work in your circumstance because I don't know where HTMLtext comes from or how you know that New York is in it to be replaced.
new Vue({
el: '#app',
data: {
place: 'New York'
},
computed: {
htmlText() {
return `<p style="text-align: center;"><b>Hospital</b></p><p>
</p><p style="text-align: center;"> <b>Physician</b></p>
<p></p><p style="text-align: center;"> City <b>${this.place}</b>`;
}
}
});
<script src="//unpkg.com/vue#latest/dist/vue.js"></script>
<div id="app">
Place: <input v-model="place">
<div v-html="htmlText"></div>
</div>

How to apply dynamic CSS class in 'v-for' according to the value of the element in Vue.js?

I want to apply positive or negative class as per the value in element which is part of v-for loop.
Below given is the template
<tr v-for='change in dispData'>
<td>{{value}}</td>
</tr
I want to add class named 'positive' if 'value>0' , else apply class 'negative'.
What is the best way to do this?
Try the following. You can bind a class and thus use if statements.
<tr v-for='change in dispData'>
<td :class="{positive: value > 0, negative: value === 0}">{{value}}</td>
</tr>
https://v2.vuejs.org/v2/guide/class-and-style.html
You can achieve this with Class and Style Bindings.
Some notes (you will read this on the documentation):
If you have some classes (like in the example: font-size-20) and add more dinamically with :class, then Vue will merge all of it, so you always will have the default classes defined with the standard html syntax.
If your classes to add have special characters (like again font-size-20, basically if are not one-word classes) then you must wrap it as a string. ie: :class="{'font-size-20': someCondition}"
Basic example:
new Vue({
el: '#example',
data: {
values: [1, 4, 0, -2, 20, -3, 0]
}
})
.font-size-20 {
font-size: 20px;
}
.positive {
color: green;
}
.negative {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="example">
<ul>
<li
class="font-size-20"
v-for="val in values"
:class="{positive: val > 0, negative: val <= 0}"
> {{ val }} </li>
</ul>
</div>

disable checkbox after checking two vuejs

how can I disable an array of checkbox after checking a number of checkboxes from that array ?
Is there a way to do this in vuejs or I will need a watcher for that?
In fact I tried to watch the 'ord.sauce' but I couldnt make it work
this is the component
Vue.component('sauce-view', {
props: ["sauce", "ord", "name"],
template: '
<div class="">
<input type="checkbox" :name="name" :value="sauce.id" v-model="ord.sauce">
{{sauce.name}}
<label >
<img :src="sauce.link" >
</label>
</div>',
});
This is the HTML
<table>
<tr v-for="o in order" >
{{o.sauce}}
<td v-for="sauce in les_sauces" >
<sauce-view :sauce="sauce" :ord="o" :name="o.produit+o.num">
</sauce-view>
</td>
</tr></table>
I have created a simple fiddle that should illustrate the logic behind it: https://jsfiddle.net/UDany/r9q4x85d/
This would be the markup:
<div id="demo">
<template v-for="(item, index) in itemlist">
<label><input type="checkbox" :value="index" name="condiment" v-model="selectedItems" :disabled="selectedItems.length >= max && selectedItems.indexOf(index) == -1" /> {{item}}</label>
</template>
<div>{{selectedItems.join(', ')}}</div>
</div>
And your JS would look like this:
var demo = new Vue({
el: '#demo',
data: {
selectedItems: [],
itemlist: [
"Mayo",
"Ketchup",
"Mustard",
"Honey"
],
max: 2
}
})
Since you're not using the input directly into the main code you'll need to proxy the properties through/from it (possibly wiring events for "select" and "unselect" and having a property for "disabled")
I've answered a question very similar to this here:
Vue.js limit selected checkboxes to 5
In your situation it's a little more involved since you're handling the value in a component. It's hard to tell your exact needs so I'd clear up your question a little more.