7
\$\begingroup\$

I am relatively new to JavaScript and JQuery. I wanted a Datepicker that has the following functionality:

  1. Weekends are not selectable
  2. Non working days (bank holidays etc.) are not selectable
  3. 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:

  1. 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 return false 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.

  2. 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.

\$\endgroup\$
2
\$\begingroup\$

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. )

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.