Vuetify: Responsive v-date-picker width for v-dialog and v-menu

I am looking to create an adaptive date picker using v-date-picker. When the page is viewed on a phone, I want the date picker to open in a v-dialog, and when viewed on a desktop, I want it to open in a v-menu.

Here is my attempt:

<template>
  <div>
    <template v-if="$vuetify.breakpoint.xsOnly">
      <v-dialog
        ref="dialog"
        v-model="modal"
        persistent
        width="290px"
      >
        <template v-slot:activator="{ on }">
          <slot name="input" ref="input" v-on="on"/>
        </template>
        <slot name="picker" ref="picker"/>
      </v-dialog>
    </template>
    <template v-else>
      <v-menu
        ref="menu"
        v-model="menu"
        :close-on-content-click="false"
        transition="scale-transition"
        offset-y
        min-width="290px"
      >
        <template v-slot:activator="{ on }">
          <slot name="input" ref="input" v-on="on"/>
        </template>
        <slot name="picker" ref="picker"/>
      </v-menu>
    </template>
  </div>
</template>

<script>
    export default {
        name: "v-date",
        data() {
            return {
                menu: false,
                modal: false,
            }
        },
        methods: {
            close() {
                this.menu = false;
                this.modal = false;
            }
        }
    }
</script>

However, I encountered issues with v-on not working. I also tried :listeners="on", but that did not work either...

For example usage of the component:

<v-date>
  <template v-slot:input>
    <v-text-field
      label="Deadline"
      v-model="data.deadline"
      readonly
    />
  </template>
  <template v-slot:picker>
    <v-date-picker v-model="data.deadline" no-title scrollable>
      <v-spacer></v-spacer>
      <v-btn text color="primary" @click="$refs.deadline.close()">OK</v-btn>
    </v-date-picker>
  </template>
</v-date>

Answer №1

Special thanks to KrasnokutskiyEA for the inspiration!

Refined version:

<template>
  <div>
    <template v-if="$vuetify.breakpoint.xsOnly">
      <v-dialog
        ref="dialog"
        v-model="modal"
        persistent
        width="290px"
      >
        <template v-slot:activator="{ on }">
          <slot name="input" ref="input" :on="on"/>
        </template>
        <slot name="picker" ref="picker"/>
      </v-dialog>
    </template>
    <template v-else>
      <v-menu
        ref="menu"
        v-model="menu"
        :close-on-content-click="false"
        transition="scale-transition"
        offset-y
        min-width="290px"
      >
        <template v-slot:activator="{ on }">
          <slot name="input" ref="input" :on="on"/>
        </template>
        <slot name="picker" ref="picker"/>
      </v-menu>
    </template>
  </div>
</template>

<script>
    export default {
        name: "v-date",
        data() {
            return {
                menu: false,
                modal: false,
            }
        },
        methods: {
            close() {
                this.menu = false;
                this.modal = false;
            }
        }
    }
</script>

Implementation example:

<v-date>
  <template v-slot:input="{ on }">
    <v-text-field
      label="Deadline"
      v-model="data.deadline"
      readonly
      v-on="on"
    />
  </template>
  <template v-slot:picker>
    <v-date-picker v-model="data.deadline" no-title scrollable>
      <v-spacer></v-spacer>
      <v-btn text color="primary" @click="$refs.deadline.close()">OK</v-btn>
    </v-date-picker>
  </template>
</v-date>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

"Vue.js integrates seamlessly with Tracking.js for advanced tracking

Has anyone successfully integrated the tracking.js library into a vueJS application? I followed these steps to install the package: npm install --save tracking After that, I defined the library in my main.js file like this: import tracking from 't ...

What methods can I use to design a splash screen using Vue.js?

I am interested in creating a splash screen that will be displayed for a minimum of X seconds or until the app finishes loading. My vision is to have the app logo prominently displayed in the center of the screen, fading in and out against a black, opaque ...

Cypress and VueJS: How to target elements that are dynamically generated following a specific user interaction

