jQuery UI DatePicker to show month year only

JavascriptJqueryDateJquery UiJquery Ui-Datepicker

Javascript Problem Overview


I am using jQuery date picker to display the calendar all over my app. I want to know if I can use it to display the month and year (May 2010) and not the calendar?

Javascript Solutions


Solution 1 - Javascript

Here's a hack (updated with entire .html file):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.js"></script>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
	<link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css">
    <script type="text/javascript">
        $(function() {
            $('.date-picker').datepicker( {
		    changeMonth: true,
		    changeYear: true,
		    showButtonPanel: true,
		    dateFormat: 'MM yy',
		    onClose: function(dateText, inst) { 
			    $(this).datepicker('setDate', new Date(inst.selectedYear, inst.selectedMonth, 1));
		    }
            });
        });
    </script>
    <style>
    .ui-datepicker-calendar {
	    display: none;
	}
    </style>
</head>
<body>
	<label for="startDate">Date :</label>
	<input name="startDate" id="startDate" class="date-picker" />
</body>
</html>

EDIT jsfiddle for the above example: http://jsfiddle.net/DBpJe/7755/

EDIT 2 Adds the month year value to input box only on clicking of Done button. Also allows to delete input box values, which isn't possible in above field http://jsfiddle.net/DBpJe/5103/

EDIT 3 updated Better Solution based on rexwolf's solution down. http://jsfiddle.net/DBpJe/5106

Solution 2 - Javascript

This code is working flawlessly to me:

<script type="text/javascript">
$(document).ready(function()
{   
    $(".monthPicker").datepicker({
        dateFormat: 'MM yy',
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,

        onClose: function(dateText, inst) {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $(this).val($.datepicker.formatDate('MM yy', new Date(year, month, 1)));
        }
    });

    $(".monthPicker").focus(function () {
        $(".ui-datepicker-calendar").hide();
        $("#ui-datepicker-div").position({
            my: "center top",
            at: "center bottom",
            of: $(this)
        });
    });
});
</script>

<label for="month">Month: </label>
<input type="text" id="month" name="month" class="monthPicker" />

Output is:

enter image description here

Solution 3 - Javascript

@Ben Koehler, that's prefect! I made a minor modification so that using a single instance of the date picker more than once works as expected. Without this modification the date is parsed incorrectly and the previously selected date is not highlighted.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
    <link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css">
    <script type="text/javascript">
    $(function() {
        $('.date-picker').datepicker( {
            changeMonth: true,
            changeYear: true,
            showButtonPanel: true,
            dateFormat: 'MM yy',
            onClose: function(dateText, inst) { 
                var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
                var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
                $(this).datepicker('setDate', new Date(year, month, 1));
            },
            beforeShow : function(input, inst) {
                var datestr;
                if ((datestr = $(this).val()).length > 0) {
                    year = datestr.substring(datestr.length-4, datestr.length);
                    month = jQuery.inArray(datestr.substring(0, datestr.length-5), $(this).datepicker('option', 'monthNamesShort'));
                    $(this).datepicker('option', 'defaultDate', new Date(year, month, 1));
                    $(this).datepicker('setDate', new Date(year, month, 1));
                }
            }
        });
    });
    </script>
    <style>
    .ui-datepicker-calendar {
        display: none;
        }
    </style>
</head>
<body>
    <label for="startDate">Date :</label>
    <input name="startDate" id="startDate" class="date-picker" />
</body>
</html>

Solution 4 - Javascript

The above answers are pretty good. My only complaint is that you can't clear the value once it's been set. Also I prefer the extend-jquery-like-a-plugin approach.

This works perfect for me:

$.fn.monthYearPicker = function(options) {
    options = $.extend({
    	dateFormat: "MM yy",
    	changeMonth: true,
    	changeYear: true,
    	showButtonPanel: true,
    	showAnim: ""
    }, options);
    function hideDaysFromCalendar() {
    	var thisCalendar = $(this);
    	$('.ui-datepicker-calendar').detach();
    	// Also fix the click event on the Done button.
    	$('.ui-datepicker-close').unbind("click").click(function() {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            thisCalendar.datepicker('setDate', new Date(year, month, 1));
    	});
    }
    $(this).datepicker(options).focus(hideDaysFromCalendar);
}

Then invoke like so:

$('input.monthYearPicker').monthYearPicker();

Solution 5 - Javascript

<style>
.ui-datepicker table{
	display: none;
}

<script type="text/javascript">
$(function() {
	$( "#manad" ).datepicker({
		changeMonth: true,
		changeYear: true,
		showButtonPanel: true,
		dateFormat: 'yy-mm',
		onClose: function(dateText, inst) { 
		    var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
		    var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
		    $(this).datepicker('setDate', new Date(year, month, 1));
		},
		beforeShow : function(input, inst) {
		    if ((datestr = $(this).val()).length > 0) {
		    	actDate = datestr.split('-');
		        year = actDate[0];
		        month = actDate[1]-1;
				$(this).datepicker('option', 'defaultDate', new Date(year, month));
		        $(this).datepicker('setDate', new Date(year, month));
		    }
		}
	});
});

This will solve the problem =) But I wanted the timeFormat yyyy-mm

Only tried in FF4 though

Solution 6 - Javascript

I had this same need today and found this on github, works with jQueryUI and has month picker in place of days in calendar

https://github.com/thebrowser/jquery.ui.monthpicker

Solution 7 - Javascript

