jQuery UI datepicker with manual entry and dynamic min-date

by Bianca Kuehweidner

HTML

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<div>
  <label for="date1">Date 1:</label>
  <input type="text" class="datepicker" id="date1">
</div>
<div>
  <label for="date2">Date 2:</label>
  <input type="text" class="datepicker" id="date2">
</div>
<div>
  <label for="date3">Date 3:</label>
  <input type="text" class="datepicker" id="date3">
</div>

JavaScript

let d = new Date();
let nextValidDate = d.getDate() + "." + (d.getMonth() + 1) + "." + d.getFullYear();

$(document).on("blur change", ".datepicker", function () {
    nextValidDate = $(this).datepicker("getDate");
});

$(document).on('focus', '.datepicker',
    function () {
        $(this).datepicker({
            numberOfMonths: 1,
            firstDay: 1,
            changeMonth: true,
            changeYear: true,
            dateFormat: 'dd.mm.yy',
            minDate: nextValidDate
        });

        $(this).datepicker('show');
    });


$(document).on('blur', '.datepicker', function () {
    if ($(this).val().length >= 2) {
        parseInputDate(this);
    }
});



function parseInputDate(elm) {
  var currDate = new Date(),
      monDt = (('0'+currDate.getMonth()+1).slice(-2)+('0'+currDate.getDate()).slice(-2)), // get current month+date to compare
      inputVal = $(elm).val().match(/\d{2}/gi); // split date components into array of [dd,mm,yy,yy]
  // another date validation, by comparing parameters and date object result 
    var isValidDate = function(yyyy,mm,dd) {
	var dt = new Date(yyyy,parseInt(mm,10)-1,dd);
    return (dt.getFullYear()+'-'+('0'+(dt.getMonth()+1)).slice(-2)+'-'+('0'+dt.getDate()).slice(-2)) == yyyy+'-'+mm+'-'+dd;
  }		
  if (inputVal!=null && inputVal.length>=2) {    
    var year = currDate.getFullYear();
    if (monDt>(inputVal[1]+inputVal[0])) year++;
    // generate formatted text based on date component count
    // add date validation to catch invalid dates using (new Date('yyyy-mm-dd')).getTime() which will return NaN on invalid date
    var result = (inputVal.length==2 && isValidDate(year,inputVal[1],inputVal[0]) && inputVal[0]+'.'+inputVal[1]+'.'+year) || 
			   (inputVal.length==3 && isValidDate('20'+inputVal[2],inputVal[1],inputVal[0]) && inputVal[0]+'.'+inputVal[1]+'.20'+inputVal[2]) || 
			   (inputVal.length==4 && isValidDate(inputVal[2]+inputVal[3],inputVal[1],inputVal[0]) &&...