vuetifyjs / vuetify

🐉 Vue Component Framework
https://vuetifyjs.com
MIT License
39.85k stars 6.97k forks source link

[Feature Request] [3.3] Month picker in VDatePicker #17950

Open cybergum13 opened 1 year ago

cybergum13 commented 1 year ago

Problem to solve

VDatePicker in Vuetify 2 had a type property that could be set to "month" to show a month selection instead of a calendar date selection. VDatePicker in Vuetify 3 does not seem to have any equivalent option. Is this going to be added back in?

Proposed solution

Add a month selection option back in to VDatePicker.

NextThread commented 1 year ago

hey, can I work on this?

Enech commented 1 year ago

It is sorely needed here (migration from V2)

NextThread commented 1 year ago

ok i'll do this

NextThread commented 1 year ago

did anybody tried, I tried to implement this but the array is not working, it's showing all dates as valid

NextThread commented 1 year ago

anyone?

throrin19 commented 1 year ago

We have the same need to migrate from V2 to V3. It's still possible to make it as a year Selector using the VDatePicker ?

carlosvaro commented 1 year ago

Hello. We have the same need when migrating from V2 to V3 (active-picker) to switch between DATE, YEAR or MONTH). Will this be possible soon? Thank you

kuzeofficial commented 1 year ago

any update on this ?

russellg commented 12 months ago

Adding support for this request (migration from v2). Would be nice to not have to cycle through the months using the left/right arrows and instead have the previous option where a user could click "Date/Month" to display all the months within the date picker modal.

waduocuiduo commented 11 months ago

Hello. We have the same need when migrating from V2 to V3. Will this be possible soon? Thank you

webdevnerdstuff commented 11 months ago

This has been added already.

Playground

waduocuiduo commented 11 months ago

This has been added already.

Playground

@webdevnerdstuff I'm sorry. But what you say is not the feature we need. The picker we need is the one which can only select a year and month(YYYYMM) , not the day(YYYYMMDD) . In vuetify 2.x , it controls with the prop type=month. OnlyYearMonthPicker

carlosvaro commented 11 months ago

@webdevnerdstuff We have the same problem. In 2.x we could define to only display a year picker, a year and month picker or the date picker where you choose year, month and day. In this fix you have to use the viewMode option, but it only makes the default to year or month, but the user have to choose the day before the "@update:modelValue" is triggered. @click:year="setYear" and @click:month="setYearAndMonth" are not triggered when the user choose a concrete year or year/month as before. Maybe I don't now how to use ir, but the viewMode property in the playground is not the solution. Regards.

webdevnerdstuff commented 11 months ago

My comment was as an answer to the OP question Add a month selection option back in to VDatePicker. Technically there is a month selector, so I was just pointing that part out. Not as an answer to everybody's inquiry on what they need, that wasn't part of the initial question.

The problem others who have posted here, is a valid ask though. It sounds like you want a straight up "month" or "year" picker, that doesn't require the calendar or selecting a specific date or changing the viewMode after selecting a month/year. I do not disagree with that.

carlosvaro commented 11 months ago

@webdevnerdstuff Yes, you are right. I think we are asking for the activePicker property (DATE, MONTH or YEAR) feature you had back in v2. Just a selector of a year or year and month. Will you implement this feature and if so, when? Thanks.

webdevnerdstuff commented 11 months ago

@webdevnerdstuff Yes, you are right. I think we are asking for the activePicker property (DATE, MONTH or YEAR) feature you had back in v2. Just a selector of a year or year and month. Will you implement this feature and if so, when? Thanks.

I'm not currently a Vuetify dev. So I do not know if/when they will.

cvaroregidor commented 8 months ago

No news if the activePicker property (DATE, MONTH or YEAR) feature we had back in vuetify2 will be developed in vuetify3? With the actual version it's impossible to have same behavior (like year-month picker without days).

KaelWD commented 8 months ago

activePicker is now called viewMode and is not related to this issue.

cvaroregidor commented 8 months ago

Thanks. I know, but with viewMode I don't have the same behavior as with activePicker. I mean, a datePicker where the user selects a year and a month and no day. Setting viewMode to "month", when the user select a year, next step of the datePicker is to show days and not month selection. Any example of how to do this?

desousar commented 8 months ago

Currently (version 3.5.4) there is only view-mode="months", which directly opens the view of all months, but then you have to select a day, there is no possibility to select only MM-YYYY

anselmoinfo commented 8 months ago

In version 2.x there was a type="month" parameter

Is it expected to be implemented in version 3.x?

https://v2.vuetifyjs.com/en/components/date-pickers-month/#usage

image

philipbeaucamp commented 5 months ago

It looks like this feature has still not been added. Is there a roadmap for this ?

desousar commented 4 months ago

I finally developed 2 variants of the v-date-picker.

Here's how my component (ADatePicker.vue) was integrated into my application (I've wrapped the Vuetify components):

<a-menu>
<template v-slot:activator="{ props }">
<a-text-field />
</template>
<a-date-picker />
</a-menu>

With the first v-date-picker, you can select only one year. With the second, you can select only a year and a month. The third is the classic.

For the first and second, I've also changed the behavior when the user clicks on an already selected year or month. Basically, nothing happens, but this needs to be changed for the user experience in the first and second.

