Date Selection
Correct Days in Month Dropdown List
One way of having your visitors enter a date into a form so as to try to reduce the chances of their entering an invalid date or a date in a format different from what you expect is to have them select the date using three dropdown lists, one each for the day, month, and year. You can specify all of the months easily enough. You can also include just those years which are in what you consider to be a valid range (or substitute a text input field for them to enter the year if the range is too big). That still leaves a problem with the day field since not all months contain the same number of days. There is nothing to prevent someone entering the 31st April or 30th February.
Most people are used to entering the day before the month and year and so if we put the fields in the more usual order we would have to limit the months that they can select if they enter a day that doesn't exist in all months. In the case of their entering the 29th February we would have to limit the years that they select to those which are leap years. Doing this would be very messy and complicated. Collecting the month before the day as people in a couple of countries do wouldn't solve the problem either since we'd still have an issue with 29th February.
A much simpler solution since we are supplying all the dropdown lists anyway is to put them in the order year, month, day so as to collect the year and month first. This will allow us to update the content of the day dropdown list so as to only include the number of days in the selected month.
Here's a working example which provides the opportunity for your visitor to select the year, month, and day where provided that they actually do select the year and month first (and have JavaScript enabled) the list of days will only include those that actually exist in the selected month.
Note that we will still need to validate all the fields afterwards to cater for where JavaScript is not available, where they didn't make a selection from all three fields, or where they selected the day first and then selected a month that doesn't have that many days but this will reduce the chances of people entering an incorrect value into the day field in te first place as those with JavaScript enabled who fill out all the fields in order will be unable to select a day that doesn't exist.
So the first thing you need to get this to work is to make sure that each of the three fields in your date selection has an appropriate id. They should have them anyway in order for the associated labels to work correctly but if you don't have them for that reason you'll still need to add them for the JavaScript to work (we'll leave the names alone for whatever server side processing you are going to pass the date to). Here's my daye selection code slightly abbreviated showing the ids we'll need to reference in the JavaScript.
<legend>Date Selection</legend>
<label for="year">Year: </label>
<select name="year" id="year" size="1">
<option value=" " selected="selected"> </option>
<option value="2000">2000</option>
<option value="2001">2001</option>
<option value="2002">2002</option>
</select>
<label for="month">Month: </label>
<select name="month" id="month" size="1">
<option value=" " selected="selected"> </option>
<option value="1">January</option>
<option value="2">February</option>
...
<option value="12">December</option>
</select>
<label for="day">Day: </label>
<select name="day" id="day" size="1">
<option value=" " selected="selected"> </option>
<option value="1">1</option>
<option value="2">2</option>
...
<option value="29">29</option>
<option value="30">30</option>
<option value="31">31</option>
</select>
</fieldset>
Now all we need is some JavaScript attached to the bottom of the page that will check for when the year and month fields have changed and when they both have been given values will (provided the day hasn't already been given a value) update the days drop down to only include the appropriate number of days.
var dd = new Date(year, month, 0);
return dd.getDate();}
function setDayDrop(dyear, dmonth, dday) {
var year = dyear.options[dyear.selectedIndex].value;
var month = dmonth.options[dmonth.selectedIndex].value;
var day = dday.options[dday.selectedIndex].value;
if (day == ' ') {
var days = (year == ' ' || month == ' ')
? 31 : daysInMonth(month,year);
dday.options.length = 0;
dday.options[dday.options.length] = new Option(' ',' ');
for (var i = 1; i <= days; i++)
dday.options[dday.options.length] = new Option(i,i);}}
function setDay() {
var year = document.getElementById('year');
var month = document.getElementById('month');
var day = document.getElementById('day');
setDayDrop(year,month,day);}
document.getElementById('year').onchange = setDay;
document.getElementById('month').onchange = setDay;
Of course if you want to have more than one such set of date drop downs in the page you'll need to duplicate the JavaScript below the blank line in the above code and substitute the alternate id and function names for the ones shown in bold in the additional copy of the code.
