Date Range Picker Similar to Google Analytics

I’ve always loved the calendar date range selector in Google Analytics, it’s extremely user-friendly for the task of selecting a range of dates; much more so than the typical dual input boxes with independent calendars. There are a few options out there for replicating the Google Analytics range picker, however I couldn’t seem to find any that offered the functionality, looks, and ease of use right out of the box. The closest I could find was the DatePicker offered by Stefan Petre, so I decided to use that as a starting point and create a Google Analytics inspired DatePicker of my own.

My version builds off of Petre’s with the following changes:

  • Split stylesheet into base.css to allow easier styling, and dark.css as the first full style.
  • Created clean.css to provide a style similar to Google Analytics.
  • Clicking the calendar month title selects the whole month when in ‘range’ mode.
  • Removed the ‘week’ column.
  • Heavy refactoring/commenting of the code.
  • Created new examples page and documentation suite.

Documentation and Download

See the following links below for the source code, examples page and documentation page.

Widget Code

To create the above date drop-down widget, you can use code like the following:

Includes

First download jQuery and DatePicker and include them:

<script type="text/javascript" src="/js/jquery/jquery.js"></script>
<script type="text/javascript" src="/js/datepicker/js/datepicker.js"></script>
<link rel="stylesheet" type="text/css" href="/js/datepicker/css/base.css" />
<link rel="stylesheet" type="text/css" href="/js/datepicker/css/clean.css" />

HTML Markup

Add the following HTML markup where you want the widget positioned:

<div id="date-range">
  <div id="date-range-field">
    <span></span>
    <a href="#">&#9660;</a>
  </div>
  <div id="datepicker-calendar"></div>
</div>

JavaScript

The following JavaScript will bind the DatePicker calendar to the <div>, update the date display, and handle displaying/hiding the calendar on click.

<script type="text/javascript">
  $(document).ready(function() {

  var to = new Date();
  var from = new Date(to.getTime() - 1000 * 60 * 60 * 24 * 14);

  $('#datepicker-calendar').DatePicker({
    inline: true,
    date: [from, to],
    calendars: 3,
    mode: 'range',
    current: new Date(to.getFullYear(), to.getMonth() - 1, 1),
    onChange: function(dates,el) {
      // update the range display
      $('#date-range-field span').text(dates[0].getDate()+' '+dates[0].getMonthName(true)+', '+dates[0].getFullYear()+' - '+
                                        dates[1].getDate()+' '+dates[1].getMonthName(true)+', '+dates[1].getFullYear());
     }
   });

   // initialize the special date dropdown field
   $('#date-range-field span').text(from.getDate()+' '+from.getMonthName(true)+', '+from.getFullYear()+' - '+
                                        to.getDate()+' '+to.getMonthName(true)+', '+to.getFullYear());

   // bind a click handler to the date display field, which when clicked
   // toggles the date picker calendar, flips the up/down indicator arrow,
   // and keeps the borders looking pretty
   $('#date-range-field').bind('click', function(){
     $('#datepicker-calendar').toggle();
     if($('#date-range-field a').text().charCodeAt(0) == 9660) {
       // switch to up-arrow
       $('#date-range-field a').html('&#9650;');
       $('#date-range-field').css({borderBottomLeftRadius:0, borderBottomRightRadius:0});
       $('#date-range-field a').css({borderBottomRightRadius:0});
     } else {
       // switch to down-arrow
       $('#date-range-field a').html('&#9660;');
       $('#date-range-field').css({borderBottomLeftRadius:5, borderBottomRightRadius:5});
       $('#date-range-field a').css({borderBottomRightRadius:5});
     }
     return false;
   });

   // global click handler to hide the widget calendar when it's open, and
   // some other part of the document is clicked.  Note that this works best
   // defined out here rather than built in to the datepicker core because this
   // particular example is actually an 'inline' datepicker which is displayed
   // by an external event, unlike a non-inline datepicker which is automatically
   // displayed/hidden by clicks within/without the datepicker element and datepicker respectively
   $('html').click(function() {
     if($('#datepicker-calendar').is(":visible")) {
       $('#datepicker-calendar').hide();
       $('#date-range-field a').html('&#9660;');
       $('#date-range-field').css({borderBottomLeftRadius:5, borderBottomRightRadius:5});
       $('#date-range-field a').css({borderBottomRightRadius:5});
     }
   });

   // stop the click propagation when clicking on the calendar element
   // so that we don't close it
   $('#datepicker-calendar').click(function(event){
     event.stopPropagation();
   });
 });
</script>

CSS

And finally the CSS to style the dropdown widget:

<style type="text/css">
  /* Style the calendar custom widget */
  #date-range {
    position:relative;
  }
  #date-range-field {
    width: 290px;
    height: 26px;
    overflow: hidden;
    position: relative;
    cursor:pointer;
    border: 1px solid #CCCCCC;
    border-radius: 5px 5px 5px 5px;
  }

  #date-range-field a  {
    color:#B2B2B2;
    background-color:#F7F7F7;
    text-align:center;
    display: block;
    position: absolute;
    width: 26px;
    height: 23px;
    top: 0;
    right: 0;
    text-decoration: none;
    padding-top:6px;
    border-radius: 0 5px 5px 0;
  }

  #date-range-field span {
    font-size: 12px;
    font-weight: bold;
    color: #404040;
    position: relative;
    top: 0;
    height: 26px;
    line-height: 26px;
    left: 5px;
    width: 250px;
    text-align: center;
  }

  #datepicker-calendar {
    position: absolute;
    top: 27px;
    left: 0;
    overflow: hidden;
    width: 497px;
    height:153px;
    background-color: #F7F7F7;
    border: 1px solid #CCCCCC;
    border-radius: 0 5px 5px 5px;
    display:none;
    padding:10px 0 0 10px;
  }

  /* Remove default border from the custom widget since we're adding our own. */
  #datepicker-calendar div.datepicker {
    background-color: transparent;
    border: none;
    border-radius: 0;
    padding: 0;
  }
</style>