I’ll try and keep this short and to the point.
I’ve got a datePicker set up that is being used for an accommodation website to set check in / check out dates. I’m using beforeShowDay to request an XML file that contains date availability and the rate. I’ve got this set up and working correctly.
When the month is changed I have an onMonthChange function to re-request information for the following / previous months dates, this also works as expected, except for one important part:
The Problem:
If you quickly click through the months the XML data coming back in can’t keep up, so dates incorrectly show as unavailable.
I need one of the following to happen:
- Once the data loads the calendar refreshes to show the correct availability
- The month forward button is disabled until the data has been loaded.
What I’ve Tried
- Hiding the month change button at the start of the onMonthChange
function then showing it at the end – this doesn’t work. - Using
async:falsein the get function – I feel this is the solution
but I can’t get it work as I can’t find any clear documentation on
where it’s meant to go.
Code:
/* Date Picker */
var datepickerOptions = {
dateFormat: 'yy-mm-dd',
};
var checkInOptions = {
showOtherMonths: false,
minDate: 0,
beforeShowDay: addPrice,
onSelect: openCheckout,
onChangeMonthYear: onMonthChange,
dateFormat: 'yy-mm-dd'
};
j.getJSON("/availability.php?startDate="+year+"-0"+month+"-01&id="+j('#property_id').text(),
{ format: "json" },
function(data) {
document.pricesData = data;
document.firstDate = '';
j('#calendar_check_in').datepicker(checkInOptions);
/* Tip Tip */
j('.ui-datepicker-calendar td').tipTip({ defaultPosition: "right" });
for (var key in document.pricesData) {
var obj = document.pricesData[key];
if(obj['avail'] == 1 && document.firstDate == ''){
document.firstDate = key;
}
}
d = new Date(document.firstDate.substr(5));
d.setMonth(d.getMonth()+1);
});
function addPrice(date) {
calDate = new Date(date);
dateString = 'date_'+calDate.getFullYear()+'-'+('0'+(calDate.getMonth()+1).toString()).substr(-2)+'-'+('0'+(calDate.getDate()).toString()).substr(-2);
if(document.pricesData[dateString] != undefined){
var priceString = document.pricesData[dateString]['price'];
if(document.pricesData[dateString]['avail'] == "1"){
valid = true;
} else {
valid = false;
}
}else{
var priceString = 'Price not available';
valid = false;
}
return [valid, '', priceString];
}
function onMonthChange(year, month, inst){
/* Date Picker */
month--;
j.getJSON("/availability.php?startDate="+year+"-0"+month+"-01&id="+j('#property_id').text(),
{ format: "json" },
function(data) {
document.pricesData = data;
document.firstDate = '';
/* Tip Tip */
j('.ui-datepicker-calendar td').tipTip({ defaultPosition: "right" });
for (var key in document.pricesData) {
var obj = document.pricesData[key];
if(obj['avail'] == 1 && document.firstDate == ''){
document.firstDate = key;
}
}
d = new Date(document.firstDate.substr(5));
d.setMonth(d.getMonth()+1);
});
}
Thanks to anyone who takes the time to read this, hoping someone has some sort of solution for as it’s a bit of a show stopper at the moment!
Thank you!
When the user changes months in the datepicker, couldn’t you clear the currently displayed pricing and availability information? That way at least you wouldn’t have incorrect data displayed. Then, if needed, you could add some message informing the user that the other data is still loading.
I would recommend strongly against trying to use async:false. That is like the nuclear option. It will have other adverse affects to the site and doesn’t sound like it is really needed in your case.