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 return- falseeven 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.
