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 > selectedDatewould returnfalseeven 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.formatDDMMYYis the right way to go. Again, this felt like it should be more straight forward.
I am interested to hear your thoughts on this.
1 Answer 1
for 1)
var today = new Date();
today.setTime(0); // resets the time. (midnight)
I believe this will fix the date comparison issue
for 2)
It just sucks that there isn't a built-in for this sort of thing. I would suggest not putting it on the Date prototype just in case it conflicts with some other date function/library down the road. Its seems to be only a matter of preference though.
(if you Google: JavaScript format date you'll see many other examples of formatting the date or https://stackoverflow.com/q/1056728/684890 where there are a few alternatives suggested in case you want some more functionality. )