Change vuetify v-chip color dynamically - vue.js

I am new to vuejs and vuetify.
I was following youtube course on vuetify and he set the v-chip color in the following manner.
<v-flex xs2 sm4 md2>
<div class="right">
<v-chip
small
:class="`${project.status} white--text my-2 caption`"
>{{ project.status }}</v-chip>
</div>
</v-flex>
and style is;
.v-chip.complete {
background: #3cd1c2;
}
.v-chip.ongoing {
background: #ffaa2c;
}
.v-chip.overdue {
background: #f83e70;
}
I can see the project status text is correctly set. For some reason the color is not getting set in v-chip.
When I inspect the object I found it has following style set
v-chip v-chip--no-color theme--light v-size--small ongoing white--text my-2 caption
For some reason no-color getting set.
Can someone provide some advice on this?

You can use the :class binding directly with the data prop in vue; it can also be used in conjunction with the regular class attribute.
var app = new Vue({
el: '#app',
data: {
projects: [{
status: 'ongoing'
}, {
status: 'complete'
}, {
status: 'overdue'
}]
}
})
#chips-container .v-chip.complete {
background: #3cd1c2;
}
#chips-container .v-chip.ongoing {
background: #ffaa2c;
}
#chips-container .v-chip.overdue {
background: #f83e70;
}
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#5.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-flex xs2 sm4 md2>
<div class="right" id="chips-container">
<v-chip v-for="project in projects" small :class="project.status" class="white--text my-2 caption">{{ project.status }}</v-chip>
</div>
</v-flex>
</div>
EDIT: Updated snipped to use vuetify

Simply use the tenary operator like this
<v-chip
label
outlined
pill
:color="project.status==='complete'?'green':project.status==='ongoing'?'blue':'orange'"
>
{{project.status}}</v-chip>

You can give your v-chip an id.
<v-chip id="chip" small :class="`${project.status} white--text caption my-2`">{{project.status}}</v-chip>
<style>
#chip.v-chip.complete {background: #00cc00;}
#chip.v-chip.ongoing{background: #0099ff;}
#chip.v-chip.overdue {background: #ff0000;}
</style>

You can user "active-class", api documentation
<v-flex xs2 sm4 md2>
<div class="right">
<v-chip small active-class="white--text my-2 caption">{{project.status}}</v-chip>
</div>
</v-flex>

Related

Add animation to append-icon in v-text-field

When a new account is registered, I display login and password details on the screen. The user can copy login&passwod details to clipboard and I would like to run animation when the append-icon (scale up, increase font or replace with another icon) is clicked. What would be the right way to do that?
<template>
<v-card class="col-12 col-md-8 col-lg-6 p-6 px-16" elevation="4">
<div class="title h2 mb-10 text-uppercase text-center">
Success
<v-icon color="green" x-large>
mdi-check-circle
</v-icon>
</div>
<v-text-field
:value="newAccount.login"
label="Login"
outlined
readonly
append-icon="mdi-content-copy"
ref='login'
#click:append="copy('login')"
></v-text-field>
<v-text-field
:value="newAccount.password"
label="Password"
outlined
readonly
append-icon="mdi-content-copy"
ref='login'
#click:append="copy('login')"
></v-text-field>
</v-card>
</template>
<script>
methods: {
copy(field) {
const input = this.$refs[field].$refs.input
input.select()
document.execCommand('copy')
input.setSelectionRange(0,0)
// apply append-icon animation
}
}
</script>
There is multiple answers to this, but to answer one of them: "replacing icon" would be pretty straight forward.
You would have to change the append-icon prop do be dynamic :, then assign a variable to it like copyIcon. You will then update this variable depending on the state of the copy.
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: {
copyIcon: 'mdi-content-copy',
newAccount: {
login: 'GhostDestroyer69',
password: '',
},
},
methods: {
copy(field) {
const input = this.$refs[field].$refs.input
input.select()
document.execCommand('copy')
input.setSelectionRange(0, 0)
// Set icon to check
this.copyIcon = 'mdi-check'
// Reset icon to copy after 1 second
setTimeout(() => {
this.copyIcon = 'mdi-content-copy'
}, 1000)
}
}
})
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-card class="col-12 col-md-8 col-lg-6 p-6 px-16" elevation="4">
<v-text-field
:value="newAccount.login"
label="Login"
outlined
readonly
:append-icon="copyIcon"
ref='login'
#click:append="copy('login')"
></v-text-field>
</v-card>
</div>
mdi has animation helpers like
append-icon="mdi-content-copy mdi-spin"
For example.

