JQuery datepicker - set callback order
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 refl开发者_JAVA技巧ected 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!
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, '']);
...
}
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
});
}
精彩评论