How to remove vuetify card on clicking a button - javascript

I have added a vuetify card and a button on it. I want that when the button is clicked, the card disappears. How can I do that?
Below is how my component looks like. I want to add a method to do so but don't know what the method will be.
<template>
<div class="notifications">
<v-layout>
<v-flex xs12 sm6 offset-sm3>
<v-card flat color="green">
<v-card-title primary-title>
<div>
<h3 class="headline">Neu Benutzer angelegt</h3>
<div> {{ card_text }} </div>
</div>
</v-card-title>
<v-card-actions>
<div class="close"><v-btn #click="removeMessage(2)">Ok</v-btn></div>
</v-card-actions>
</v-card>
</v-flex>
</v-layout>
</div>
</template>
<script>
export default {
data () {
return {
card_text: 'Success!'
}
},
methods: {
removeMessage(seconds) {
},
},
};
</script>

You can hide it with v-if and a boolean flag:
<template>
<div class="notifications" v-if="show">
<v-layout>
<v-flex xs12 sm6 offset-sm3>
<v-card flat color="green">
<v-card-title primary-title>
<div>
<h3 class="headline">Neu Benutzer angelegt</h3>
<div> {{ card_text }} </div>
</div>
</v-card-title>
<v-card-actions>
<div class="close"><v-btn #click="removeMessage(2)">Ok</v-btn></div>
</v-card-actions>
</v-card>
</v-flex>
</v-layout>
</div>
</template>
<script>
export default {
data () {
return {
card_text: 'Success!',
show:true;
}
},
methods: {
removeMessage(seconds) {
setTimeout(()=> this.show = false, seconds * 1000);
},
},
};
</script>

You can also use v-show and make something like this: CodePen

Related

How to set parent component data from child component in vuejs

