ui.datepicker's "unselectable" rules now applicable to text input as well

ui.datepicker's "unselectable" rules now applicable to text input as well

We needed the ability to let users enter dates into the text field manually, but still wanted the field to validate against the same dates the datepicker doesn't allow you to select.

After prying datepicker apart, I built a rule for the Validator plugin which copies datepicker's own logic. So even if you added a custom function to beforeShowDay, the validator will obey the same 'selectable' rules datepicker does when rendering the calendar.
  1. jQuery.validator.addMethod("vdate", function(value, element) {
  2.         // Datepicker's internal method for choosing selectable ported to a custom validator method.
  3.         // All criteria are the same, except othermonth is omitted.
  4.         var inst = $.data(element,'datepicker'); // instance data used internally by datepicker's functions
  5.         var printDate = $(element).datepicker("getDate"); // date passed is not massaged for DST like printDate in original code
  6.         var minDate = $.datepicker["_getMinMaxDate"](inst, 'min', true);
  7.         var maxDate = $.datepicker["_getMinMaxDate"](inst, 'max');
  8.         var beforeShowDay = $.datepicker["_optionDatepicker"](element,'beforeShowDay');
  9.         var daySettings = (beforeShowDay ? beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, '']);
  10.         var unselectable = (!daySettings[0] || (minDate !=null && (printDate < minDate)) || (maxDate !=null && (printDate > maxDate)));
  11.         return (this.optional(element) || !unselectable);
  12. }, "Please choose a valid date");
This validator is fine grained; that is to say, if you set defaults for one master datepicker and then created several instances of datepickers with variants in their minDate/maxDate/beforeShowDay rules, so long as they all have the class 'vdate' the validator should apply the rules specific to that instance.

Part of the reason this was so onerous was because datepicker inlines all the logic for date rendering rather than storing an array. Worse, there's no utility function for accepting a date and returning the boolean selectable.

I would make that function a top priority for future revisions to (or replacements for) ui.datepicker; a picker which supports multiple entry contexts ought to apply the same standards to each of them.

If I weren't under deadline, I'd write it myself.