I am relatively new to JavaScript and JQuery. I wanted a Datepicker that has the following functionality:
- Weekends are not selectable
- Non working days (bank holidays etc.) are not selectable
- The first selectable day must be x number of full working days in the future, taking into account bank holidays and weekends
I looked at few examples and came up with this (the date format is dd/mm):
$(function() {
var holidays= [[3,1], [22,4], [25,4], [29,4], [2,5], [30,5], [29,8], [26,12], [27,12]];
var workingDayOffset = 10, selectedDate = new Date();
function nonWorkingDays(date) {
for (var j = 0; j < holidays.length; j++) {
if (date.getMonth() == holidays[j][1] - 1 && date.getDate() == holidays[j][0]) {
return [false, ''];
}
}
return [true, ''];
}
function beforeCurrentDate(date) {
if(date.getDate() === selectedDate.getDate() && date.getMonth() === selectedDate.getMonth() && date.getFullYear() === selectedDate.getFullYear())
{
return [true, ''];
}
return [date < selectedDate,''];
}
function nonAvailableDays(date) {
var noWeekend = $.datepicker.noWeekends(date), before = beforeCurrentDate(date), holiday = nonWorkingDays(date);
return [noWeekend[0] && before[0] && holiday[0], ''];
}
for(var i = 0; i < workingDayOffset; i++) {
selectedDate.setDate(selectedDate.getDate() + 1);
if(!nonAvailableDays(selectedDate)[0])
{
i--;
}
}
Date.prototype.formatDDMMYY=function(){
var dd = this.getDate(), mm = this.getMonth()+1, yyyy = this.getFullYear();
if(dd<10){
dd = '0' + dd;
}
if(mm<10){
mm = '0'+ mm;
}
return String(dd + "\/" + mm + "\/" + yyyy);
};
$( "#datepicker" ).val(selectedDate.formatDDMMYY());
$( "#datepicker" ).datepicker({ beforeShowDay: nonAvailableDays, dateFormat: 'dd/mm/yy', showOn: 'button', buttonText: "select", defaultDate: selectedDate,gotoCurrent: true}) ;
});
I am looking for a general critique of the code, but also there are a couple of things that I thought would be easier / cleaner:
In beforeCurrentDate I wanted to do a check that the date was less than selectedDate, in terms of the whole date, not including the time component. Using
date > selectedDate
would returnfalse
even if the date component was the same, due to the time part. I thought about setting the time on the selected date, but then GMT offset came into play. It seemed to me that it should be easier, in the end I added a fudge that check just the date components for a match.I am not sure adding
Date.prototype.formatDDMMYY
is the right way to go. Again, this felt like it should be more straight forward.
I am interested to hear your thoughts on this.