flatpickr / flatpickr

lightweight, powerful javascript datetimepicker with no dependencies
https://flatpickr.js.org
MIT License
16.17k stars 1.46k forks source link

Feature request: yearSelectorType 'static', similar to the monthSelectorType. #2429

Open lastminutegoals opened 3 years ago

lastminutegoals commented 3 years ago

Your Environment

So basically, I am trying to achieve something very simple here:

image

A datepicker as usual, with static month and year between the next and previous arrows. I don't want the user to be able to interact with the year select/dropdown, and I want the year to be displayed next to the month. The only user interaction I want happening here is to be either from the calendar dates, or the prev/next arrows.

So solution number 1 would be to just add a disabled attribute to the year element - numInput cur-year. Problem with that approach is it's really hard to style it, for example removing the up and down arrows next to an <input type="number"> is a challenge by itself, and you have to test this on numerous different browsers.

input,
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
    border: none;
    background-image: none;
    background-color: transparent;
    -webkit-box-shadow: none;
    -moz-box-shadow: none;
    box-shadow: none;
}

input[type="number"] {
    -moz-appearance: textfield;
}

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: none;
}

.reset [type="number"] {
    -moz-appearance: spinner-textfield;
}

.reset input[type="number"]::-webkit-outer-spin-button,
.reset input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: inner-spin-button;
}

And so on... it becomes really ugly and hacky solution.

Solution number 2 currently and what I tried is hiding the year selector via CSS and then programmatically listen and handle datepicker events (init, prev/next and date select so respectively - onReady, onMonthChange, onChange), so that we manually append the year as text right after the month element - cur-month.

JSFiddle example here

However, there is a problem with this approach which mainly concern how the onMonthChange event fires.

As you can see from the example above, the onReady and onChange events work as expected:

  onReady: function(selectedDates, dateStr, instance) {
   // on init append the year as text to the month element 
    instance.monthElements[0].textContent += instance.currentYear;
  }
  onChange: function(selectedDates, dateStr, instance) {
   // do the same when the user clicks anywhere on the calendar dates
    instance.monthElements[0].textContent += instance.currentYear;
  }

onMonthChange however appears to work differently.

  onMonthChange: (selectedDates, dateStr, instance) => {
    instance.monthElements[0].textContent += instance.currentYear;
   // the instance parameter here returns the older instance of the datepicker instead
   // or in other words instance.currentMonth and instance.currentYear will return values
   // of the datepicker before the user interacted (the previous month)
   // it also does not tell you whether or not the user clicker prev or next button
  }

Additionally, in the example I linked you can see that the first two methods work and the year value gets appended as text after the month element, but for the onMonthChange it doesn't. I am not exactly sure what the reason for that is. I tried also adding instance.redraw(); but to no avail either.

Anyway, all of this could have been easily avoided if we were able to pass yearSelectorType: 'static' as options to the datepicker instance as suggested here already #1826.

Additionally and lastly, if there is another non-hacky approach to this and I have missed it, I'd appreciate it if someone lets me know.

Cheers and thanks for developing and maintaining this library. Apart from this small issue I am having I love how it works and behaves!

pacop commented 3 years ago

We are also interested on that.

At #1826 @chmln commented that "although the option for the year seems not necessary just yet", I don't see why not. Maybe there is another solution that we don't know?. To the best of my knowlege, it forces us to use ugly/hacky solutions and what it is worse, it isn't homogeneous having one option for month and not for year.

Dang3rZone commented 3 years ago

I agree! Currently need to disable the year from the date picker and a cleaner way would be yearSelectorType: 'static'

cchacholiades commented 2 years ago

+1 for yearSelectorType: 'static'

torian257x commented 2 years ago

+1

marcod1419 commented 1 year ago

+1! My team would like this feature too.

AnujShr commented 1 year ago
.cur-year {
    pointer-events: none!important;
}
.arrowUp, .arrowDown {
    display: none !important;
}

.numInputWrapper:hover {
    background: none!important;
}

I have been using this and seems like it works.

m345054 commented 1 week ago

Any updates on this?