v-toolbar not behaving responsively

I am trying to implement vuetify in my project. I am newbie in VueJs & vuetify too.
I am trying to use a toolbar which contains a rounded image on the right corner. But, It is not responsive. When i open developer option and decrease the screen size to that of mobile. The rounded image does not render.
I tried using plain tags but it is actually disrupting the layout.
Here is the code
VuetifyTest.vue:
<template lang="html">
<v-toolbar>
<v-toolbar-side-icon>
<!-- <v-img src="../assets/mad_logo.png" aspect-ratio="1.7"></v-img> -->
</v-toolbar-side-icon>
<v-toolbar-title>Title</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items class="hidden-sm-and-down">
<v-layout
align-center
justify-space-around
wrap
>
<v-avatar
:tile= false
size="36"
color="grey lighten-4"
>
<img src="../assets/static.jpeg" alt="avatar">
</v-avatar>
</v-layout>
</v-toolbar-items>
</v-toolbar>
</template>
<script lang="js">
export default {
name: 'VuetifyTest',
props: [],
mounted() {
},
data() {
return {
}
},
methods: {
},
computed: {
}
}
</script>
<style scoped >
</style>
This is how it looks like in laptop screen
This is how it looks like in mobile screen
How do i change the code to make it responsive
PS: I also tried reducing the screen size while viewing here in reduced screen size.
Even though it showed like this..
Even though the official documentation have this problem?
How do i make it responsive..
thanks!
You do not have to specify v-layout within the v-toolbar - if you remove the v-layout and replace it with just the v-avatar, it works.. Examples are below:
[CodePen Mirror]
Snippet:
new Vue({ el: "#app" })
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify/dist/vuetify.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons" rel="stylesheet" />
<link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="stylesheet" />
<div id="app">
<v-app>
<v-toolbar>
<v-toolbar-side-icon>
</v-toolbar-side-icon>
<v-toolbar-title>Title</v-toolbar-title>
<v-spacer></v-spacer>
<v-avatar :tile=false size="36" color="grey lighten-4">
<img src="https://i.pravatar.cc/300?img=3" alt="avatar">
</v-avatar>
</v-toolbar>
</v-app>
</div>

How to add a class and then remove that same class in the vuejs?

