Hamish McBrearty
Hamish McBrearty

Reputation: 179

Javascript date incrementing and looping over weekends

I'm trying to create a jQuery that takes the input of a form and changes one of the fields based on the previous form. The idea is, to take the service the customer selects, add two days to it then provide them with a list of five dates to choose from but exclude the weekends.

I'm not much of a JS or jQuery guy and while I have something mostly functional, it's not quite working as I'd expect.

Here's the fiddle I'm working on.

$("#ninja_forms_field_74").change(function() {
    var service = $("#ninja_forms_field_74").val();
    var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
    var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

    if (service == "2Days") {
        var someDate = new Date();
        var numberOfDaysToAdd = 2;
        someDate.setDate(someDate.getDate() + numberOfDaysToAdd);
        var dd = someDate.getDate();
        var mm = someDate.getMonth();
        var day = days[ someDate.getDay() ];

        if (day == "Saturday"){
            someDate.setDate(someDate.getDate() + 2);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }

        if (day == "Sunday"){
            someDate.setDate(someDate.getDate() + 1);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }

        var target = day + " " + dd + " " + months[mm];
        someDate.setDate(someDate.getDate() + numberOfDaysToAdd);
        someDate.setDate(someDate.getDate() + 1);
        var dd = someDate.getDate();
        var mm = someDate.getMonth();
        var day = days[ someDate.getDay() ];

        if (day == "Saturday"){
            someDate.setDate(someDate.getDate() + 2);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        if (day == "Sunday"){
            someDate.setDate(someDate.getDate() + 1);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        var target2 = day + " " + dd + " " + months[mm];someDate.setDate(someDate.getDate());

        someDate.setDate(someDate.getDate() + 1);
        var dd = someDate.getDate();
        var mm = someDate.getMonth();
        var day = days[ someDate.getDay() ];

        if (day == "Saturday"){
            someDate.setDate(someDate.getDate() + 2);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }

        if (day == "Sunday"){
            someDate.setDate(someDate.getDate() + 1);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        var target3 = day + " " + dd + " " + months[mm];someDate.setDate(someDate.getDate());

        someDate.setDate(someDate.getDate() + 1);
        var dd = someDate.getDate();
        var mm = someDate.getMonth();
        var day = days[ someDate.getDay() ];

        if (day == "Saturday"){
            someDate.setDate(someDate.getDate() + 2);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }

        if (day == "Sunday"){
            someDate.setDate(someDate.getDate() + 1);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        var target4 = day + " " + dd + " " + months[mm];someDate.setDate(someDate.getDate());

        someDate.setDate(someDate.getDate() +1);
        var dd = someDate.getDate();
        var mm = someDate.getMonth();
        var day = days[ someDate.getDay() ];
        if (day == "Saturday"){
            someDate.setDate(someDate.getDate() + 2);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        if (day == "Sunday"){
            someDate.setDate(someDate.getDate() + 1);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        var target5 = day + " " + dd + " " + months[mm];someDate.setDate(someDate.getDate());
        $("#ninja_forms_field_84").children().remove().end().append($("<option></option>").val(target).html(target));
        $("#ninja_forms_field_84").append($("<option></option>").val(target2).html(target2));
        $("#ninja_forms_field_84").append($("<option></option>").val(target3).html(target3));
        $("#ninja_forms_field_84").append($("<option></option>").val(target4).html(target4));
        $("#ninja_forms_field_84").append($("<option></option>").val(target5).html(target5));
    }
    if (service == "Fax"){

        var someDate = new Date();
        var numberOfDaysToAdd = 2;
        someDate.setDate(someDate.getDate() + numberOfDaysToAdd);
        var dd = someDate.getDate();
        var mm = someDate.getMonth();
        var day = days[ someDate.getDay() ];
        if (day == "Saturday"){
            //  var numberOfDaysToAdd = numberOfDaysToAdd + 2;
            someDate.setDate(someDate.getDate() + 2);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        if (day == "Sunday"){
            //  var numberOfDaysToAdd = numberOfDaysToAdd + 1;
            someDate.setDate(someDate.getDate() + 1);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        var target = day + " " + dd + " " + months[mm];someDate.setDate(someDate.getDate() + numberOfDaysToAdd);
        someDate.setDate(someDate.getDate() + 1);
        var dd = someDate.getDate();
        var mm = someDate.getMonth();
        var day = days[ someDate.getDay() ];
        if (day == "Saturday"){
            //  var numberOfDaysToAdd = numberOfDaysToAdd + 2;
            someDate.setDate(someDate.getDate() + 2);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        if (day == "Sunday"){
            //  var numberOfDaysToAdd = numberOfDaysToAdd + 1;
            someDate.setDate(someDate.getDate() + 1);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        var target2 = day + " " + dd + " " + months[mm];someDate.setDate(someDate.getDate());
        someDate.setDate(someDate.getDate() + 1);
        var dd = someDate.getDate();
        var mm = someDate.getMonth();
        var day = days[ someDate.getDay() ];
        if (day == "Saturday"){
            //  var numberOfDaysToAdd = numberOfDaysToAdd + 2;
            someDate.setDate(someDate.getDate() + 2);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        if (day == "Sunday"){
            //  var numberOfDaysToAdd = numberOfDaysToAdd + 1;
            someDate.setDate(someDate.getDate() + 1);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        var target3 = day + " " + dd + " " + months[mm];someDate.setDate(someDate.getDate());
        someDate.setDate(someDate.getDate() + 1);
        var dd = someDate.getDate();
        var mm = someDate.getMonth();
        var day = days[ someDate.getDay() ];
        if (day == "Saturday"){
            //  var numberOfDaysToAdd = numberOfDaysToAdd + 2;
            someDate.setDate(someDate.getDate() + 2);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        if (day == "Sunday"){
            //  var numberOfDaysToAdd = numberOfDaysToAdd + 1;
            someDate.setDate(someDate.getDate() + 1);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        var target4 = day + " " + dd + " " + months[mm];someDate.setDate(someDate.getDate());
        someDate.setDate(someDate.getDate() + 1);
        var dd = someDate.getDate();
        var mm = someDate.getMonth();
        var day = days[ someDate.getDay() ];
        if (day == "Saturday"){
            //  var numberOfDaysToAdd = numberOfDaysToAdd + 2;
            someDate.setDate(someDate.getDate() + 2);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        if (day == "Sunday"){
            //  var numberOfDaysToAdd = numberOfDaysToAdd + 1;
            someDate.setDate(someDate.getDate() + 1);
            var dd = someDate.getDate();
            var mm = someDate.getMonth();
            var day = days[ someDate.getDay() ];
        }
        var target5 = day + " " + dd + " " + months[mm];someDate.setDate(someDate.getDate());
        $("#ninja_forms_field_84").children().remove().end().append($("<option></option>").val(target).html(target));
        $("#ninja_forms_field_84").append($("<option></option>").val(target2).html(target2));
        $("#ninja_forms_field_84").append($("<option></option>").val(target3).html(target3));
        $("#ninja_forms_field_84").append($("<option></option>").val(target4).html(target4));
        $("#ninja_forms_field_84").append($("<option></option>").val(target5).html(target5));
    }
    if (service == "SameDay"){
        var d = new Date();
        var day = d.getDay();
        var dd = d.getDate();
        var mm = d.getMonth();
        var target = days[day] + " " + dd + " " + months[mm];
        $("#ninja_forms_field_84").children().remove().end().append($("<option></option>").val(target).html(target));
    }
});

Upvotes: 3

Views: 606

Answers (1)

Mic
Mic

Reputation: 4004

I put together a function that returns an array of date objects for a specified number of future dates, excluding weekends. I currently have it generating 14 days, so that you can see the month roll. Try using it to get your list of dates.

function getFutureDays(count) {
  var days = [];
  var today = new Date();
  var offset = 1; //start with tomorrow
  //while loop continues adding non-weekend dates until the array length equals the supplied count.
  while(days.length < count) {
    var nextDate = new Date();
    nextDate.setDate(today.getDate() + offset);
    //weekend check below - only add to the array if it's not a 0 (Sun) or 6 (Sat)
    if(nextDate.getDay() !== 0 && nextDate.getDay() !== 6) {
      days.push(nextDate);
    }
    offset++; //increase the offset to move onto the next day.
  }
  return days;
}

document.write(getFutureDays(14).join('<br />'));

Dealing with the formatting, I would suggest making it a separate function. Starting with a fragment of code you already have:

  var d = new Date();
  var day = d.getDay();
  var dd = d.getDate();
  var mm = d.getMonth();
  var target = days[day] + " " + dd + " " + months[mm];

This can do essentially what you want. You have the months and days string arrays currently being declared each time the function is called. It's a style choice, but I personally like to put them in a closure, building on what you had like this:

  var formatDate = (function (days, months) {return 
    function(d) {
      //var d = new Date(); this becomes the argument
      var day = d.getDay();
      var dd = d.getDate();
      var mm = d.getMonth();
      return days[day] + " " + dd    + " " + months[mm]; //this can return instead of being a variable
    }
  })(
     ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], 
    ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
  );

This keeps them out of the global namespace, but you don't have to recreate them all the time. It's worth pointing out a few other options at this point. Instead of writing your own format function, you could have looked at some of the built-in ones, like Date.toLocaleDateString. You can see them here: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date

Moment.js is a well established library that also has some formatting methods. http://momentjs.com/

Now if you wanted to get an array of strings representing the dates, one option, provided you're targeting reasonably modern browsers, is to take the array returned from getFutureDays and use the Array.map function to generate an array of strings.

 var formattedDates = getFutureDays(5).map(formatDate);

Another option would be to put the formatDate call right in the getFutureDays function, in the same line as the push to the array.

days.push(formatDate(nextDate));

This would make the array returned from it into strings containing your formatted representations of the dates rather than date objects themselves. It's a bit cleaner for your case as long you're not needing to use the date objects elsewhere. Bringing it all into the basic structure of your code, it looks something like this.

var formatDate = (function (days, months) {return function(d) {
	  var day = d.getDay();
    var dd = d.getDate();
	  var mm = d.getMonth();
    return days[day] + " " + dd    + " " + months[mm];
    //return target;
}})(['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);

function getFutureDays(count, offset) {
  var days = [];
  var today = new Date();
  var offset = offset ? offset : 1; //start with tomorrow unless something else is supplied
  //while loop continues adding non-weekend dates until the array length equals the supplied count.
  while(days.length < count) {
    var nextDate = new Date();
    nextDate.setDate(today.getDate() + offset);
    //weekend check below - only add to the array if it's not a 0 (Sun) or 6 (Sat)
    if(nextDate.getDay() !== 0 && nextDate.getDay() !== 6) {
      days.push(formatDate(nextDate));
    }
    offset++; //increase the offset to move onto the next day.
  }
  return days;
}

$("#ninja_forms_field_74").change(function() {
  var service = $("#ninja_forms_field_74").val();
  var daysToAdd = [];
  if (service === "2Days") {
     daysToAdd = getFutureDays(5, 2);
  } else if (service === "Fax") {
    daysToAdd = getFutureDays(5, 1);
  } else {
    daysToAdd.push(formatDate(new Date()));
  }
  var daysField = $("#ninja_forms_field_84");
  daysField.children().remove().end();
  for(var i = 0; i < daysToAdd.length; i++) {
    daysField.append($("<option></option>").val(daysToAdd[i]).html(daysToAdd[i]));
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
Service Type
</p>
<select name="ninja_forms_field_74" id="ninja_forms_field_74">
    <option value="">-- select an option --</option>
    <option value="SameDay">Same Day</option>
    <option value="Fax">Fax to Pharmacy</option>
    <option value="2Days">Two business days</option>
</select>
<p>Day to collect</p>
<select name="ninja_forms_field_84" id="ninja_forms_field_84">

Note that I also added an option offset argument to the getFutureDays function specifying the number of days forward to start from.

Upvotes: 1

Related Questions