Reputation: 2523
Ok, this is somewhat strange and I'm quite amazed. I wonder if anyone knows if this is an intended behaviour or some bug.
On an ASP.NET MVC app I use jQuery for client events. I have several datepickers where I try to override the standard day color patterns on click events by playing with onSelect attribute on datepicker object.
Basically, on onSelect I use AJAX calls to ask server for the days I want to show on a determinate color and change them (usually after adding the clicked day to the list of "marked" days).
My code don't seem to be overriding the default behaviour (when you click on a day all days get standard color and the day you clicked in is highlighted), it instead seems to execute after it (thus redrawing states and colors on the datepicker to my desire).
What I've found that surprise me is that if I use $.ajax to call the server, my code executes before the "default behaviour" showing the standard color pattern, but if I use $.post my code executes after the "default behaviour" overriding the standard color pattern.
Here's some code example:
$("#diasNoLectivosHolder").datepicker({
minDate: arrayNoLaborables[0],
maxDate: arrayNoLaborables[1],
onSelect: function (fecha, calendar, event) {
$.post($.url("Grupos/diaNoLaborable/" + $("#idGrupo").val() + "/" + fecha.replace(/\//g, ".")), function (xmlResponse) {
if (xmlResponse)
$.post($.url("Grupos/obtenerDiasNoLaborables/" + $("#idGrupo").val()), function (xmlDias) {
marcarNoLaborables(xmlDias);
});
$("#fechaInicio").change();
return false;
});
return false;
},
onChangeMonthYear: function () {
$.post($.url("Grupos/obtenerDiasNoLaborables/" + $("#idGrupo").val()), function (xmlResponse) { marcarNoLaborables(xmlResponse); });
}
});
On this example, the calendar flickers briefly to the standard color pattern after a click on any day and finishes showing the color pattern that my marcarNoLaborables(xmlDias); method defines.
On the contrary, if I use:
$("#diasNoLectivosHolder").datepicker({
minDate: arrayNoLaborables[0],
maxDate: arrayNoLaborables[1],
onSelect: function (fecha, calendar, event) {
$.ajax({
async: false,
cache: false,
url: $.url("Grupos/diaNoLaborable/" + $("#idGrupo").val() + "/" + fecha.replace(/\//g, ".")),
success: function (xmlResponse) {
if (xmlResponse)
$.ajax({
async: false,
cache: false,
url: $.url("Grupos/obtenerDiasNoLaborables/" + $("#idGrupo").val()),
success: function (xmlDias) {
marcarNoLaborables(xmlDias);
}
});
$("#fechaInicio").change();
return false;
}
});
return false;
},
onChangeMonthYear: function () {
$.post($.url("Grupos/obtenerDiasNoLaborables/" + $("#idGrupo").val()), function (xmlResponse) { marcarNoLaborables(xmlResponse); });
}
});
The datePicker, after the click on any day, finishes drawing the "standard color pattern", if I step on code execution I can see that my modified color pattern applies, but on finishing my code, the standar pattern applies.
So my question is... anyone knows why the use of $.ajax or $.post affects on the moment when the code is executed respect the "default datepicker behaviour"?
Feel free to ask anything that's not clear on my explanation. English is not my mother language and sometimes I find difficult to explain clearly complex situations like this.
Thank you all.
Upvotes: 1
Views: 456
Reputation: 6027
The reason the code is executed at different points in your script is because of setting the "async" option.
By default, the "async" option is set to true, meaning code execution is not blocked while the XHR is made. Usually this is the wanted behaviour, as you do not want the UI thread to be blocked while your script makes a call to the server for more data.
Setting the "async" option to false changes to behaviour so your script pauses until a response from the server is made.
I'm unsure what the end goal of your script is, so i cannot make a recommendation as to what you should be doing. But you should know that the $.post
method is just a shorthand for the $.ajax
method with the follow options:
$.ajax({
type: "POST",
url: url,
data: data,
success: success,
dataType: dataType
});
So if the blocking behaviour of your sync is absolutely needed (not recommended) you could get a "POST" type AJAX request with the same options passed to $.ajax.
Hope this helps.
Upvotes: 4