I have the following div:
<div class="col bg-color-red-4">
<a href="#" v-on:click="showMobileMenu = !showMobileMenu">
<i class="hamburger hamburger--3dx " v-bind:class="{ 'is-active': showMobileMenu }" >
<span class="hamburger-box">
<span class="hamburger-inner"></span>
</span>
</i>
</a>
<p>3DX</p>
</div>
data(){
return {
showMobileMenu: false
}
},
That is visually like this:
basically it's a button that allows me to open the left panel:
When you click on the button you add the class 'is-active' that allows the change of form, leaving it like this:
and it effectively opens the left panel, but after turning off the left panel, that is, returning to the view that I was in, this one finds the class added.
then I need that when I click, I change the shape to an "X", when I open the left panel, but when I come back I do not have the form "X", that is, it does not contain the class 'is-active' anymore
Beforehand thank you very much.
At first read the official docs:
[https://v2.vuejs.org/v2/guide/class-and-style.html#ad][1]
At second - check Matt Oestreich's answer
At third - you can also bind classes to the variables like this:
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
/>
And in a Vue.js script:
data: {
isActive: true,
hasError: false
}
You can bind to the class attribute and supply specific classes that way..
[CodePen Mirror]
Code Snippet:
const vm = new Vue({
el: "#app",
data: {
status: false,
bars: "fa fa-bars",
times: "fa fa-times",
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.5.14/vuetify.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/font-awesome#4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.5.6/dist/vuetify.min.css" rel="stylesheet" />
<div id="app">
<v-app>
<v-content>
<v-container>
<i
style="cursor:pointer;"
:class="status ? times : bars"
#click="status = !status"
></i>
<h1>Click The Icon</h1>
<h3>It is currently {{ status ? 'open' : 'closed' }}</h3>
</v-container>
</v-content>
</v-app>
</div>

Custom attribute name without value - Vue.js

I am using Bootstrap-Vue Accordions in my project, and I want to dynamically render a loop of accordions.
The problem is that it has an attribute v-b-toggle.accordionName, which has no value (or this is what I think).
I need to find a way to bind this attribute's 'name' dynamically.
<b-card no-body v-for="seminar in seminars" :key="seminar.name">
<b-card-header role="tab">
<b-button block v-b-toggle.( ?? )>{{seminar.title}}</b-button>
</b-card-header>
<b-collapse :id="seminar.name" role="tabpanel">
<b-card-body>
Hey there!
</b-card-body>
</b-collapse>
</b-card>
I tried to use v-b-toggle.seminar.name, but clearly failed.
Also tried to use v-bind="toggle", and have a data of toggle={'v-b-toggle.seminarOne': true}, but also failed.
Finally, I know it can be done using custom directives, but I am looking for another local way, if possible.
Thanks.
the v-b-toggle attribute is already dynamic. you can simply use it like this:
new Vue({
el: '#app',
data:{
seminars:[
{
title:'seminar1',
name:'seminar1',
},
{
title:'seminar2',
name:'seminar2',
}
]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://unpkg.com/bootstrap-vue#2.0.0-rc.14/dist/bootstrap-vue.css" rel="stylesheet"/>
<link href="https://unpkg.com/bootstrap#next/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/bootstrap-vue#2.0.0-rc.14/dist/bootstrap-vue.js"></script>
<div id="app">
<b-card no-body v-for="seminar in seminars" :key="seminar.name">
<b-card-header role="tab">
<b-button block v-b-toggle="seminar.name">{{seminar.title}}</b-button>
</b-card-header>
<b-collapse :id="seminar.name" role="tabpanel">
<b-card-body>
Hey there! i am {{seminar.name}}
</b-card-body>
</b-collapse>
</b-card>
</div>
https://jsfiddle.net/aep6hqd1/3/

Can't get the correct value of scrollHeight for a textarea - VueJs, Vuetify

Am trying to get the value scrollHeight of a texteara filed, the problem is when i use the document object : document.querySelector("#textarea-element").scrollHeight, i have a correct value ,
but when i’ve tried to do it with refs the value is wrong and didn’t change.
I’ve made a detailed jsfiddle for these behaviors please see below:
new Vue({
el: '#app' ,
data: {
height: 'auto',
scrollHeightUsingRefsVuejs:'',
scrollHeightUsingDocumentObject: ''
},
methods:{
resizeTextarea (e) {
this.scrollHeightUsingRefsVuejs = this.$refs.messageBox.$el.scrollHeight
this.scrollHeightUsingDocumentObject = document.querySelector("#textarea-element").scrollHeight
console.log(this.scrollHeightUsingRefsVuejs, this.scrollHeightUsingDocumentObject)
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<link href="https://unpkg.com/vuetify#1.0.11/dist/vuetify.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/vuetify#1.0.11/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-content>
<v-container>
<v-text-field
color="cyan darken"
label="Text field"
multi-line
rows="2"
placeholder="Start typing..."
ref="messageBox"
#keydown.native="resizeTextarea"
:style="{height: height}"
id="textarea-element"
></v-text-field>
<p>
Scroll Height Using Refs Vuejs : <strong>{{ scrollHeightUsingDocumentObject}}</strong>
</p>
<p>
<span style="color:red">(Wrong)</span> Scroll Height Using Refs Vuejs : <strong>{{ scrollHeightUsingRefsVuejs }}</strong>
</p>
</v-container>
</v-content>
</v-app>
</div>
(To see the value of scrollHeight type anything if the textearea filed)
The this.$refs.messageBox.$el.scrollHeight refers to parent node input-group generated by Vuetify that’s way the value seems wrong , all we need just to add a selector to tearea node like this this.$refs.messageBox.$el.querySelector('textarea').scrollHeight