admin管理员组

文章数量:1313347

I'm trying to add a button in the control pane of my datepicker. It should allow to show the name of the whole month, instead of a specific date.

I need both behaviors (date picker and month picker) but it seems that the dynamic change of date format crashes the widget. Commented code has the same problem.

var dateToday = new Date();
var maxDate = "+365";
$('.datepicker').datepicker({
  minDate: dateToday,
  maxDate: maxDate,
  dateFormat: "dd-mm-yy",
  changeMonth: true,
  changeYear: true,
  showButtonPanel: true,
  onChangeMonthYear: function(year, month, instance) {
      var thisCalendar = $(this);
      setTimeout(function() {
          var buttonPane = $(instance)
              .datepicker("widget")
              .find(".ui-datepicker-buttonpane");

          $("<button>", {
              text: "Whole month",
              click: function() {
                  var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
                  var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
                  thisCalendar.datepicker("option", "dateFormat", "MM yy");
                  thisCalendar.datepicker('setDate', month + "/01/" + year);
                  //thisCalendar.datepicker('setDate', new Date(year, month, 1));
                  //thisCalendar.datepicker("refresh");

              }
          }).appendTo(buttonPane).addClass("ui-datepicker-clear ui-state-default ui-priority-primary ui-corner-all");
      }, 1);
  }

})

This fiddle shows my issue: /. The button appears only on next months, not the current one. If you click on it, it always shows the same month (e.g. August 2021, as of today).

I'm trying to add a button in the control pane of my datepicker. It should allow to show the name of the whole month, instead of a specific date.

I need both behaviors (date picker and month picker) but it seems that the dynamic change of date format crashes the widget. Commented code has the same problem.

var dateToday = new Date();
var maxDate = "+365";
$('.datepicker').datepicker({
  minDate: dateToday,
  maxDate: maxDate,
  dateFormat: "dd-mm-yy",
  changeMonth: true,
  changeYear: true,
  showButtonPanel: true,
  onChangeMonthYear: function(year, month, instance) {
      var thisCalendar = $(this);
      setTimeout(function() {
          var buttonPane = $(instance)
              .datepicker("widget")
              .find(".ui-datepicker-buttonpane");

          $("<button>", {
              text: "Whole month",
              click: function() {
                  var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
                  var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
                  thisCalendar.datepicker("option", "dateFormat", "MM yy");
                  thisCalendar.datepicker('setDate', month + "/01/" + year);
                  //thisCalendar.datepicker('setDate', new Date(year, month, 1));
                  //thisCalendar.datepicker("refresh");

              }
          }).appendTo(buttonPane).addClass("ui-datepicker-clear ui-state-default ui-priority-primary ui-corner-all");
      }, 1);
  }

})

This fiddle shows my issue: https://jsfiddle/mLewc6ep/3/. The button appears only on next months, not the current one. If you click on it, it always shows the same month (e.g. August 2021, as of today).

Share Improve this question asked Feb 6, 2016 at 11:16 saccoddsaccodd 1,06710 silver badges24 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

It looks like a datepicker bug, it messes the date when you change the dateFormat and you have minDate and maxDate set at the same time.

The solution is to remove min/max date options, set the new format and then restore the min/max:

thisCalendar.datepicker("option", "minDate", null);
thisCalendar.datepicker("option", "maxDate", null);
thisCalendar.datepicker("option", "dateFormat", "MM yy");
thisCalendar.datepicker("option", "minDate", dateToday);
thisCalendar.datepicker("option", "maxDate", maxDate);
// a hack to trick the datepicker and keep the date we set
thisCalendar.datepicker("option", "defaultDate", new Date(year, month, 1));
thisCalendar.datepicker('setDate', new Date(year, month, 1));

Here is the fiddle.

Update:

this solution works, but if you get the date: thisCalendar.datepicker('getDate'); it always shows today date. may it be another bug?

In general, I am not really sure if this is a bug or a normal behavior. Looking at the datepicker code, it is clear they did not expect partial date formats (such as year + month, without the day).

Datepicker doesn't just keep the date value as date, it also parses it from the text value of the input, so it looks like this:

  • We set the MM yy format
  • We choose the date
  • Datepicker converts Date object value into the text March 2016
  • For now everything is OK, but then the backward process is triggered
  • Datepicker parses the March 2016 text and here is where things go wrong, it is not able to parse it and resets value to the defaultDate (which is today by default)

Here is the place where they parse the date and here is the place where it fails, after the parsing it has year and month value, but default value for day is -1, so it can not construct the date.

The workaround is to set the defaultDate value to the same value as date, so when it fails to parse the text, it falls back to the value we need. I updated the fiddle and code above.

This seems quite random, but if you move the update of the format to the first line of the button click, it works.

Give it a try!

Something I forgot to mention that I added: the date format doesn't seem to work when omitting the day ponent. So if you use this line as the first in the block, it does work. Not sure if this really helps :-)

thisCalendar.datepicker("option", "dateFormat", "dd MM yy");

本文标签: javascriptJquery UI datepicker setDate not working on dynamic change of formatDateStack Overflow