xdan/datetimepicker

Feature request: Display only year and month, not days

awthird opened this issue · 4 comments

It would be very handy if setting the format or dateFormat to 'Y-m' would disable the display of the days or, alternatively, there were options to hide the days in the displayed calendar. Currently, it shows the days with all of them selected, which implies a daily granularity. For some purposes, that can be misleading or redundant.

Thanks.

Had the same issue. Add this to your datetimepicker constructor:

onGenerate() {
  const pickerEl = this[0];

  // hide the datepicker for this element, but keep the month selector
  pickerEl.querySelector(".xdsoft_calendar").classList.add("d-none");

  // fix widget styles
  pickerEl.classList.add("my-2", "py-0");
}

EDIT: I copied this in such a hurry that I didn't stop to think that the code assumes that you are using Bootstrap.

To get this to work as-copied, you would need to add the following CSS rules (stolen shamelessly from the Bootstrap 5 stylesheet):

<style>

.d-none {
    display: none!important;
}

.py-2 {
    padding-top: 0.5rem!important;
    padding-bottom: 0.5rem!important;
}
.py-0 {
    padding-top: 0!important;
    padding-bottom: 0!important;
}

</style>

Alternatively, you could set the CSS attributes manually on the elements using, for example pickerEl.querySelector(".xdsoft_calendar").style['display'] = "none";

All code in this comment is untested and is provided as a starting point or inspiration for the reader.

Thanks for the suggestion. Unfortunately, it doesn't work for me - the calendar days for the selected year/month are still displayed. Here's my constructor:

$("#datepicker").datetimepicker({
     onGenerate:function( ct ){
       const pickerEl = this[0];

       // hide the datepicker for this element, but keep the month selector
       pickerEl.querySelector(".xdsoft_calendar").classList.add("d-none");

       // fix widget styles
       pickerEl.classList.add("my-2", "py-0");
     },
     closeOnWithoutClick: true,
     format: 'Y-m',
     formatDate: 'Y-m',
   });

Anyway, maybe it's not quite as simple as I originally thought. I note that one has to click on a day in the displayed days part of the calendar to trigger the update, even if only selecting the year and month, so hiding the calendar days would make that impossible.

I apologize for the issue, my first comment was using Bootstrap classes in the example, which would probably need to be swapped for other style rules. I edited the comment to provide a sample.

Regarding your last paragraph, you can override the onChangeMonth method to handle changes in the year/month pickers without requiring the day itself to be clicked. I created a handler function for this purpose, which assigned to handle both onChangeMonth and onSelectDate (all this is done in the constructor).

This is all available in the docs (not being snarky, I had to dig around to find what I needed, but it's all there). But what you want to achieve (which appears to have a lot of overlap with what I wanted to achieve) should be doable.

Got it working, thanks to your tip. This is what I ended up with:

   var ymdate = new Date("2021-03");
   ymdate = ymdate.toUTCString().substr(0,25);
   $("#id-datepicker").datetimepicker({
     onGenerate: function () {
       const pickerEl = this[0];
       pickerEl.querySelector(".xdsoft_calendar").style['display'] = "none";
     },
     onChangeMonth: function(ct, $i) {
       var newdate = ct.toISOString().substr(0,7);
       $("#id-datepicker").val( newdate );
       $("#calendar-form").submit();
     },
     defaultDate: new Date(ymdate),
     closeOnWithoutClick: true,
     format: 'Y-m',
     formatDate: 'Y-m',
   });

I had an issue with timezones (doesn't everyone) but it was particularly painful on the first day of the month because the offset was defaulting the datetimepicker to the previous day. Converting to UTCString and omitting the timezone fixed that.

Thanks so much for your help.