<template>
  <v-date-picker
    v-if="props.viewMode === 'year'"
    :key="state.keyYearOnly"
    :year="state.year"
    :view-mode="props.viewMode"
    :color="props.color"
    :hide-header="props.noTitle"
    :modelValue="props.modelValue"
    @update:viewMode="handleYearViewMode"
    @update:year="emitValue"
    @click="clickEvent" />
  <v-date-picker
    v-else-if="props.viewMode === 'months'"
    :key="state.keyMonthYear"
    :view-mode="getMonthYearViewMode"
    :year="state.year"
    :month="state.month"
    :color="props.color"
    :hide-header="props.noTitle"
    :modelValue="state.modelValue"
    @update:modelValue="emitValue"
    @update:viewMode="handleMonthYearViewMode"
    @update:year="updateYear_ofMonthYear"
    @update:month="updateMonth_ofMonthYear"
    @click="clickEvent" />
  <v-date-picker
    v-else
    :year="state.year"
    :month="state.month"
    :color="props.color"
    :hide-header="props.noTitle"
    :show-adjacent-months="true"
    :view-mode="props.viewMode"
    :modelValue="state.modelValue"
    @update:modelValue="emitValue" />
</template>

<script setup>
import { reactive, computed, onMounted } from 'vue';

const monthsList = {
  January: 0,
  February: 1,
  March: 2,
  April: 3,
  May: 4,
  June: 5,
  July: 6,
  August: 7,
  September: 8,
  October: 9,
  November: 10,
  December: 11,
};

const emit = defineEmits(['update:modelValue']);

const props = defineProps({
  //vuetify props
  color: { type: String, required: false },
  noTitle: { type: Boolean, required: false },
  showAdjacentMonths: { type: Boolean, required: false },
  startMonth: { type: String, required: false, default: undefined },
  startYear: { type: Number, required: false, default: undefined },
  viewMode: { type: String, default: 'month' },
  modelValue: { type: undefined, required: false },
});

const state = reactive({
  keyYearOnly: 0,
  keyMonthYear: 0,

  monthYearViewMode: props.viewMode,
  month: convertMonthStrToInt(),
  year: props.startYear,
  modelValue: props.modelValue,

  /*
    They are 2 cases:
    - User clicks on an unselected chip => normal behavior
    - User clicks on an already selected chip => @update:modelValue isn't called so I've to emit it manually
  */
  clickOnUnselectredChip_YearOnly: false,
  clickOnUnselectredChip_MonthYear: false,
});

const getMonthYearViewMode = computed(() => {
  return state.monthYearViewMode;
});

function convertMonthStrToInt() {
  return monthsList[props.startMonth];
}

function updateYear_ofMonthYear(year) {
  state.year = year;
}
function updateMonth_ofMonthYear(nbMonth) {
  state.month = nbMonth;
  emitValue(new Date(state.year, state.month, 1));
}

/*
Target: YearOnly and MonthYear types
Aim: change default behavior 
Result: when the user clicks on an already selected year or month chip, he is either redirected into the date-picker or out of it
*/
function clickEvent() {
  if (props.viewMode === 'year') {
    if (!state.clickOnUnselectredChip_YearOnly) {
      emitValue(state.year);
    }
  } else if (props.viewMode === 'months') {
    if (state.monthYearViewMode === 'year' && !state.clickOnUnselectredChip_MonthYear) {
      handleMonthYearViewMode('month');
    }
    if (state.monthYearViewMode === 'months' && !state.clickOnUnselectredChip_MonthYear) {
      emitValue(new Date(state.year, state.month, 1));
    }
    state.clickOnUnselectredChip_MonthYear = false;
  }
}

function emitValue(date) {
  if (props.viewMode === 'year') {
    state.clickOnUnselectredChip_YearOnly = true;
  }
  emit('update:modelValue', date);
}

function handleYearViewMode() {
  state.keyYearOnly += 1;
}

function handleMonthYearViewMode(e) {
  state.clickOnUnselectredChip_MonthYear = true;
  if (e === 'year') {
    state.monthYearViewMode = 'year';
  } else if (e === 'month') {
    state.monthYearViewMode = 'months';
  }
}

onMounted(() => {
  // the key is used to refresh the Vuetify date-picker to correctly set the start option when it starts on a view other than the default "month" view
  setTimeout(() => {
    if (props.viewMode === 'year' && state.keyYearOnly === 0) {
      state.keyYearOnly += 1;
    }
    if (props.viewMode === 'months' && state.keyMonthYear === 0) {
      state.keyMonthYear += 1;
    }
  }, 200);
});
</script>
uhrb commented 3 months ago

View mode is not replacement for type='month' of vue2. I faced the issue when migrating vuetify2 to vuetify3 with this date pickers. Now I forced to implement it by myself, struggling to make em look and feel same way, vuetify do for v-date-picker component. It was a breaking change for this component, when "type" was removed. I do not know why team decided to remove used functionality and introduce breaking change without providing guidance how to achieve same behavior of the component, but it is unexpected and at least required to mention in documentation. As for now, I forced to replace all the date-picker components with third-party one, since it is safer and more consistent, instead of using non-functional component or try to have two different datepicker components in solution. Hopefully team will re-think approach and take into account, that month-only or year-only selection is need by the end-users of the framework.

overclocked555 commented 2 months ago

@desousar example: playground

J-Sek commented 1 month ago

I gave it a shot, but... even after fixing few edge cases, I think dedicated 3-column view would deliver much better UX (following what seems to be industry standard [1], [2]).

image

Material spec shows list-style though [3].

Does the core team has an opinion about the future layout of month picker?

r0otx commented 1 month ago

Need select variant only month and year, or only year example: I'm set type 'months' open calendar in months list, select month, after see years list, select year and show result (mm.yyyy) please add this addon.

J-Sek commented 1 month ago

Need select variant only month and year, or only year example: I'm set type 'months' open calendar in months list, select month, after see years list, select year and show result (mm.yyyy) please add this addon.

I think you don't need date picker for it. Playground