Friday, March 22, 2013

How to Dynamically Restrict From/To Dates with jQuery UI Datepicker

It has been awhile since my last post, but things sure have been busy over at Limelight Web Development! Anyway, I figured it was time to update the blog and pass along a useful piece of jQuery magic!

You are probably familiar with jQuery UI Datepicker already. It has a lot of options built in, a couple of which allow you to restrict the selectable 'to' and 'from' dates. The provided examples over at the jQuery UI site are useful on a single implementations, but what if you want to implement this across your entire site and not have to mess with it any more?

Let's assume your forms have a consistent structure across your entire application/site, like so:

 <!-- To/From Date Form Block -->
<form action="/action/" id="myform" method="post" name="myform">
  <div class="horiz">
    <div class="leftColumn">
      <label for="from_date">From:</label>
      <input class="datepicker" name="from_date" type="text" value="" />
    <div class="rightColumn">
      <label for="to_date">To:</label>
      <input class="datepicker" name="to_date" type="text" value="" />
  <div class="submitWrapper">
    <input name="submit_dates" type="submit" value="Submit" /> 

The main requirement being that all date inputs have class "datepicker", all from fields contain "from" in the name attribute and all to fields contain "to" in the name attribute and they are each descendants of a 'form' element. They don't have be direct children as you can see in the example code block above.

Now to implement datepicker across the entire site with automatically restricted maxDate and minDate on the appropriate fields, the following code will do all the work for you. It will make the to-date's minDate the same as the from-date's selected date. It will make the from-date's maxDate the same as the to-date's selected date.

 //jQuery UI Datepicker Universal Config
  showAnim: "slideDown",
  dateFormat: "mm/dd/yy",
  onSelect: function(dateText, inst){
   if( $(this).attr('name').indexOf('from') > -1 ) {
    var $from_date = $(this).datepicker("getDate");
    var $to_date_input = $(this).closest('form').find('.datepicker[name*="to"]');
    $to_date_input.datepicker("option","minDate", $from_date);
   } else if( $(this).attr('name').indexOf('to') > -1 ) {
    var $to_date = $(this).datepicker("getDate");
    var $from_date_input = $(this).closest('form').find('.datepicker[name*="from"]');
    $from_date_input.datepicker("option","maxDate", $to_date);