Here's what I came up with. It hides the calendar without needing an extra style block and adds a clear button to deal with the problem of not being able to clear the value once you click on the input. Also works nicely with multiple monthpickers on the same page.

HTML:

<input type='text' class='monthpicker'>

JavaScript:

$(".monthpicker").datepicker({
    changeMonth: true,
    changeYear: true,
    dateFormat: "yy-mm",
    showButtonPanel: true,
    currentText: "This Month",
    onChangeMonthYear: function (year, month, inst) {
        $(this).val($.datepicker.formatDate('yy-mm', new Date(year, month - 1, 1)));
    },
    onClose: function(dateText, inst) {
        var month = $(".ui-datepicker-month :selected").val();
        var year = $(".ui-datepicker-year :selected").val();
        $(this).val($.datepicker.formatDate('yy-mm', new Date(year, month, 1)));
    }
}).focus(function () {
    $(".ui-datepicker-calendar").hide();
}).after(
    $("<a href='javascript: void(0);'>clear</a>").click(function() {
        $(this).prev().val('');
    })
);

Solution 8 - Javascript

Like many others, I've encountered numerous problems trying to do this, and only a combination of the solutions posted, and eventually a big hack to make it perfect, has landed me a solution which works with all date formats and localization, just like normal datepickers.

Problems with other solutions in this thread that I've tried:

  1. Selecting a new date in a datepicker, would also change the (internal) date of other datepickers, so when you opened the other ones again (or tried getting their date), they would have a different date than the one displayed in their assigned input-field.
  2. The datepicker wouldn't "remember" the date when opened again.
  3. The code for juggling the dates used substringing so it wasn't compatible with all formats.
  4. The input-field wasn't updated correctly, if you typed in a wrongly formatted input-string for a date, and then clicked 'Close' on the datepicker.
  5. The monthpicker only changed the input-field on closing it, rather than whenever the values were changed.
  6. You couldn't have normal datepickers, which show the days, on the same page as monthpickers, which don't show the days.

I've finally found a way to fix all of these problems, even in the original datepickers!

NOTE: You do NOT need to use the following monthpicker scripts to fix the first four problems in your normal jQuery datepickers. Simply use the Datepicker instantiation script further down in this post. Issues 5 and 6 only pertain to different monthpicker solutions I've tried out.

Issues 1-3 and 5 had to do with how the date- and monthpickers are referenced in their internal code, making sure they don't interfere with other date- and monthpickers, as well as some manual updating of the pickers. This you can see in the instantiation-examples below. The fourth problem was fixed by adding some custom code to the datepicker functions (see comments in the examples, especially about onClose).

For the sixth and last problem, pertaining only to use of the monthpickers alongside datepickers, we just need to separate the datepickers and the monthpickers properly.

So, why not get one of the few custom jQuery-UI monthpicker addons out there? The ones I found when I wrote this lacked localization flexibility/ability, some lacked animation support...so, what to do? Roll your "own" from the datepicker-code! This gets you a fully-functioning monthpicker, with all the functionalities of the datepicker, just without the displaying of days.

I have supplied a monthpicker js-script and the accompanying CSS-script, using the method described below, with the jQuery-UI v1.11.1 code. Simply copy these code-snippets to two new files, monthpicker.js and monthpicker.css, respectively, and use the instantiation code-snippets below.

If you want to read about the rather simple process by which I converted the datepicker to a monthpicker, scroll down to the last section. Then you can perhaps repeat the process with a newer version of jQuery-UI.


Now to add the datepickers and monthpickers to the page!

These following javascript code-snippets work with multiple datepickers and/or monthpickers on the page, without the aforementioned problems! Fixed generally by using '$(this).' a lot :)

The first script is for a normal datepicker, and the second one is for the "new" monthpickers.

The out-commented .after, which lets you create some element to clear the input-field, is stolen from Paul Richards' answer.

I'm using the "MM yy" format in my monthpicker, and the 'yy-mm-dd' format in my datepicker, but this is completely compatible with all formats, so you are free to use whichever one you want. Simply change the 'dateFormat' option. The standard options 'showButtonPanel', 'showAnim', and 'yearRange' are of course optional and customizable to your wishes.


Adding a datepicker

Datepicker instantiation. This one goes from 90 years ago and to the present day. It helps you to keep the input-field correct, especially if you set the defaultDate, minDate and maxDate options, but it can handle it if you don't. It will work with any dateFormat you choose.

