0

In a gravity form I have been able to disable weekends and public holidays from Datepicker 1 (from date) and Datepicker 2 (to date).

In Datepicker 2 we want to select the first workday three days after the date selected in Datepicker 1. 

See: http://returatrv.staging.wpengine.com/bestilling-container-borettslag/

If you select feb 17 in cal1, feb 20 is selected in DP2, which is correct. The setDate is getDate +3 days. 

When setDate ends up on a weekend or disabled date, it should jump to the next work-day. If feb 19 is selected in DP1, feb 24 should be selected in DP2 (first workday). How can I use the code already in place (line 9-15) to set setDate to the first non-disabled day in the array?

I have a feeling I could reuse the code in

 optionsObj.beforeShowDay = function(date) { ...

to change the setDate for DP2.

 set_date.setDate(set_date.getDate() + 3); //check if the result is in disabled days / weekends

I would really appreciate som help on this ;) Although many other questions are similar (like Add days after date is selected excluding weekends and holidays), I have not been able to solve this.

  gform.addFilter('gform_datepicker_options_pre_init', function(optionsObj,
    formId, fieldId) {

    if (formId == <?php echo $skjemaID; ?> && fieldId == 7) {

     // Disable holidays and weekends from datapickers
     // Could I use this to find first work-day?
     optionsObj.beforeShowDay = function(date) {

     // array of holidays from external json-source
     currentDate = jQuery.datepicker.formatDate('yy-mm-dd', date),
     day = date.getDay();

      return [!(disabledDays.indexOf(currentDate) != -1 || day == 0 ||
        day == 6)];
    };


      optionsObj.minDate = 1;
      optionsObj.onClose = function(dateText, inst) {
        var min_date = $.datepicker.parseDate('dd/mm/yy', dateText),
            set_date = $.datepicker.parseDate('dd/mm/yy', dateText),
            end_date = $.datepicker.parseDate('dd/mm/yy', dateText);

            // set minDate in datepicker 1 to nest day
            min_date.setDate(min_date.getDate() + 1);

            // Find first workday after 3 days
            // Samples of expected behaviour:
            // Select feb 10 in dp1 - show feb 13 in dp2
            // Select feb 12 in dp1 - show feb 17 in dp2
            // Select feb 27 in dp1 - show mar in dp2

            set_date.setDate(set_date.getDate() +3);

            // Check if set_date is in disabledDays or weekend
            // if yes, add a day, check again
            // if not, select set_day in datepicker 2 

        $('#input_<?php echo $skjemaID; ?>_8').datepicker('option',
          'minDate', min_date).datepicker('setDate', set_date);
      };
    }
    return optionsObj;
  });

Please help me in the right direction; I have been struggling quite some time with this.

  • `I have not been able to solve this.` why not? The `while` approach is the immediate solution I thought about. – Mosh Feu Feb 13 '20 at 10:30
  • See comment under. Why can't result of `function isInArray(disabledDates, value) { return [!(disabledDates.indexOf(value) != -1 || day == 0 || day == 6)]; }` be evaluated in if/then or while-loop? – Reidar Nygård Feb 19 '20 at 08:25
  • I'm not sure why you need to stop the `while` loop if the data is in `disabledDate`. You just need to not skip also if the date is in disabled. https://jsbin.com/sodidey/edit?js,console – Mosh Feu Feb 19 '20 at 09:59
  • Thanks Mosh Feu for helping me along the way to fix this ;). I basically just needed the following do/while-loop: do { set_date.setDate(set_date.getDate() + 1); } while (!isInArray(disabledDates, set_date)); – Reidar Nygård Feb 21 '20 at 07:46

2 Answers2

0

Yes, use the AddBusinessDays function from the linked "similar question" and replace the call to noWeekendsOrHolidays with your beforeShowDay function. You would also need to pass in the start date instead of using today.

Keith
  • 1
  • I have added a function that evaluates if setDate is within disabledDays, but although it returns True or False in console. I can't get a loop to stop when it is FALSE. ` function isInArray(disabledDates, value) { return [!(disabledDates.indexOf(value) != -1 || day == 0 || day == 6)]; } if (check != 'true') { console.log( 'Check in first loop: ' + check ); set_date.setDate(set_date.getDate() + 1); var check = isInArray(disabledDates, set_date); } // Does not work – Reidar Nygård Feb 19 '20 at 08:19
0

After much testing I was able to find the problem and solve this. The final code (replacing optionsObj.onClose = function(dateText, inst))

optionsObj.onClose = function(dateText, inst) {

    var min_date = $.datepicker.parseDate('dd-mm-yy', dateText),
        set_date = $.datepicker.parseDate('dd-mm-yy', dateText);

  function isInArray(disabledDates, dateToCheck) {
   const day = dateToCheck.getDay();
    return !(disabledDates.indexOf(dateToCheck) != -1 || day === 0 || day == 6);
    } 

    min_date.setDate(min_date.getDate() + 1);
    set_date.setDate(set_date.getDate() + 2);

    do {
      set_date.setDate(set_date.getDate() + 1);
    }
    while (!isInArray(disabledDates, set_date));

    $('#input_<?php echo $skjemaID; ?>_8').datepicker('option',
      'minDate', min_date).datepicker('setDate', set_date);
  };

Thanks for help, the JSbin from Mosh Feu made me see what was wrong.