I have recently been drinking the jQuery kool aid. One of my favorite plugins for it is the excellent Datepicker plugin, which I am using whenever I want to display a nice calendar to users.
Last week I needed it to work on a single selectbox that listed available dates but couldn't find any documentation for it. There are some examples of a datepicker for multiple selectboxes (day/month/year), but not when you only have a single one. So here is my attempt at it.
I am using the jQuery UI 1.5 beta release, so your milage may vary since the API has changed quite a bit lately.
The Markup
The example I am working with has the following structure:
<select id="date"> <option>Select date</option> <option value="2008-05-01">May 1, 2008</option> <option value="2008-05-03">May 3, 2008</option> <option value="2008-05-05">May 5, 2008</option> <option value="2008-05-25">May 25, 2008</option> </select>
Datepicker primarily works with input elements so you will need to add a hidden element for it. This is kind of essential anyways if you want to have separated display format for the dates because datepicker supports only one format for each instance.
I prefer to have the value as an ISO date string and then use more user friendly format that is visible so I tend to do this anywhere the UI is important. The extra element is as simple as:
<input id="datepicker" type="hidden"/>
DatePicker, Setting the Scene
We need to tell the datepicker which dates are available from the selectbox. For performance reasons, I have created a map of available dates, which the datepicker references to determine if a date is available or not.
$(document).ready(function() {
var dates = {};
$('#date option').slice(1).each(function() {
var date = $(this).val();
var year = date.substring(0, 4);
var month = date.substring(5, 7) - 1;
var day = date.substring(8, 10);
dates[new Date(year, month, day)] = true;
});
// ...
The datepicker can now be instantiated on the hidden element and made available through its button feature:
$('#datepicker').datepicker({
dateFormat: 'yy-mm-dd',
buttonImage: 'calendar.png',
buttonImageOnly: true,
showOn: 'button',
// ...
Restricting DatePicker to dates in the datepicker
I already created a map of available dates, we now need to connect that data to the datepicker. This is trivial with the beforeShowDay datepicker configuration option. We simply reference the dates map to determine if the date should be allowed or not.
beforeShowDay: function(date) {
return [dates[date], ''];
},
Synching the two Elements on a Change
The selectbox needs to be updated immediately when a date is selected using the datepicker. It is not as important to update the datepicker value as we are only using that for display. This means that we can get away with only updating it when we need to display it.
Both cases can be solved using options in the datepicker object, we update the selecbox with onSelect and the datepicker with beforeShow. Since I am using the ISO format on both sides, it is simply a matter of synching the values.
onSelect: function(date) {
$('#date').val(date);
},
beforeShow: function() {
$(this).val($('#date').val());
return {};
}
Demo
The Complete Script
$(document).ready(function() {
var dates = {};
$('#date option').slice(1).each(function() {
var date = $(this).val();
var year = date.substring(0, 4);
var month = date.substring(5, 7) - 1;
var day = date.substring(8, 10);
dates[new Date(year, month, day)] = true;
});
$('#datepicker').datepicker({
dateFormat: 'yy-mm-dd',
buttonImage: 'calendar.png',
buttonImageOnly: true,
showOn: 'button',
onSelect: function(date) {
$('#date').val(date);
},
beforeShowDay: function(date) {
return [dates[date], ''];
},
beforeShow: function() {
$(this).val($('#date').val());
return {};
}
});
});
8 comments:
Nice and thorough tutorial. Great use of datepicker.
Thanks, useful technique.
Can I suggest an improvement: that you set the datepicker's minDate and maxDate according to the min/max range defined by the date values in your selectbox. This way the user won't have to hunt around as much in datepicker to find valid dates to select from.
@bokkeman nice suggestion.
This would be easy to add by parsing $('#date option:last').val() for maxDate and do the same for minDate using the second element.
please tell me how do you set select boxes month and year in the datepicker ?
ppp0: I am not sure what you mean. In my example I have only one select box with the entire date value. I set it from the datepicker with onSelect option:
onSelect: function(date) {
$('#date').val(date);
}
This means: set the value of #date to the date of the datepicker. If you have multiple selecte boxes, then you need to split the date up and set each select box value. Something like:
onSelect: function(date) {
$('#year').val(date.substring(0, 4));
$('#month').val(date.substring(5, 7) - 1);
}
You would then need select boxes with these identifiers and populated with possible values.
Excellence!
Hi. Your blog appeared in the activity reports at cachefile.net so it was necessary for me to send along a notice:
Cachefile.net is going offline due to a lack of support. The shutdown date will be March 15, 2009.
Users are strongly advised to try Google AJAX Libraries at http://code.google.com/apis/ajaxlibs/ which implements an API as well as a common repository for some of the popular script libraries.
http://marcgrabanski.com/article/jquery-ui-datepicker-themes
hi please tell how to to get the datefield from the above demo
Post a Comment