Change jQueryUI datepicker to monthpicker [duplicate] - javascript
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?
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
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:
#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>
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();
<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
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
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('');
})
);
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:
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.
The datepicker wouldn't "remember" the date when opened again.
The code for juggling the dates used substringing so it wasn't compatible with all formats.
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.
The monthpicker only changed the input-field on closing it, rather than whenever the values were changed.
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.
Links to pastebins for some extra date- and monthpicker setups:
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.
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).
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"
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
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; }
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.
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.
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>
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();
}
});
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);
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.
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 :)
Waht about:
http://www.mattkruse.com/javascript/calendarpopup/
Select the month-select example
Made a couple of refinements to BrianS's nearly perfect response above:
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)
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
}
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);
}
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
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!
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.
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.
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");
}
}
});
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'
]
});
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());
I used this code and work perfectly
$(".your_input_class").datepicker({
dateFormat: 'MM yy',
changeMonth: true,
changeYear: true,
showButtonPanel: true,
startView: "months",
minViewMode: "months"
});
Use onSelect call back and remove the year portion manually and set the text in the field manually
Related
SetDate on jquery Datepicker onClose does not change value
i have a table and each row has a datepicker. Datepickers are only selecting months and on close i set the first day of the month except if this day is before the minDate so i want to set minDate there. SetDate function does not work. My log gives me that properDate is set correctly but when i pass it in the setDate the result does not change and somehow it is stack to first Day of the month. What am i missing? function initDatepickerSchedule(){ $(".datepickerSchedule").each(function(){ $(this).datepicker({ showOn: "both", changeMonth: true, changeYear: true, dateFormat: "yy-mm-dd", minDate: scheduleTaskMinDate(), maxDate: scheduleTaskMaxDate($(this).closest("tr").find(".ScheduledTaskQtyInput").val(),$(this).closest("tr").find(".ScheduledTaskCompletedQtyInput").val()), showButtonPanel: true, onClose: function(dateText, inst) { function isDonePressed(){ return $('#ui-datepicker-div').html().indexOf('ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all ui-state-hover') > -1; } if (isDonePressed()){ var month = $("#ui-datepicker-div .ui-datepicker-month :selected").val(); var year = $("#ui-datepicker-div .ui-datepicker-year :selected").val(); var properDate=new Date(year, month, 1); var minDate=$(this).datepicker("option","minDate"); console.log(properDate);// 2019-12-1 console.log(minDate);//2019-12-2 console.log(properDate<minDate);// true if(properDate<minDate){ properDate=minDate; } console.log("before set"); console.log(properDate===minDate);//true console.log(properDate);//2019-12-2 $(this).datepicker("setDate",properDate); console.log($(this).datepicker("getDate"));//2019-12-1 var coNo=$(this).closest("tr").find(".changeOrderNoInput").val(); $(this).closest("tr").find(".ScheduledTaskVersion").val(studyTaskScheduleVersion($(this).datepicker("getDate"),coNo)); $("#SubmitScheduleDistButton").prop('disabled', true).prop('title',"Validate without Errors to Unlock"); } } }).focus(function(){ $(".ui-datepicker-calendar").hide(); $(this).attr("autocomplete","off"); }); }); }
It seems that max Date was really relevant. In this specific case i should have a date inside the same month for the maxDate, but for some reason (i do not remember and checked possible influence in other parts of the program but i can not find any problem)i was returning the first date of the month. So this was not shown on the datepicker case calendar was hidden so i could not know. And this is way it was overriding the set function cause of the maxDate.
jQuery datepicker not showing binded date
This is my jquery datepicker $(".monthPickerStart").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('d M,yy', new Date(year, month, 1))); } }); $(".monthPickerStart").focus(function () $(".ui-datepicker-calendar").hide(); $("#ui-datepicker-div").position({ my: "center top", at: "center bottom", of: $(this) }); }); aspx page code <asp:TextBox ID="txt" class="monthPickerStart" Text='<%# Eval(Date", "{0:MMM/dd/yyyy}") %>' runat="server"></asp:TextBox> Problem: If their is already a date in this text box and when I try to open datepicker, then it opens the current date, rather than opening the date which is present inside that textbox. for example date inside textbox = 5/13/2019, then when i try to open datepicker then it opens current date instead of 5/13/2019
According to this http://api.jqueryui.com/datepicker/#utility-formatDate you have to set the date format properly Since you are using dateFormat: 'MM yy' to initialize the Datepicker, The Input field text value should contain the default value as May 2019 All the date formats supported are mentioned in the link above
Date picker using jquery for dob year validation
I am using date picker from Jquery. Where currently I facing one problem By default the calendar will show till 2100 years but if the user select any feature date or current date the system should not accept. The system should accept the date minimum 10 year previous from todays date. I am bit confused how to do I tried with min year & max year but If i gave year range as 1900 to 2015 calendar was showing till 2015 sep only but i want to show till 2100 Here is the jsbin Link Guys kindly help me Here is the Jquery code $("#txt_dob").datepicker({ dateFormat: "mm-dd-yy", changeMonth: true, changeYear: true, //showButtonPanel: true, yearRange: '-115:+10', beforeShow: function () { setTimeout(function (){ $('.ui-datepicker').css('z-index', 99999999999999); }, 0); }, }).on('change', function() { if($('#txt_dob').valid()){ $('#txt_dob').removeClass('errRed'); } // triggers the validation test on change }); Thanks in advance
My solution would be to create a Date object: var date = new Date(); // current date Then substract 10 years: date.setFullYear(date.getFullYear() - 10) Then affect this date to be the maximum date of your date picker $("#txt_dob").datepicker({ dateFormat: "mm-dd-yy", maxDate: date, changeMonth: true, changeYear: true });
Use the maxDate property of the date picker as follows: maxDate: '-10Y'
Trying to validate jQuery UI Datepicker
I am trying to check if a date is older than today's date & show an error if true. What is currently happening is if the month is less than today's month, the error is showing even if the year is set to 2014 or beyond. For example today is 4/18/2013 which doesn't have an error, but 4/17/2014 & 3/17/2014 get errors but 5/17/2013 does not. It seems the year is being ignored during the check. Hope that made a little sense... $("#expDate").datepicker({ changeMonth: true, changeYear: true, minDate: 0, onClose: function(selectedDate) { var currDate = $.datepicker.formatDate('mm/dd/yy', new Date()); if (selectedDate < currDate) { $("#warning").append("The number has expired"); } else { $("#warning").html(""); } } });
You can do it directly with maxDate option $("#datepicker").datepicker({ maxDate: new Date() });
jQuery UI DatePicker to show month year only
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?
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
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:
#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>
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();
<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
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
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(''); }) );
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: 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. The datepicker wouldn't "remember" the date when opened again. The code for juggling the dates used substringing so it wasn't compatible with all formats. 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. The monthpicker only changed the input-field on closing it, rather than whenever the values were changed. 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. Links to pastebins for some extra date- and monthpicker setups: 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. 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). 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"
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
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; }
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.
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.
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>
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(); } });
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);
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.
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 :)
Waht about: http://www.mattkruse.com/javascript/calendarpopup/ Select the month-select example
Made a couple of refinements to BrianS's nearly perfect response above: 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) 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 }
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); }
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
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!
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.
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.
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"); } } });
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' ] });
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());
I used this code and work perfectly $(".your_input_class").datepicker({ dateFormat: 'MM yy', changeMonth: true, changeYear: true, showButtonPanel: true, startView: "months", minViewMode: "months" });
Use onSelect call back and remove the year portion manually and set the text in the field manually