How can I custom datepicker in the vuetify? - vue.js

I want to make datetimepicker like this : https://vuetifyjs.com/en/getting-started/consulting-and-support. If you click "2 Hour Consulting Session", it will display datetimepicker like this : https://ibb.co/kHrbHTG. I want to make like that. But I don't find the component datetimepicker in the documentation. The docs : https://vuetifyjs.com/en/components/date-pickers
Based on my analysis, it uses datepicker modal. not the datepimepicker. The timepicker is only customized using the outline button. but I am confused how to place the outline button next to the datepicker
My script like this :
<template>
<v-row>
<v-col cols="12" sm="6" md="4">
<v-dialog
ref="dialog"
v-model="modal"
:return-value.sync="date"
persistent
width="290px"
>
<template v-slot:activator="{ on }">
<v-btn color="success" dark v-on="on">Call datepicker</v-btn>
</template>
<v-date-picker v-model="date" scrollable>
<div class="flex-grow-1"></div>
<v-btn text color="primary" #click="modal = false">Cancel</v-btn>
<v-btn text color="primary" #click="$refs.dialog.save(date)">OK</v-btn>
</v-date-picker>
</v-dialog>
</v-col>
</v-row>
</template>
<script>
export default {
data: () => ({
modal: false,
}),
}
</script>
Is it possible to customize the datepicker to be like that?

That Datepicker is not part of Vuetify. That screenshot you took is in fact an <iframe> of the https://calendly.com/ website, which looks like a website for managing appointments. So that calendar is basically just custom CSS made by that company, nothing to do with Vuetify.

Related

What is the purpose of {attrs} parameter in v-slot: activator?

I created a simple v-dialog using Vuetify. It uses v-slot:activator with destructured data, namely {on, attrs }. While I can understand on part then I can't get what's the purpose of attrs? If I remove it then dialog still works fine. How it works and what is it for?
Here some basic example from Vuetify docs:
<template>
<div class="text-center">
<v-dialog
v-model="dialog"
width="500"
>
<template v-slot:activator="{ on, attrs }">
<v-btn
color="red lighten-2"
dark
v-bind="attrs"
v-on="on"
>
Click Me
</v-btn>
</template>
<v-card>
<v-card-title class="text-h5 grey lighten-2">
Privacy Policy
</v-card-title>
<v-card-text>
Lorem ipsum dolor sit amet...
</v-card-text>
</v-card>
</v-dialog>
</div>
</template>
<script>
export default {
data () {
return {
}
},
}
</script>
Its purpose is to give you set of attributes/props that you can easily bind with v-bind="attrs" (using object binding syntax) to the component you choose as an activator
In the case of v-dialog its content is generated by default implementation of activatable mixin and generates some ARIA attribute but the component using the mixin can override or extend it (as for example v-menu does)

Instance of v-dialog is generated twice – Vuetify

I have a problem with <v-dialog> that appears everywhere in my Vue.js application using Vuetify.js.
Every <v-dialog> is loading twice on the page. You can see it by looking at how it appears:
If I close one dialog the other dialog stays visible and works exactly like the first. It seems like Vue is generating two instances of it.
The code of the dialog isn't the issue, I think:
<v-dialog
v-model="dialog"
persistent
hide-overlay
no-click-animation
>
<v-card>
<v-card-title>Text</v-card-title>
<v-card-text>
<p class="subtitle-1">Some more text</p>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="primary"
depressed
>
Next
<v-icon right>mdi-chevron-right</v-icon>
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
The v-model is declared in data():
export default {
data() {
return {
dialog: true,
};
},
}
Any help is appreciated! Thanks.

how I can change the background color by clicking button using vuetify?

Here, I have used vuetify to create buttons which pop up dialog box that contains buttons with different colors and I want to use buttons to change the background color of navigation and menu bar but due to my limited knowledge on vue and vuetify I am not able to change my background color. Can anyone help me???
My code is here:
<template>
<v-row justify="center">
<v-dialog v-model="dialog" persistent max-width="600px" class="pa-md-4 mx-lg-auto">
<template v-slot:activator="{ on }">
<v-btn color="primary" dark v-on="on">Theme</v-btn>
</template>
<div class="text-center">
<v-btn v-for="(item) in colors" :color="item" dark large class="ma-2" style="width:100px;">
<span class="text-truncate" style="width:120px;">
{{item.replace(/-/g, '')}}
</span>
</v-btn>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="blue darken-1" text #click="dialog = false">Close</v-btn>
<v-btn color="blue darken-1" text #click="dialog = false">Save</v-btn>
</v-card-actions>
</div>
</v-dialog>
</v-row>
</template>
<script>
export default {
data(){
return{
colors: ["red","pink","purple","deep-purple","indigo","blue","light-blue","cyan","teal","green","light-green","lime","yellow","amber","orange","deep-orange","brown","blue-grey","grey", "black"],
dialog: false
}
},
} </script>
To do this you actually use themes that you setup in vuetify.js and you can assign different colors to the different values for example primary: '#c3c3c3' and define different themes within your app. It comes with light and dark theme but you can also add/remove themes programmatically.
It's quite a bit of code so I will post the links on where directions can be found here.
https://vuetifyjs.com/en/customization/theme/#custom-theme-variants
And the actual usage can be found here:
https://vuetifyjs.com/en/customization/theme/#usage

v-slot:badge and v-if does not work with a computed property

