Roeland
Roeland

Reputation: 3858

a jquery datepicker plugin that allows user to choose just a month and year

I am currently using jquery ui datepicker for forms that have date inputs. The problem is on my current form I need the user to just select a month. How would I got about doing this using jquery ui date picker?

Upvotes: 2

Views: 698

Answers (3)

brianpeiris
brianpeiris

Reputation: 10795

You could take advantage of the configurability of jQuery UI's datepicker and use some CSS and JavaScript to achieve the behavior you've described. The following solution uses CSS to hide the calendar portion of the datepicker and some JavaScript to handle the month and year selection:

Working Demo

http://jsbin.com/uzafo (editable via http://jsbin.com/uzafo/edit)

Full Source

monthAndYear.css

.ui-datepicker.monthAndYear {
  width: 20em;
}
.ui-datepicker.monthAndYear .ui-datepicker-calendar {
  display: none;
}
.ui-datepicker.monthAndYear .ui-datepicker-header {
  margin-bottom: 0.2em;
}

monthAndYear.js

var monthAndYear = {
  /**
   * datepicker doesn't update the input field since
   * we don't actually select a date, so we have to 
   * manually determine the selected month and year
   * and update the input field ourselves.
  **/
  getMonthAndYear: function (dateText, instance) {
    if (!instance.settings.monthAndYear) {
      return;
    }

    var
      selectedYear = instance.selectedYear,
      selectedMonth = instance.selectedMonth,
      selectedDate = new Date(selectedYear, selectedMonth),
      dateFormat = 
        instance.settings.originalDateFormat ||
        instance.settings.dateFormat ||
        $.datepicker.regional[''].dateFormat;

    $(this).val($.datepicker.formatDate(dateFormat, selectedDate));
  },

  /**
   * If we want to use normal datepickers on the same page
   * we have to add and remove the modified styles accordingly
  **/
  styleMonthAndYear: function (input, instance) {
    var
      dpDiv = instance.dpDiv,
      className = 'monthAndYear';
    if (instance.settings.monthAndYear) {
      dpDiv.addClass(className);
    }
    else {
      dpDiv.removeClass(className);
    }
  }
}

main.js

$.datepicker.setDefaults({
  beforeShow: monthAndYear.styleMonthAndYear,
  onClose: monthAndYear.getMonthAndYear
});

$(function () {
  $('#vanillaDatePicker').datepicker();

  $('#modifiedDatepickerOne').datepicker({
    monthAndYear: true
  });

  $('#modifiedDatepickerTwo').datepicker({
    monthAndYear: true,
    changeYear: true
  });

  /**
   * We have to do a bit of trickery here, in order to use a
   * dateFormat ('yy-mm') that datepicker normally wouldn't accept.
   * We parse the date manually and clear the dateFormat setting
   * in order to force datepicker to use the defaultDate setting.
   * We also save the original dateFormat so that we can
   * use it later in getMonthAndYear.
  **/
  $('#modifiedDatepickerThree').datepicker({
    monthAndYear: true,
    changeYear: true,
    dateFormat: 'yy-mm',
    beforeShow: function (input, instance) {
      monthAndYear.styleMonthAndYear.call(this, input, instance);

      var 
        date = $.datepicker.parseDate('yy-mm-dd', input.value + '-01'),
        originalDateFormat =
          instance.settings.dateFormat ||
          instance.settings.originalDateFormat;

      return {
        originalDateFormat: originalDateFormat,
        dateFormat: '',
        defaultDate: date
      };
    }
  });
});

main.html

<!doctype html>
<html lang="en">
  <head>
    <title>jQuery UI datepicker Month and Year Modification</title>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8" />

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
    <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css" type="text/css" />
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js" type="text/javascript"></script>

    <link rel="stylesheet" href="monthAndYear.css" type="text/css" />
    <script src="monthAndYear.js" type="text/javascript"></script>

    <script src="main.js" type="text/javascript"></script>
  </head>
  <body>
    <h1>jQuery UI datepicker Month and Year Modification</h1>

    <h2>Vanilla datepicker</h2>
    <input type="text" id="vanillaDatePicker" value="03/20/2009" />

    <h2>Modified datepicker</h2>
    <input type="text" id="modifiedDatepickerOne" value="03/20/2009" />

    <h2>Modified datepicker with a dropdown to change the year</h2>
    <input type="text" id="modifiedDatepickerTwo" value="03/20/2009" />

    <h2>Modified datepicker with custom date format</h2>
    <input type="text" id="modifiedDatepickerThree" value="2009-03" />
  </body>
</html>

Upvotes: 5

Rob Van Dam
Rob Van Dam

Reputation: 7960

What about ignoring the selected day in the display (and forcing the date to the 1st for some consistency):

$('.selector').datepicker({
    dateFormat: 'mm/yyyy',
    onSelect: function(dateText, inst) {
        $(this).datepicker('setDate', dateText.replace(/[0-9]{2}$/, '01'));
    }
});

Or else you could do the same thing on the server (although its less obvious to the user).

For the sake of usability you might need to say something like "Choose any day in the desired month".

Upvotes: 0

micahwittman
micahwittman

Reputation: 12476

I'm not aware of a jQuery datepicker where the UI of the widget operates on month and year only.

An alternative approach: Masked Input Plugin.

Using mm/yyyy as an example:

$("#date").mask("99/9999");

Upvotes: 0

Related Questions