NOTE: The many "new Date()" calls look ridiculous, but I can't find another way to have a dynamic Date packed into the declaration without doing that for each part, since I (to my knowledge) cannot create a reusable instance in that context. If someone knows of a better way to set an augmented Date in a context like where you set minDate and maxDate, I would appreciate it greatly!

        $('#MyDateTextBox').datepicker({
            dateFormat: 'yy-mm-dd',
            changeMonth: true,
            changeYear: true,
            showButtonPanel: true,
            showMonthAfterYear: true,
            showWeek: true,
            showAnim: "drop",
            constrainInput: true,
        	yearRange: "-90:",
        	minDate: new Date((new Date().getFullYear() - 90), new Date().getMonth(), new Date().getDate()),
        	maxDate: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()),
        	defaultDate: new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()),
        	
            onClose: function (dateText, inst) {
                // When onClose is called after we have clicked a day (and not clicked 'Close' or outside the datepicker), the input-field is automatically
                // updated with a valid date-string. They will always pass, because minDate and maxDate are already enforced by the datepicker UI.
                // This try is to catch and handle the situations, where you open the datepicker, and manually type in an invalid date in the field,
                // and then close the datepicker by clicking outside the datepicker, or click 'Close', in which case no validation takes place.
                try {
                    // If datepicker can parse the date using our formatstring, the instance will automatically parse
                    // and apply it for us (after the onClose is done).
                    // If the input-string is invalid, 'parseDate' will throw an exception, and go to our catch.
                    // If the input-string is EMPTY, then 'parseDate' will NOT throw an exception, but simply return null!
                    var typedDate = $.datepicker.parseDate($(this).datepicker('option', 'dateFormat'), $(this).val());

                    // typedDate will be null if the entered string is empty. Throwing an exception will force the datepicker to
                    // reset to the last set default date.
                    // You may want to just leave the input-field empty, in which case you should replace 'throw "No date selected";' with 'return;'
                    if (typedDate == null)throw "No date selected";

                    // We do a manual check to see if the date is within minDate and maxDate, if they are defined.
                    // If all goes well, the default date is set to the new date, and datepicker will apply the date for us.
                    var minDate = $(this).datepicker("option", "minDate");
                    var maxDate = $(this).datepicker("option", "maxDate");
                    if (minDate !== null && typedDate < minDate) throw "Date is lower than minDate!";
                    if (maxDate !== null && typedDate > maxDate) throw "Date is higher than maxDate!";

                    // We update the default date, because the date seems valid.
                    // We do not need to manually update the input-field, as datepicker has already done this automatically.
                    $(this).datepicker('option', 'defaultDate', typedDate);
                }
                catch (err) {
                    console.log("onClose: " + err);
                    // Standard behavior is that datepicker does nothing to fix the value of the input field, until you choose
                    // a new valid date, by clicking on a day.
                    // Instead, we set the current date, as well as the value of the input-field, to the last selected (and
                    // accepted/validated) date from the datepicker, by getting its default date. This only works, because
                    // we manually change the default date of the datepicker whenever a new date is selected, in both 'beforeShow'
                    // and 'onClose'.
                    var date = $(this).datepicker('option', 'defaultDate');
                    $(this).val($.datepicker.formatDate($(this).datepicker('option', 'dateFormat'), date));
                    $(this).datepicker('setDate', date);
                }
            },

            beforeShow: function (input, inst) {
                // beforeShow is particularly irritating when initializing the input-field with a date-string.
                // The date-string will be parsed, and used to set the currently selected date in the datepicker.
                // BUT, if it is outside the scope of the minDate and maxDate, the text in the input-field is not
                // automatically updated, only the internal selected date, until you choose a new date (or, because
                // of our onClose function, whenever you click close or click outside the datepicker).
                // We want the input-field to always show the date that is currently chosen in our datepicker,
                // so we do some checks to see if it needs updating. This may not catch ALL cases, but these are
                // the primary ones: invalid date-format; date is too early; date is too late.
                try {
                    // If datepicker can parse the date using our formatstring, the instance will automatically parse
                    // and apply it for us (after the onClose is done).
                    // If the input-string is invalid, 'parseDate' will throw an exception, and go to our catch.
                    // If the input-string is EMPTY, then 'parseDate' will NOT throw an exception, but simply return null!
                    var typedDate = $.datepicker.parseDate($(this).datepicker('option', 'dateFormat'), $(this).val());

                    // typedDate will be null if the entered string is empty. Throwing an exception will force the datepicker to
                    // reset to the last set default date.
                    // You may want to just leave the input-field empty, in which case you should replace 'throw "No date selected";' with 'return;'
                    if (typedDate == null)throw "No date selected";

                    // We do a manual check to see if the date is within minDate and maxDate, if they are defined.
                    // If all goes well, the default date is set to the new date, and datepicker will apply the date for us.
                    var minDate = $(this).datepicker("option", "minDate");
                    var maxDate = $(this).datepicker("option", "maxDate");
                    if (minDate !== null && typedDate < minDate) throw "Date is lower than minDate!";
                    if (maxDate !== null && typedDate > maxDate) throw "Date is higher than maxDate!";

                    // We update the input-field, and the default date, because the date seems valid.
                    // We also manually update the input-field, as datepicker does not automatically do this when opened.
                    $(this).val($.datepicker.formatDate($(this).datepicker('option', 'dateFormat'), typedDate));
                    $(this).datepicker('option', 'defaultDate', typedDate);
                }
                catch (err) {
                    // Standard behavior is that datepicker does nothing to fix the value of the input field, until you choose
                    // a new valid date, by clicking on a day.
                    // We want the same behavior when opening the datepicker, so we set the current date, as well as the value
                    // of the input-field, to the last selected (and accepted/validated) date from the datepicker, by getting
                    // its default date. This only works, because we manually change the default date of the datepicker whenever
                    // a new date is selected, in both 'beforeShow' and 'onClose', AND have a default date set in the datepicker options.
                    var date = $(this).datepicker('option', 'defaultDate');
                    $(this).val($.datepicker.formatDate($(this).datepicker('option', 'dateFormat'), date));
                    $(this).datepicker('setDate', date);
                }
            }
        })
    //.after( // this makes a link labeled "clear" appear to the right of the input-field, which clears the text in it
    //    $("<a href='javascript: void(0);'>clear</a>").click(function() {
    //        $(this).prev().val('');
    //    })
    //)
    ;

Adding a monthpicker

