Input TextField with DatePicker using Vuetify(supports Tab and click operations)
In vuetify creating a DatePicker is an easy task, but attaching it to a input field, adding collapse and expand feature to it needs some work. In this post we're going to learn how to link DatePicker to TextField with a smooth user experience.
Starting with a Date Picker
We start with implementing a minimal date picker from vuetify. The dateValue
is binded to the DatePicker.
<template>
<v-layout row wrap>
<v-date-picker locale="en-in" v-model="dateValue" no-title></v-date-picker>
</v-layout>
</template>
<script>
export default {
data() {
return {
dateValue: null,
};
},
};
</script>
Linking TextField to DatePicker
Then add a readonly text input field which get its value from dateValue
<template>
<v-container>
<v-text-field
:label="label"
readonly
prepend-icon="event"
:value="dateValue"
></v-text-field>
<v-date-picker locale="en-in" v-model="dateValue" no-title></v-date-picker>
</v-container>
</template>
<script>
export default {
data() {
return {
dateValue: null,
};
},
props: {
label: String,
},
};
</script>
Showing/Hiding DatePicker when TextField is clicked
Having the basic functionality required, now we want to hide the date picker, and selectively display it when the text field is clicked. For this we use the v-menu
component of vuetify.
<template>
<v-menu
v-model="dateMenu"
:close-on-content-click="false"
:nudge-right="40"
lazy
transition="scale-transition"
offset-y
full-width
min-width="290px"
max-width="290px"
>
<template v-slot:activator="{on}">
<v-text-field
:label="label"
prepend-inner-icon="event"
readonly
hide-details
:value="dateValue"
v-on="on"
></v-text-field>
</template>
<v-date-picker
locale="en-in"
v-model="dateValue"
no-title
@input="dateMenu = false"
></v-date-picker>
</v-menu>
</template>
<script>
export default {
data() {
return {
dateMenu: false,
dateValue: null,
};
},
props: {
label: String,
},
};
</script>
We have the entire functionality that we want, but we still lack the keyboard accessibility
Keyboard Accessibility
You can listen for the focus
and blur
events to enhance the experience for the users who prefer to navigate using keyboard (using Tab
key). Therefore the final code considering the focus and blur of text input field will be as follows:
The setTimeout
was used in this code, since the value of dateValue
was set
after the transition was completed in usual case. I assume the delay of
200ms
for the transition.
<template>
<v-menu
v-model="dateMenu"
:close-on-content-click="false"
:nudge-right="40"
lazy
transition="scale-transition"
offset-y
full-width
min-width="290px"
max-width="290px"
>
<template v-slot:activator="{on}">
<v-text-field
:label="label"
prepend-inner-icon="event"
readonly
hide-details
:value="dateValue"
v-on="on"
@focus="focusDate"
@blur="blurDate"
></v-text-field>
</template>
<v-date-picker
locale="en-in"
v-model="dateValue"
no-title
@input="dateMenu = false"
></v-date-picker>
</v-menu>
</template>
<script>
export default {
data() {
return {
dateMenu: false,
dateValue: null,
};
},
props: {
label: {
type: String,
required: true,
},
},
methods: {
focusDate() {
setTimeout(() => {
if (!this.dateMenu) {
this.dateMenu = true;
}
}, 200);
},
blurDate() {
setTimeout(() => {
if (this.dateMenu) {
this.dateMenu = false;
}
}, 200);
},
},
};
</script>
Resources:
This post is inspired by this article and this answer
Last Updated on
Comments