JQuery Datepicker – Selecting just Month or Year

Quick code post – We’re working with a client who needs to be able to select imprecise dates – either an exact date, the month and year, or just the year. Most date pickers aren’t set to handle this case, and I didn’t really want to write one from scratch.

We were already using the JQuery Datepicker so with some Javascript magic, I turned it into a DatePicker with Month and Year.

First, I created a method to register a Date Picker, since we have them in many places:

function registerDatePicker(element) {
  $(element).datepicker({
    changeMonth: true, 
    changeYear: true, 
    yearRange: 'c-100:c+10', 
    beforeShow: function(input, inst) { setDateFromString(input); }});
  $(element).focus(function() {
    $(this).datepicker('show');
    if( $(this).datepicker('widget').find('tr#month-year-select').length == 0 ) {
      var tbody = $(this).datepicker('widget').find('tbody');
      tbody.prepend('<tr id="month-year-select"><td colspan="3" align="center"><p class="ui-state-default" id="datepicker-month-select">Select Month</p></td><td><p> </p><td colspan="3" align="center"><p id="datepicker-year-select" class="ui-state-default">Select Year</p></td></tr>');
      tbody.find('#datepicker-year-select').click(function() { pushYear(element) });
      tbody.find('#datepicker-month-select').click(function() { pushMonthYear(element); });
    }
  });
}

Notice that I’m adding in buttons to select the month or year right after the tbody. Because the Datepicker doesn’t actually select a date at default, or whenever you change the month or year, the following methods make the right thing happen:

function pushMonthYear(element) {
  var shortMonthString = $('.ui-datepicker-month option:selected').text();
  var monthNames = $(element).datepicker("option", "monthNames")
  var shortMonthNames = $(element).datepicker("option", "monthNamesShort")
  var monthString = monthNames[shortMonthNames.indexOf(shortMonthString)];
  var year = $('.ui-datepicker-year option:selected').text();
  $(element).val(monthString + " " + year);
  $(element).datepicker("hide");
}
function pushYear(element) {
  var year = $('.ui-datepicker-year option:selected').text();
  $(element).val(year);
  $(element).datepicker("hide");
}

Finally, because we want it to go to the right screen whenever there is something already in the box, there’s this method, called beforeShow:

function setDateFromString(element) {
  var dateString = $(element).val();
  var createdDate = null;
  //Input element has '1994'
  if(dateString.length == 4) {
    createdDate = new Date(dateString, 1, 1, 0, 0, 0);
    $(element).val("1/1/" + dateString);
  //Input element has 'September 1994'
  } else if (dateString.split(' ').length == 2) {
    var splitDate = dateString.split(' ');
    var monthString = splitDate[0];
    var year = splitDate[1];
    var month = $(element).datepicker("option", "monthNames").indexOf(monthString) + 1;
    $(element).val(month + "/1/" + year);
  }
}

Viola! A bit hackish, but it works well.

Datepicker with Month and Year

Comments on this entry are closed.