Include the monthpicker.js file and the monthpicker.css file in the page you want to use the monthpickers.

Monthpicker instantiation The value retrieved from this monthpicker, is always the FIRST day of the selected month. Starts at the current month, and ranges from 100 years ago and 10 years into the future.

    $('#MyMonthTextBox').monthpicker({
        dateFormat: 'MM yy',
        changeMonth: true,
        changeYear: true,
        showMonthAfterYear: true,
        showAnim: "drop",
        constrainInput: true,
        yearRange: "-100Y:+10Y",
        minDate: new Date(new Date().getFullYear() - 100, new Date().getMonth(), 1),
        maxDate: new Date((new Date().getFullYear() + 10), new Date().getMonth(), 1),
        defaultDate: new Date(new Date().getFullYear(), new Date().getMonth(), 1),
        
        // Monthpicker functions
        onClose: function (dateText, inst) {
            var date = new Date(inst.selectedYear, inst.selectedMonth, 1);
            $(this).monthpicker('option', 'defaultDate', date);
            $(this).monthpicker('setDate', date);
        },

        beforeShow: function (input, inst) {
            if ($(this).monthpicker("getDate") !== null) {
                // Making sure that the date set is the first of the month.
                if($(this).monthpicker("getDate").getDate() !== 1){
                    var date = new Date(inst.selectedYear, inst.selectedMonth, 1);
                    $(this).monthpicker('option', 'defaultDate', date);
                    $(this).monthpicker('setDate', date);
                }
            } else {
                // If the date is null, we reset it to the defaultDate. Make sure that the defaultDate is always set to the first of the month!
                $(this).monthpicker('setDate', $(this).monthpicker('option', 'defaultDate'));
            }
        },
        // Special monthpicker function!
        onChangeMonthYear: function (year, month, inst) {
            $(this).val($.monthpicker.formatDate($(this).monthpicker('option', 'dateFormat'), new Date(year, month - 1, 1)));
        }
    })
    //.after( // this makes a link labeled "clear" appear to the right of the input-field, which clears the text in it
    //    $("<a href='javascript: void(0);'>clear</a>").click(function() {
    //        $(this).prev().val('');
    //    })
    //)
    ;

That's it! That's all you need to make a monthpicker.

I can't seem to make a jsfiddle work with this, but it is working for me in my ASP.NET MVC project. Just do what you normally do to add a datepicker to your page, and incorporate the above scripts, possibly by changing the selector (meaning $("#MyMonthTextBox")) to something that works for you.

I hope this helps someone.

  1. Monthpicker working on the last day of the month. The date you get from this monthpicker will always be the last day of the month.

  2. Two collaborating monthpickers; 'start' is working on the first of the month, and 'end' is working on the last of the month. They are both restricted by each other, so choosing a month on 'end' which is before the selected month on 'start', will change 'start' to be the same month as 'end'. And vice versa. OPTIONAL: When selecting a month on 'start', the 'minDate' on 'end' is set to that month. To remove this feature, comment out one line in onClose (read the comments).

  3. Two collaborating datepickers; They are both restricted by each other, so choosing a date on 'end' which is before the selected date on 'start', will change 'start' to be the same month as 'end'. And vice versa. OPTIONAL: When selecting a date on 'start', the 'minDate' on 'end' is set to that date. To remove this feature, comment out one line in onClose (read the comments).


How I changed the DatePicker into being a MonthPicker

I've taken all the javascript code from jquery-ui-1.11.1.js pertaining to their datepicker, pasted it into a new js-file, and replaced the following strings:

  • "datepicker" ==> "monthpicker"
  • "Datepicker" ==> "Monthpicker"
  • "date picker" ==> "month picker"
  • "Date picker" ==> "Month picker"

Then I removed the part of the for-loop which creates the entire ui-datepicker-calendar div (the div which other solutions hide using CSS). This can be found in the _generateHTML: function (inst).

Find the line that says:

"</div><table class='ui-datepicker-calendar'><thead>" +

Mark everything from after the closing div-tag and down to (and not including) the line where it says:

drawMonth++;

Now it'll be unhappy because we need to close some things. After that closing div-tag from before, add this:

";

The code should now be seamed together nicely. Here's a code-snippet showing what you should've ended up with:

...other code...

