views:

470

answers:

2

I'm using the JQuery datepicker and show it to the user with some days disabled. Certain users in my site can mark some days in an agenda as 'being available', their working hours so to speak. Their availability has to be reflected in the calendar to other users.

I have searched the web for this, and it seems that one should use the beforeShowDay event for this, which is exactly what I do. In short, when the datepicker loads, I make a call to the server, parse the json result (a list of dates), push it in an array, which is read in beforeShowDay and here I check if the day is in the array.

The problem comes when I change month. In onChangeMonthYear, I do another call to the server and retrieve the availablitly for this new month. However, it seems that beforeShowDay is called before this event, which means that there are no availabilities loaded yet, and the calendar shows nothing. Here is some code:

var dates = [];

$(document).ready(function() {
  var today = new Date();
  $.post("/AgendaApi/Day/" + today , null, function(json) {
    $.each(json, function(index, result) {
      dates.push(result.AvailableDate);
    });
  }, "json");
});

$(document).ready(function() {
  $('#date').datepicker({
    minDate: new Date(),
    dateFormat: 'dd-mm-yy',
    onChangeMonthYear: function(year, month, thisCalendar) {
      $.post("/AgendaApi/Day/01-" + month + "-" + year, null, function(json) {
        $.each(json, function(index, result) {
          dates.push(result.AvailableDate);
        });
      }, "json");
    },
    beforeShowDay: function(date) {      
      if ($.inArray(date, dates) > -1) {
        return [true, ''];
      }
      return [false, ''];
    }
  });
});

In the code above I left out some culture-specific date parsing and all, but you get the general idea. How can I resolve this? Because what I want is, if the user change month, I first fetch all the available days for that month, and then the calendar is 'drawn'. Not the other way around. I'm using asp.net MVC but that doesn't matter much. Many thanks!

A: 

onChangeMonthYear is before beforeShowDay:

     /* Action for selecting a new month/year. */
     _selectMonthYear: function(id, select, period) {
      var target = $(id);
      var inst = this._getInst(target[0]);
      inst._selectingMonthYear = false;
      inst['selected' + (period == 'M' ? 'Month' : 'Year')] =
      inst['draw' + (period == 'M' ? 'Month' : 'Year')] =
       parseInt(select.options[select.selectedIndex].value,10);
      this._notifyChange(inst); // onMonthYearChange
      this._adjustDate(target);
     }

     _adjustDate: function(id, offset, period) {
      var target = $(id);
      var inst = this._getInst(target[0]);
      if (this._isDisabledDatepicker(target[0])) {
       return;
      }
      this._adjustInstDate(inst, offset +
       (period == 'M' ? this._get(inst, 'showCurrentAtPos') : 0), // undo positioning
       period);
      this._updateDatepicker(inst);
     },

            //_updateDatePicker makes the call to _generateHtml where the beforeShowDate event is executed:

  _generateHtml{...
      var daySettings = (beforeShowDay ? beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);

...
   }
scottm
I'm not sure I get it. Is this the code of the datepicker itself? Cause whatever it says, it sure doesn't work for me :-)
Razzie
A: 

I found a solution, not the best, I guess, but it works. I changed the request in the onChangeMonthYear event to be synchronous:

onChangeMonthYear: function(year, month, thisCalendar) {
  jQuery.ajax({
    url: "/AgendaApi/Day/01-" + month + "-" + year,
    success: function(json) {
      $.each(json, function(index, result) {
        dates.push(result.AvailableDate);
      });
    },
    dataType: "json",
    async: false
  });
}
Razzie