8
\$\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\$

1 Answer 1

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\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.