calender += "<div class='ui-monthpicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
                (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
                (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
                this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
                    row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
                "</div>";
            drawMonth++;
            if (drawMonth > 11) {
                drawMonth = 0;
                drawYear++;
            }

...other code...

Then I copy/pasted the code from jquery-ui.css pertaining to the datepickers to a new CSS-file, and replaced the following strings:

  • "datepicker" ==> "monthpicker"

Solution 9 - Javascript

Add one more simple solution

 $(function() {
	$('.monthYearPicker').datepicker({
		changeMonth: true,
		changeYear: true,
		showButtonPanel: true,
		dateFormat: 'M yy'
	}).focus(function() {
		var thisCalendar = $(this);
		$('.ui-datepicker-calendar').detach();
		$('.ui-datepicker-close').click(function() {
var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
thisCalendar.datepicker('setDate', new Date(year, month, 1));
		});
	});
});

http://jsfiddle.net/tmnasim/JLydp/
Features:

  • display only month/year
  • Adds the month year value to input box only on clicking of Done button
  • No "reopen" behavior when click "Done"
    ------------------------------------
    another solution that work well for datepicker and monthpicker in the same page:(also avoid the bug of mutiple click on previous button in IE, that may occur if we use focus function)
    JS fiddle link

Solution 10 - Javascript

I needed a Month/Year picker for two fields (From & To) and when one was chosen the Max/Min was set on the other one...a la picking airline ticket dates. I was having issues setting the max and min...the dates of the other field would get erased. Thanks to several of the above posts...I finally figured it out. You have to set options and dates in a very specific order.

See this fiddle for the full solution: Month/Year Picker @ JSFiddle

Code:

var searchMinDate = "-2y";
var searchMaxDate = "-1m";
if ((new Date()).getDate() <= 5) {
    searchMaxDate = "-2m";
}
$("#txtFrom").datepicker({
    dateFormat: "M yy",
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    showAnim: "",
    minDate: searchMinDate,
    maxDate: searchMaxDate,
    showButtonPanel: true,
    beforeShow: function (input, inst) {
        if ((datestr = $("#txtFrom").val()).length > 0) {
            var year = datestr.substring(datestr.length - 4, datestr.length);
            var month = jQuery.inArray(datestr.substring(0, datestr.length - 5), "#txtFrom").datepicker('option', 'monthNamesShort'));
        $("#txtFrom").datepicker('option', 'defaultDate', new Date(year, month, 1));
                $("#txtFrom").datepicker('setDate', new Date(year, month, 1));
            }
        },
        onClose: function (input, inst) {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $("#txtFrom").datepicker('option', 'defaultDate', new Date(year, month, 1));
            $("#txtFrom").datepicker('setDate', new Date(year, month, 1));
            var to = $("#txtTo").val();
            $("#txtTo").datepicker('option', 'minDate', new Date(year, month, 1));
            if (to.length > 0) {
                var toyear = to.substring(to.length - 4, to.length);
                var tomonth = jQuery.inArray(to.substring(0, to.length - 5), $("#txtTo").datepicker('option', 'monthNamesShort'));
                $("#txtTo").datepicker('option', 'defaultDate', new Date(toyear, tomonth, 1));
                $("#txtTo").datepicker('setDate', new Date(toyear, tomonth, 1));
            }
        }
    });
    $("#txtTo").datepicker({
        dateFormat: "M yy",
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        showAnim: "",
        minDate: searchMinDate,
        maxDate: searchMaxDate,
        showButtonPanel: true,
        beforeShow: function (input, inst) {
            if ((datestr = $("#txtTo").val()).length > 0) {
                var year = datestr.substring(datestr.length - 4, datestr.length);
                var month = jQuery.inArray(datestr.substring(0, datestr.length - 5), $("#txtTo").datepicker('option', 'monthNamesShort'));
                $("#txtTo").datepicker('option', 'defaultDate', new Date(year, month, 1));
                $("#txtTo").datepicker('setDate', new Date(year, month, 1));
            }
        },
        onClose: function (input, inst) {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $("#txtTo").datepicker('option', 'defaultDate', new Date(year, month, 1));
            $("#txtTo").datepicker('setDate', new Date(year, month, 1));
            var from = $("#txtFrom").val();
            $("#txtFrom").datepicker('option', 'maxDate', new Date(year, month, 1));
            if (from.length > 0) {
                var fryear = from.substring(from.length - 4, from.length);
                var frmonth = jQuery.inArray(from.substring(0, from.length - 5), $("#txtFrom").datepicker('option', 'monthNamesShort'));
                $("#txtFrom").datepicker('option', 'defaultDate', new Date(fryear, frmonth, 1));
                $("#txtFrom").datepicker('setDate', new Date(fryear, frmonth, 1));
            }
            
        }
    });

Also add this to a style block as mentioned above:

.ui-datepicker-calendar { display: none !important; }

Solution 11 - Javascript

I combined many of above good answers and arrive on this:

    $('#payCardExpireDate').datepicker(
    		{
    			dateFormat: "mm/yy",
    			changeMonth: true,
    	        changeYear: true,
    	        showButtonPanel: true,
    	        onClose: function(dateText, inst) { 
    	            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
    	            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
    	            $(this).datepicker('setDate', new Date(year, month, 1)).trigger('change');
    	        },
                beforeShow : function(input, inst) {
                    if ((datestr = $(this).val()).length > 0) {
                        year = datestr.substring(datestr.length-4, datestr.length);
                        month = datestr.substring(0, 2);
                        $(this).datepicker('option', 'defaultDate', new Date(year, month-1, 1));
                        $(this).datepicker('setDate', new Date(year, month-1, 1));
                    }
                }
    		}).focus(function () {
    	        $(".ui-datepicker-calendar").hide();
    	        $("#ui-datepicker-div").position({
    	            my: "center top",
    	            at: "center bottom",
    	            of: $(this)
    	        });
    	    });

This is proved working but facing many bugs so I was forced to patch in several places of datepicker:

if($.datepicker._get(inst, "dateFormat") === "mm/yy")
{
    $(".ui-datepicker-calendar").hide();
}

patch1: in _showDatepicker : to smooth the hide;

patch2: in _checkOffset: to correct month picker positioning (otherwise when the field is at the bottom of the browser, the offset check is off);

patch3: in onClose of _hideDatepicker: otherwise when closing the date fields will flash for a very short period which is very annoying.

I know the my fix was far from good but for now it's working. Hope it helps.

Solution 12 - Javascript

I had the problem of date picker mixed with month picker. I solved it like that.

	$('.monthpicker').focus(function()
    {
    $(".ui-datepicker-calendar").show();
   	}).datepicker( {
        changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        dateFormat: 'MM/yy',
        create: function (input, inst) { 
            
         },
        onClose: function(dateText, inst) { 
            var month = 1+parseInt($("#ui-datepicker-div .ui-datepicker-month :selected").val());           
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            	
        }
    });

Solution 13 - Javascript

Is it just me or is this not working as it should in IE(8)? The date changes when clicking done, but the datepicker opens up again, until you actually click somewhere in the page to loose focus on the input field...

I'm looking in to solving this.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.js"></script>
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.min.js"></script>
	<link rel="stylesheet" type="text/css" media="screen" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css">
<script type="text/javascript">
$(function() {
    $('.date-picker').datepicker( {
		changeMonth: true,
		changeYear: true,
		showButtonPanel: true,
		dateFormat: 'MM yy',
		onClose: function(dateText, inst) { 
			var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
			var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
			$(this).datepicker('setDate', new Date(year, month, 1));
		}
    });
});
</script>
<style>
.ui-datepicker-calendar {
	display: none;
	}
</style>
</head>
<body>
	<label for="startDate">Date :</label>
	<input name="startDate" id="startDate" class="date-picker" />
</body>
</html>

Solution 14 - Javascript

If you are looking for a month picker try this jquery.mtz.monthpicker

This worked for me well.

options = {
    pattern: 'yyyy-mm', // Default is 'mm/yyyy' and separator char is not mandatory
    selectedYear: 2010,
    startYear: 2008,
    finalYear: 2012,
    monthNames: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
};

$('#custom_widget').monthpicker(options);

Solution 15 - Javascript

I've had certain difficulties with the accepted answer and no other one could be used with a minimum effort as a base. So, I decided to tweak the latest version of the accepted answer until it satisfies at least minimum JS coding/reusability standards.

Here is a way much cleaner solution than the 3rd (latest) edition of the Ben Koehler's accepted answer. Moreover, it will:

  • work not only with the mm/yy format, but with any other including the OP's MM yy.
  • not hide the calendar of other datepickers on the page.
  • not implicitly pollute the global JS object with the datestr, month, year etc variables.

Check it out:

$('.date-picker').datepicker({
    dateFormat: 'MM yy',
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    onClose: function (dateText, inst) {
        var isDonePressed = inst.dpDiv.find('.ui-datepicker-close').hasClass('ui-state-hover');
        if (!isDonePressed)
            return;

        var month = inst.dpDiv.find('.ui-datepicker-month').find(':selected').val(),
            year = inst.dpDiv.find('.ui-datepicker-year').find(':selected').val();

        $(this).datepicker('setDate', new Date(year, month, 1)).change();
        $('.date-picker').focusout();
    },
    beforeShow: function (input, inst) {
        var $this = $(this),
            // For the simplicity we suppose the dateFormat will be always without the day part, so we
            // manually add it since the $.datepicker.parseDate will throw if the date string doesn't contain the day part
            dateFormat = 'd ' + $this.datepicker('option', 'dateFormat'),
            date;

        try {
            date = $.datepicker.parseDate(dateFormat, '1 ' + $this.val());
        } catch (ex) {
            return;
        }

        $this.datepicker('option', 'defaultDate', date);
        $this.datepicker('setDate', date);

        inst.dpDiv.addClass('datepicker-month-year');
    }
});

And everything else you need is the following CSS somewhere around:

.datepicker-month-year .ui-datepicker-calendar {
    display: none;
}

That's it. Hope the above will save some time for further readers.

Solution 16 - Javascript

after digging jQueryUI.com for datepicker, here's my conclusion and answer to your question.

First, I would say no to your question. You can't use jQueryUI datepicker for picking month and year only. It is not supported. It has no callback function for that.

But you can hack it to display only month and and year by using css to hide the days, etc. And I think won't make sense still cause you need the dates to be click in order to pick a date.

I can say you just have to use another datepicker. Like what Roger suggested.

Solution 17 - Javascript

If anyone want that also for multiple calendars its not very hard to add this functionallity to jquery ui. with minified search for:

x+='<div class="ui-datepicker-header ui-widget-header ui-helper-clearfix'+t+'">'+(/all|left/.test(t)&&C==0?c?f:n:"")+(

add this in front of x

var accl = ''; if(this._get(a,"justMonth")) {accl = ' ui-datepicker-just_month';}

search for

<table class="ui-datepicker-calendar

and replace it with

<table class="ui-datepicker-calendar'+accl+'

also search for

this._defaults={

replace it with

this._defaults={justMonth:false,

for css you should use:

.ui-datepicker table.ui-datepicker-just_month{
    display: none;
}

after that all is done just go to your desired datepicker init functions and provide setting var

$('#txt_month_chart_view').datepicker({
    changeMonth: true,
        changeYear: true,
        showButtonPanel: true,
        dateFormat: 'MM yy',
        justMonth: true,
        create: function(input, inst) {
            $(".ui-datepicker table").addClass("badbad");
        },
        onClose: function(dateText, inst) {
            var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
            var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
            $(this).datepicker('setDate', new Date(year, month, 1));
        }
});

justMonth: true is the key here :)

Solution 18 - Javascript

Waht about: http://www.mattkruse.com/javascript/calendarpopup/

Select the month-select example

Solution 19 - Javascript

Made a couple of refinements to BrianS's nearly perfect response above:

  1. I've regexed the value set on show because I think it does actually make it slightly more readable in this case (although note I'm using a slightly different format)

  2. My client wanted no calendar so I've added an on show / hide class addition to do that without affecting any other datepickers. The removal of the class is on a timer to avoid the table flashing back up as the datepicker fades out, which seems to be very noticeable in IE.

EDIT: One problem left to solve with this is that there is no way to empty the datepicker - clear the field and click away and it repopulates with the selected date.

EDIT2: I have not managed to solve this nicely (i.e. without adding a separate Clear button next to the input), so ended up just using this: https://github.com/thebrowser/jquery.ui.monthpicker - if anyone can get the standard UI one to do it that would be amazing.

	$('.typeof__monthpicker').datepicker({
		dateFormat: 'mm/yy',
		showButtonPanel:true,
		beforeShow: 
			function(input, dpicker)
			{							
				if(/^(\d\d)\/(\d\d\d\d)$/.exec($(this).val()))
				{
					var d = new Date(RegExp.$2, parseInt(RegExp.$1, 10) - 1, 1);
					
					$(this).datepicker('option', 'defaultDate', d);
					$(this).datepicker('setDate', d);
				}
					
				$('#ui-datepicker-div').addClass('month_only');
			},
		onClose: 
			function(dt, dpicker)
			{
				setTimeout(function() { $('#ui-datepicker-div').removeClass('month_only') }, 250);
				
				var m = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
				var y = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
				
				$(this).datepicker('setDate', new Date(y, m, 1));
			}
	});

You also need this style rule:

#ui-datepicker-div.month_only .ui-datepicker-calendar {
display:none
}

Solution 20 - Javascript

I liked the @user1857829 answer and his "extend-jquery-like-a-plugin approach". I just made a litte modification so that when you change month or year in any way the picker actually writes the date in the field. I found that I'd like that behaviour after using it a bit.

jQuery.fn.monthYearPicker = function(options) {
  options = $.extend({
    dateFormat: "mm/yy",
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    showAnim: "",
    onChangeMonthYear: writeSelectedDate
  }, options);
  function writeSelectedDate(year, month, inst ){
   var thisFormat = jQuery(this).datepicker("option", "dateFormat");
   var d = jQuery.datepicker.formatDate(thisFormat, new Date(year, month-1, 1));
   inst.input.val(d);
  }
  function hideDaysFromCalendar() {
    var thisCalendar = $(this);
    jQuery('.ui-datepicker-calendar').detach();
    // Also fix the click event on the Done button.
    jQuery('.ui-datepicker-close').unbind("click").click(function() {
      var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
      var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
      thisCalendar.datepicker('setDate', new Date(year, month, 1));
      thisCalendar.datepicker("hide");
    });
  }
  jQuery(this).datepicker(options).focus(hideDaysFromCalendar);
}

Solution 21 - Javascript

Marked answer work!! but Not in my case there's more then one datepicker and only want to implement on particular datepicker

So I use instance of dp and find datepicker Div and add hide class

Here's Code

<style>
    .hide-day-calender .ui-datepicker-calendar{
        display:none;
    }
</style>

<script>
        $('#dpMonthYear').datepicker({ 
            changeMonth: true,
            changeYear: true,
            showButtonPanel: true,
            dateFormat: 'MM yy',
            onClose: function (dateText, inst) { 
                $(this).datepicker('setDate', new Date(inst.selectedYear, inst.selectedMonth, 1));
            },
            beforeShow: function (elem,dp) {
                $(dp.dpDiv).addClass('hide-day-calender'); //here a change
            }
        });
</script>

> Note: You can not target .ui-datepicker-calendar and set css, because it will constantly rendering while selection/changes

Solution 22 - Javascript

I know it's a little late response, but I got the same problem a couple of days before and I have came with a nice & smooth solution. First I found this great date picker here

Then I've just updated the CSS class (jquery.calendarPicker.css) that comes with the example like this:

.calMonth {
  /*border-bottom: 1px dashed #666;
  padding-bottom: 5px;
  margin-bottom: 5px;*/
}

.calDay 
{
	display:none;
}

The plugin fires an event DateChanged when you change anything, so it doesn't matter that you are not clicking on a day (and it fits nice as a year and month picker)

Hope it helps!

Solution 23 - Javascript

I also needed a month picker. I made a simple one with year on header and 3 rows of 4 months below. Check it out: Simple monthyear picker with jQuery.

Solution 24 - Javascript

I tried the various solutions provided here and they worked fine if you simply wanted a couple of drop downs.

The best (in appearance etc) 'picker' (https://github.com/thebrowser/jquery.ui.monthpicker) suggested here is basically a copy of an old version of jquery-ui datepicker with the _generateHTML rewritten. However, I found it no longer plays nicely with current jquery-ui (1.10.2) and had other issues (doesn't close on esc, doesn't close on other widget opening, has hardcoded styles).

Rather than attempt to fix that monthpicker and rather than reattempt the same process with the latest datepicker, I went with hooking into the relevant parts of the existing date picker.

This involves overriding:

  • _generateHTML (to build the month picker markup)
  • parseDate (as it doesn't like it when there's no day component),
  • _selectDay (as datepicker uses .html() to get the day value)

As this question is a bit old and already well answered, here's only the _selectDay override to show how this was done:

jQuery.datepicker._base_parseDate = jQuery.datepicker._base_parseDate || jQuery.datepicker.parseDate;
jQuery.datepicker.parseDate = function (format, value, settings) {
    if (format != "M y") return jQuery.datepicker._hvnbase_parseDate(format, value, settings);
    // "M y" on parse gives error as doesn't have a day value, so 'hack' it by simply adding a day component
    return jQuery.datepicker._hvnbase_parseDate("d " + format, "1 " + value, settings);
};

As stated, this is an old question, but I found it useful so wanted to add feedback with an alterantive solution.

Solution 25 - Javascript

This is how it is done. As on Dec 2021

$('.monthpicker').datepicker({
    autoclose: true,
    showButtonPanel: true,
    viewMode: "months",
    minViewMode: "months",
    format: "M-yyyy"
})

If you want to keep current month selected then add

$('.monthpicker').datepicker({
    autoclose: true,
    showButtonPanel: true,
    viewMode: "months",
    minViewMode: "months",
    format: "M-yyyy"
}).datepicker('setDate', new Date());

Solution 26 - Javascript

For a monthpicker, using jQuery v1.7.2

I have the following javascript which is doing just that

$l("[id$=txtDtPicker]").monthpicker({
    showOn: "both",
    buttonImage: "../../images/Calendar.png",
    buttonImageOnly: true,
    // Default is 'mm/yyyy' and separator char is not mandatory
    pattern: 'yyyymm',
    monthNames: [
        'Jan',
        'Fev',
        'Mar',
        'Abr',
        'Mai',
        'Jun',
        'Jul',
        'Ago',
        'Set',
        'Out',
        'Nov',
        'Dez'
    ]
});

Solution 27 - Javascript

Thanks for Ben Koehler's solution.

However, I had a problem with multiple instances of datepickers, with some of them needed with day selection. Ben Koehler's solution (in edit 3) works, but hides the day selection in all instances. Here's an update that solves this issue :

$('.date-picker').datepicker({
    dateFormat: "mm/yy",
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    onClose: function(dateText, inst) {
        if($('#ui-datepicker-div').html().indexOf('ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all ui-state-hover') > -1) {
            $(this).datepicker(
                'setDate',
                new Date(
                    $("#ui-datepicker-div .ui-datepicker-year :selected").val(),
                    $("#ui-datepicker-div .ui-datepicker-month :selected").val(),
                    1
                )
            ).trigger('change');
            $('.date-picker').focusout();
        }
        $("#ui-datepicker-div").removeClass("month_year_datepicker");
    },
    beforeShow : function(input, inst) {
        if((datestr = $(this).val()).length > 0) {
            year = datestr.substring(datestr.length-4, datestr.length);
            month = datestr.substring(0, 2);
            $(this).datepicker('option', 'defaultDate', new Date(year, month-1, 1));
            $(this).datepicker('setDate', new Date(year, month-1, 1));
            $("#ui-datepicker-div").addClass("month_year_datepicker");
        }
    }
});

Solution 28 - Javascript

I used this code and work perfectly

$(".your_input_class").datepicker({
    dateFormat: 'MM yy',
    changeMonth: true,
    changeYear: true,
    showButtonPanel: true,
    startView: "months", 
    minViewMode: "months"
});

Solution 29 - Javascript

Use onSelect call back and remove the year portion manually and set the text in the field manually

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAanuView Question on Stackoverflow
Solution 1 - JavascriptBen KoehlerView Answer on Stackoverflow
Solution 2 - JavascriptLeniel MaccaferriView Answer on Stackoverflow
Solution 3 - JavascriptBrianSView Answer on Stackoverflow
Solution 4 - Javascriptuser1857829View Answer on Stackoverflow
Solution 5 - JavascriptErik PolderView Answer on Stackoverflow
Solution 6 - JavascriptAnthony ShawView Answer on Stackoverflow
Solution 7 - JavascriptPaul RichardsView Answer on Stackoverflow
Solution 8 - JavascriptUltroman the TacomanView Answer on Stackoverflow
Solution 9 - JavascriptChinh PhanView Answer on Stackoverflow
Solution 10 - JavascriptAmy StruckView Answer on Stackoverflow
Solution 11 - JavascriptrexwolfView Answer on Stackoverflow
Solution 12 - JavascriptPYTView Answer on Stackoverflow
Solution 13 - JavascriptTom Van SchoorView Answer on Stackoverflow
Solution 14 - Javascriptuser2630080View Answer on Stackoverflow
Solution 15 - JavascriptAlexander AbakumovView Answer on Stackoverflow
Solution 16 - JavascriptReigelView Answer on Stackoverflow
Solution 17 - JavascriptprdaturView Answer on Stackoverflow
Solution 18 - JavascriptRogerView Answer on Stackoverflow
Solution 19 - JavascriptWhelkaholismView Answer on Stackoverflow
Solution 20 - JavascriptstravanatoView Answer on Stackoverflow
Solution 21 - JavascriptRavi MakwanaView Answer on Stackoverflow
Solution 22 - JavascriptpjnovasView Answer on Stackoverflow
Solution 23 - JavascriptTiago CoelhoView Answer on Stackoverflow
Solution 24 - Javascriptfreedomn-mView Answer on Stackoverflow
Solution 25 - JavascriptJay MomayaView Answer on Stackoverflow
Solution 26 - JavascriptRicardo AppletonView Answer on Stackoverflow
Solution 27 - Javascriptdj3c1tView Answer on Stackoverflow
Solution 28 - JavascriptImron RosadiView Answer on Stackoverflow
Solution 29 - JavascriptTeja KantamneniView Answer on Stackoverflow