Below is the parent component and child component. I am trying to access tabs_value data in the parent component from the child component but it is returning as undefined.
this.$parent.tabs_value returns as undefined when I try to access it inside the run method in the child component.
Please help me find where I am going wrong? Below is the code
Parent Component
<template>
<div>
<v-layout row wrap>
<v-flex xs12 sm12 lg12>
<div>
<v-card>
<v-tabs v-model="tabs_value"
color="black"
centered
show-arrows
>
<v-toolbar-title>Custom</v-toolbar-title>
<v-spacer></v-spacer>
<v-tab href="#build">Build</v-tab>
<v-tab href="#run">Run</v-tab>
</v-tabs>
<v-tabs-items v-model="tabs_value">
<v-tab-item value="#build" id="build">
<Build ref="build_reports" />
</v-tab-item>
<v-tab-item value="#run" id="run">
<Run :reports="reports" ref="run_reports" />
</v-tab-item>
</v-tabs-items>
</v-card>
</div>
</v-flex>
</v-layout>
</div>
</template>
<script>
import Build from 'views/build.vue'
import Run from 'views/run.vue'
import URLs from 'views/routes'
export default {
components: {
Build,
Run
},
data: function() {
return {
tabs_value: 'build',
isLoaded: true,
reports: []
}
},
created() {
this.fetch();
},
methods: {
fetch() {
this.$axios.get(URLs.REPORTS_URL)
.then(response => {
this.reports = response.data
});
}
}
};
</script>
Child Component run.vue
<template>
<div>
<v-layout row wrap>
<v-flex xs12 sm12 lg12>
<div>
<v-card>
<div>
<v-data-table
:headers="headers"
:items="reports"
hide-default-footer
:mobile-breakpoint="0">
<template slot="item" slot-scope="props">
<tr>
<td>{{props.item.name}}</td>
<td>
<div>
<v-tooltip attach left>
<template v-slot:activator="{ on, attrs }">
<a v-bind="attrs" v-on="on"
class="" href='javascript:void(0);'
#click="run(props.item)"><i small slot="activator" dark color="primary" class="fas fa-play"></i></a>
</template>
<span>Run</span>
</v-tooltip>
</div>
</td>
</tr>
</template>
<template slot="no-data" >
<v-alert id='no-data' :value="true" color="error" icon="warning">
No Reports Yet
</v-alert>
</template>
</v-data-table>
</div>
</v-card>
</div>
</v-flex>
</v-layout>
</div>
</template>
<script>
import URLs from 'views/routes'
export default {
props: ['reports'],
data: function() {
return {
headers: [
{ text: 'Name', value: 'name', sortable: false },
{ text: 'Actions', sortable: false }
],
}
},
methods: {
run(report) {
debugger
// this.$parent.tabs_value returns as undefined
}
}
}
</script>
you can use component events i.e $emit.
Below is example which will tell you how to use $emit. (https://vuejs.org/guide/components/events.html#emitting-and-listening-to-events)
Parent Component
<template>
<ChildComponent #updateTabsValue="updateTabsValue"/>
</template>
<script>
export default {
data(){
return {
tabsValue: 'tabs',
};
},
methods:{
updateTabsValue(val){
this.tabsValue = val;
}
},
}
</script>
Child Component
<template>
<button #click="$emit('updateTabsValue','newVal')"/>
</template>

v-card is not being shown completly

I am working with vuetify and I want to implement a Stepper.
Within the stepper I want to have v-card which once clicked on read more would open. So far the functions are working.
The problem is that when I only open a card - meaning in the index.vue I put the card component instead of the stepper, the card opens reacts perfectly. But, when the card is within the stepper component, when I press on read more it is only shown a part of it. I guess some element is having a fixed size and wont resize, but I cannot figure it out where exactly the problem is. Any help is welcomed!
My index.vue file looks like this:
<template>
<v-container>
<v-app>
<div>
<Stepper/>
</div>
</v-app>
</v-container>
</template>
<script>
import Stepper from "../components/Stepper.vue";
export default {
data: () => ({
}),
components: {Stepper }
}
</script>
The Stepper.vue component looks like this:
<template>
<v-stepper v-model="e6" vertical ref="stepper">
<!--- Step 1-->
<v-stepper-step :complete="e6 > 1" step="1">
</v-stepper-step>
<v-stepper-content step="1">
<Card1 />
</v-stepper-content>
<!--- Step 2-->
<v-stepper-step :complete="e6 > 2" step="2">
</v-stepper-step>
<v-stepper-content step="2">
<Card2 />
</v-stepper-content>
<!--- Step 3-->
<v-stepper-step :complete="e6 > 3" step="3">
</v-stepper-step>
<v-stepper-content step="3">
<Card2 />
</v-stepper-content>
</v-stepper>
</template>
The cards inside are from format identical only the text is different. Hence I will post only one card:
<template>
<v-hover >
<template v-slot:default="{ hover }">
<v-card class="mx-auto">
<v-img class="white--text" src="picture1.png" width="300" height="169">
<v-card-title class="text-h5">
{{ $t('welcome_hello') }}
</v-card-title>
</v-img>
<v-card-actions>
<v-btn text color="teal accent-4" #click="openCard()">
Learn More
</v-btn>
</v-card-actions>
<v-expand-transition>
<v-card v-if="reveal" class="transition-fast-in-fast-out v-card--reveal" style="height: 100%;">
<v-card-text class="pb-0">
<p class="text-h4 text--primary">
{{ $t('welcome_message1') }}
</p>
<p>{{ $t('welcome_message2') }}</p>
<p>{{ $t('welcome_message3') }}</p>
</v-card-text>
<v-card-actions class="pt-0">
<v-btn text color="teal accent-4" #click="nextStep()">
Next
</v-btn>
</v-card-actions>
</v-card>
</v-expand-transition>
</v-card>
</template>
</v-hover>
</template>
<script>
export default {
data: () => ({
reveal: false,
}),
methods: {
openCard() {
this.reveal = true
},
closeCard() {
this.reveal = false
},
completedCard(){
},
nextStep() {
this.closeCard()
this.$root.$emit('nextStepFunction') //like this
},
}
}
</script>
<style>
.v-card--reveal {
bottom: 0;
opacity: 1 !important;
position: absolute;
width: 100%;
}
</style>
You should give your v-card a height and then overflow to scroll.
<v-card height="450" style="overflow-y: scroll; overflow-x: hidden">
// Your card body
</v-card>

Adding values to an array inside hash in vue not working

I am trying add the feature to add multiple workers when clicked on Add worker. The issue I am facing here is that when I put workers array inside the management then this feature doesn't work. But if puts workers array outside the management hash then it works. But I want it to be inside the management issue. I am getting the error cannot read the property push.
<div v-for="(worker, index) in management.workers" :key="index">
<v-container fluid>
<v-layout row wrap>
<v-flex xs12 md6 class="add-col-padding-right info-align">
<v-text-field
label='Name'
v-model="worker.name"
>
</v-text-field>
</v-flex>
<v-flex xs12 md6 class="add-col-padding-left info-align">
<v-text-field
label='Hours of work'
v-model="worker.hours_of_work"
>
</v-text-field>
</v-flex>
</v-layout>
<v-btn class="red-button next-btn" #click="deleteRow(index)">Delete</v-btn>
</v-container>
</div>
<v-btn class="red-button next-btn" #click="addRow">Add Workers</v-btn>
<script>
export default {
data () {
return {
management: {
workers: []
}
}
}
methods: {
addRow() {
this.management.workers.push({
name: '',
hours_of_work: '',
total: ''
})
},
deleteRow(index) {
this.management.workers.splice(index,1)
}
}
}
</script>
Code seems to work below:
new Vue({
el: "#app",
vuetify: new Vuetify(),
data() {
return {
management: {
workers: []
}
}
},
methods: {
addRow() {
this.management.workers.push({
name: '',
hours_of_work: '',
total: ''
})
},
deleteRow(index) {
this.management.workers.splice(index, 1)
},
getRows(){
console.clear()
console.log(this.management.workers)
}
}
});
<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.2.20/dist/vuetify.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.2.20/dist/vuetify.min.js"></script>
<div id="app">
<v-app>
<div v-for="(worker, index) in management.workers" :key="index">
<v-container fluid>
<v-layout row wrap>
<v-flex xs12 md6 class="add-col-padding-right info-align">
<v-text-field label='Name' v-model="worker.name">
</v-text-field>
</v-flex>
<v-flex xs12 md6 class="add-col-padding-left info-align">
<v-text-field label='Hours of work' v-model="worker.hours_of_work">
</v-text-field>
</v-flex>
</v-layout>
<v-btn class="red-button next-btn" #click="deleteRow(index)">Delete</v-btn>
</v-container>
</div>
<v-btn class="red-button next-btn" #click="addRow">Add Workers</v-btn>
<v-btn class="red-button next-btn" #click="getRows">View Workers</v-btn>
</v-app>
</div>

Show mutiple v-dialog boxes with different content in vue.js

Hii I am working on the Vue.js template and I stuck at a point where I need to show dynamic v-dialog using looping statement but now it shows all.
Dom:
<template v-for="item of faq">
<div :key="item.category">
<h4>{{ item.heading }}</h4>
<div v-for="subitems of item.content" :key="subitems.qus">
<v-dialog
v-model="dialog"
width="500"
>
<template v-slot:activator="{on}">
{{subitems.qus}}
</template>
<v-card>
<v-card-title
class="headline grey lighten-2"
primary-title
>
Privacy Policy
</v-card-title>
<v-card-text>
{{ subitems.ans }}
</v-card-text>
<v-divider></v-divider>
</v-card>
</v-dialog>
</div>
</div>
</template>
Script:
export default {
data: () => ({
faq,
dialog:false,
}),
}
I do not understand how I can do this. If I click on one button then it shows all.
There must a design a pattern for this one but a quick solution would be to create array of booleans for v-models of dialogs. something like below
export default {
data: () => ({
faq,
dialog: [] // Array instead of Boolean.
}),
}
and
<template v-for="item of faq">
<div :key="item.category">
<h4>{{ item.heading }}</h4>
<div v-for="(subitems, index) of item.content" :key="subitems.qus">
<v-dialog
v-model="dialog[index]"
width="500"
>
<template v-slot:activator="{on}">
{{subitems.qus}}
</template>
<v-card>
<v-card-title
class="headline grey lighten-2"
primary-title
>
Privacy Policy
</v-card-title>
<v-card-text>
{{ subitems.ans }}
</v-card-text>
<v-divider></v-divider>
</v-card>
</v-dialog>
</div>
</div>
</template>
Brother, you are doing a very small mistake, you should not keep your v-dialog component inside your loop, take this out from loop block and don't take dialog as empty array keep it false.

Avatar picker with Nuxt & Vuetify

I'm having some issues to make an avatar picker works...
After click to select the avatar in not being replaced and with the error TypeError: Cannot read property 'src' of undefined at VueComponent.selectAvatar
I'm currently using Vuetify and the v-avatar component with a v-for to load all the images.
Any idea how to make it work?
HTML
<v-flex xs12 pt-0 pb-0>
<h1 class="title mb-4">User Details</h1>
<v-avatar
size="100px"
>
<img
:src="this.selectedAvatar"
alt="Avatar"
>
</v-avatar>
</v-flex>
<v-flex x12>
<v-btn
color="primary"
flat="flat"
small
#click="selectAvatarDialog = true"
class="avatar-btn"
>
Update avatar
</v-btn>
</v-flex>
<v-dialog
v-model="selectAvatarDialog"
max-width="80%"
>
<v-card>
<v-container fluid pa-2>
<v-layout row wrap align-center justify-center fill-height>
<v-flex xs6 sm4 md3 lg2 my-2 class="text-xs-center"
v-for="(avatar,i) in avatars"
:key="i">
<v-img
:src="avatar.src"
aspect-ratio="1"
width="100px"
max-width="100px"
min-width="100px"
class="dialog-avatar-img"
#click="selectAvatar()"
></v-img>
</v-flex>
</v-layout>
<v-card-actions class="mt-2">
<v-spacer></v-spacer>
<v-btn
color="primary"
flat="flat"
#click="selectAvatarDialog = false"
>
Cancel
</v-btn>
</v-card-actions>
</v-container>
</v-card>
</v-dialog>
JS
export default {
layout: 'default',
data() {
return {
selectAvatarDialog: false,
avatars: [
{src: require('#/assets/images/avatar-01.png') },
{ src: require('#/assets/images/avatar-02.png') },
{ src: require('#/assets/images/avatar-03.png') },
{ src: require('#/assets/images/avatar-04.png') },
{ src: require('#/assets/images/avatar-05.png') }
],
selectedAvatar: require('#/assets/images/avatar-01.png'),
}
},
methods: {
selectAvatar(){
this.selectedAvatar = this.avatar.src
console.log('Avatar selected')
}
}
}
Thank you
The problem is in your selectAvatar method where you are trying to use 'this.avatar' but it doesn't exist. The avatar in your for loop isn't passed to your script. You should do like this:
<v-img
...
#click="selectAvatar(i)"
></v-img>
And in your script:
methods: {
selectAvatar(i){
this.selectedAvatar = this.avatars[i].src
console.log('Avatar selected')
}
}

Categories

Resources