I'm working on a CMS project and I have an issue I can't figure out.
I Have a component where I'm showing IP's. On change I want a badge to appear, so the user knows "this field is changed".
But the thing is the badge won't show if I'm using "v-slot:badge".
In the v-if is a computed property, If I inspect the page with vue devtools ‘isStartIpValueChanged’ will be true on a change. So, it should work right?
Template
<v-list-item-content>
<v-form ref="form" v-model="valid">
<v-hover v-slot:default="{ hover }">
<v-row align-content="center" no-gutters>
<v-col>
<v-badge overlap color="red" right>
<template v-slot:badge v-if="isStartIpValueChanged">
<v-avatar color="red" size="6"></v-avatar>
</template>
<v-text-field
dense
:rules="apiIpRules"
v-model="apiIp.startIp"
#input="valueChanged()"
ref="startIp"
:class="hover ? 'hover-text-color' : ''"
placeholder="###.###.###.###">
</v-text-field>
</v-badge>
</v-col>
<v-col cols="1" class="text-center" align-self="center">
<p>-</p>
</v-col>
<v-col cols="1" class="text-center" align-self="center">
<v-btn v-show="hover" #click="deleteIp()" icon small color="red"><v-icon>mdi-minus-circle</v-icon></v-btn>
</v-col>
</v-row>
</v-hover>
</v-form>
Created and Computed (apiIp is a prop I get from the parent component)
created () {
this.apiIpsOriginalValueStartIp = this.apiIp.startIp
this.apiIpsOriginalValueEndIp = this.apiIp.endIp
this.apiIp.uuid = this.GenerateUUID()
},
computed: {
isStartIpValueChanged () {
return this.apiIp &&
(this.apiIp.startIp !== this.apiIpsOriginalValueStartIp ||
this.apiIp.uuid === null)
},
isEndIpValueChanged () {
return this.apiIp &&
(this.apiIp.endIp !== this.apiIpsOriginalValueEndIp ||
this.apiIp.uuid === null)
}
},
Anyone know what is going wrong here?
As according to Vuetify's own documentation, you should be using the v-model, directly on the v-badge, to show it only when you want it to.
<v-badge overlap color="red" right v-model="isStartIpValueChanged">
<template v-slot:badge>
<v-avatar color="red" size="6"></v-avatar>
</template>
<v-text-field
dense
:rules="apiIpRules"
v-model="apiIp.startIp"
#input="valueChanged()"
ref="startIp"
:class="hover ? 'hover-text-color' : ''"
placeholder="###.###.###.###">
</v-text-field>
</v-badge>
Doc: https://vuetifyjs.com/en/components/badges#show-on-hover

How to trigger a method at component opening in vuejs?

I have a main component that is used to display items using a loop:
<v-list-tile v-for="(item, index) in items" :key="item.title">
...
<report type="item.type"> </report>
</v-list>
The report component is used to report abuse on the system, and report type may vary depending on the item from the parent loop.
As users are very unlikely to use report on a regular basis I would like to only load v-select elements when the Dialog (modal) is opened.
Using created or mounted triggers the loading method everytime the report component is generated and not when the report component is opened.
Is there a smart way to prevent this and only have the loading method within report being triggered only when the component is opened.
=== Report.vue file ===
=== This file is loaded in the parent component
<template lang="html">
<v-dialog v-model="dialog" persistent max-width="800px" lazy>
<v-btn icon slot="activator">
<v-icon>error_outline</v-icon>
</v-btn>
<v-card>
<v-card-title>
<div class="headline"><v-icon large>error_outline</v-icon> Reporting</div>
</v-card-title>
<v-card-text>You are about to report the following {{ reportType }}: "<i>{{ reportContent.title }}</i>"
<v-container v-if="this.$store.getters['report/getLoadedState']" grid-list-md >
<v-layout wrap>
<v-flex xs12 sm12>
<v-select
label="Select a reason"
required
cache-items
:items="items"
item-text="title"
item-value="id"
></v-select>
</v-flex>
<v-flex xs12 sm12>
<v-text-field
label="Please provide additional information here"
multi-line></v-text-field>
</v-flex>
</v-layout>
</v-container>
<v-container v-else grid-list-md>
<v-layout>
<v-flex xs12 sm12>
Loading
</v-flex>
</v-layout>
</v-container>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="green darken-1" flat="flat" #click.native="cancel">Cancel</v-btn>
<v-btn color="green darken-1" flat="flat" #click.native="report">Report</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
export default {
name: 'report',
data () {
return {
dialog: false,
items: this.$store.getters['report/getItems']
}
},
props: ['reportType', 'reportContent'],
methods: {
cancel () {
this.dialog = false
},
report () {
this.dialog = false
},
loadReasons (type) {
if (!this.$store.getters['report/getLoadedState']) {
this.$store.dispatch('report/setItems', type)
}
}
}
}
</script>
<style lang="css" scoped>
</style>
PS 1: I'm not using JQuery and do not intend to use it
PS 2: Calling the method outside of the report component is not an option as I want to maximize reusability of this compenent and only pass arguments to it using props
How I have done this in the past is to use a "dynamic component." Vue uses a special syntax for dynamic components <component v-bind:is="currentView"></component> see: Vue dynamic components
You can set the "currentView" property to null and then on a button click another event set the currentView to report. Doing it this way will allow you to use the mounted method as the component is not rendered or created until it is dynamically called.
<component :is="myComponent"></component>
<v-btn #click="loadComponent">Show Report</v-btn>
then...
data:{
myComponent: null;
},
methods: {
loadComponent: function(){
this.myComponent = 'report';
}
}
P.S. You can of course use this method to render any other components in the same place. i.e. you can set the 'currentView' to the name of any available component and it will be instantly rendered in its place.
I ended up using a watch on the boolean managing the dialog...
Make a function which loads the v-select. Don't initialize it just create it. Now whenever user clicks the report model you can initialize multiple functions using v-on:click or #click.
For example :
<div v-on:click="return function() { fn1('foo');fn2('bar'); }()"> </div>
This solution can also be found on :
Stackoverflow Link