I am currently testing a new feature where a button will only appear for the user to click after they have completed another action. Before proceeding with the action, I am verifying if the button exists: cy.get('span') .contains('Selec ...

VueJS 3 custom Checkbox fails to update UI upon clicking

I'm attempting to implement a customized checkbox using Vue 3 and the composition API based on this example. However, despite confirming through devtools that all my props and bound data are successfully passed from the parent component to the child c ...

Copy both the image and JSON object to the clipboard

I am attempting to utilize the clipboard API to write an image and JSON object to the window clipboard. I am working with Vue and Electron and have successfully written an image and plain text, but I encounter an error when trying to write a JSON object: ...

Troubleshooting Tips for Resolving Problems with VueJS getElementById Bug

I'm currently working with a VueJS single File component that has the following template: <template> <div class="row"> <div class="col-md-12"> <div id="hottable"></div> < ...

A guide on fetching the selected date from a datepicker in framework7 with the help of vuejs

Here is a snippet of the code for a component I am working on: <f7-list-input label=“Fecha de nacimiento” type=“datepicker” placeholder=“Selecciona una fecha” :value=“perfil.fecha_nacimiento” @input=“perfil.fecha_nacimiento = $event.t ...

What is the most efficient approach to completing everyday tasks directly in a Vuex store?

Currently, I am working on making API calls from within a Vuex store action object. Here's an example of one of my actions: /** * Check an account activation token * */ [CHECK_ACTIVATION_TOKEN] ({commit}, payload) { Api.checkActivationToken(payl ...

Passing props from a parent component to a nested child component in Vue 3

My goal is to achieve the functionality described in the title. Suppose I have the following structure: parent -> child -> secondChild Currently, there is a variable called isActive in the parent component. Below is how it can be implemented: paren ...

Connecting Vue component data to external state sources

I am facing a challenge with integrating a Vue component into a large legacy system that is not based on Vue. This component retrieves data through AJAX requests and displays information based on an array of database record IDs, typically passed at page lo ...

Vue.js does not display HTML properly within the vue-swal component

I'm currently working on integrating HTML content into a Sweet Alert popup using this code snippet Link: https://www.npmjs.com/package/vue-swal this.$swal({ title: '<i>Custom HTML</i>', html:`This is an <em> em ...

The absence of FormData.entries in submit is a limitation of the Vue framework

I recently created a Vue-App that consists of a simple form with just one <input name"surname"> and a <button type="submit">. The use case is to input "myname" and submit the form. However, when I initialize new FormData( ...

Harness the power of Vue.js by implementing plugin methods in your code

For my first attempt at building a SPA with Vue, I decided to re-use a few functions but encountered some issues. The error message "this.ExperienceToLevel is not a function" kept popping up and it left me puzzled. Furthermore, I'm contemplating if c ...

What causes Vue to only update once when there are two closely timed mutations to reactive data?

Can you take a look at this simple example? export default { data() { return { name: "Amy", age: 18, }; }, computed: { combinedDataForWatching() { return { name: this.name, age: this.age, ...

What does the `Class<Component>` represent in JavaScript?

Apologies for the lackluster title (I struggled to think of a better one). I'm currently analyzing some Vue code, and I stumbled upon this: export function initMixin (Vue: Class<Component>) { // ... } What exactly does Class<Component> ...

Implementing a toggle function in Vue.js to add or remove a class from the body element when a

I'd like to add a toggleable class to either the body element or the root element("#app") when the button inside the header component is clicked. Header.vue : <template lang="html"> <header> <button class="navbar-toggler navbar-tog ...

What's the most effective method to incorporate additional events into this element using the conditional operator?

Looking for help with this code snippet: <span role="link" tabindex="0" :class="tabDetails.showPayment ? 'link' : ''" @click="tabDetails.showPayment ? cTab('payments') : null" ...

Toggle button with v-bind in Nativescript Vue

Hey there, I'm just starting out with nativescript vue and I have a question regarding a simple "toggle" feature that I'm trying to implement. Essentially, when a button is pressed, I want the background color to change. <template> < ...

Information displays instantly in the initial milliseconds

When developing dynamic web pages with Nuxt, I encountered an issue in the pages directory where a file named _url.vue is located. The contents of this file are as follows: <template lang="pug"> div component( v-for= ...

Vue 3 feature: Click the button to dynamically insert a new row into the grid

Just starting out in the world of coding, I've zero experience with Vue - it's my introduction to frameworks and arrays are currently my nemesis. In a recent exercise, I managed to display the first five elements of an array in a table after filt ...