無効な日付を絶対選択させない
selectタグで日付を選択するフォームをよく見かけるが本来存在しない日付が選択できてしまうことが多い。
例えば2月は28日か29日が最後だが30日や31日が選択できたり、4, 6, 9, 11月は30日までしかないが31日が選択できてしまうなどだ。
選択された月の日にちのみを入れる
JavaScriptを使用すれば選択された月の日にちのみを入れることができる。例えば1月なら31日まで、9月なら30日までといった具合だ。
やり方は簡単でまず下記の記述で選択された月の最後の日にちを取得することができる。もちろん2月のうるう年にも対応している。
var d = new Date(d, m, 0); d.getDate(); // // sample1 // var d = new Date(2015, 2, 0); // d.getDate(); => 28 // // sample2 // var d = new Date(2016, 2, 0); // d.getDate(); => 29
最後の日にちを取得したら日数分のoptionタグを生成して日にちのselectタグに挿入する。
関数を作成しておいて年と月のselectタグのonchangeイベントで両方が選択されているときに実行すると良い。
<select name=year" onchange="dateCheck('year', 'month', 'day')"> <option value="">--年</option> <option value="2015">2015年</option> <option value="2016">2016年</option> </select> <select name="month" onchange="dateCheck('year', 'month', 'day')"> <option value="">--月</option> <option value="1">1月</option> <!-- 省略 --> <option value="12">12月</option> </select> <select name="day"> <option value="">--日</option> <option value="1">1日</option> <!-- 省略 --> <option value="31">31日</option> </select>
function dateCheck(year, month, day) { var y = Number(document.getElementsByName(year)[0].value); var m = Number(document.getElementsByName(month)[0].value); var day = document.getElementsByName(day)[0]; var d = Number(day.value); if (y && m) { var ds = new Date(y, m, 0); var dsn = Number(ds.getDate()); var html = '<option value="">--日</option>'; for(var i = 1; i <= dsn; i++) { if (i === d) { html += '<option value="' + i + '" selected>' + i + '日</option>'; } else { html += '<option value="' + i + '">' + i + '日</option>'; } } day.innerHTML = html; } }
選択した日にちをd変数に格納しoptionタグ生成時にselected属性が付くようにすれば年と月を切り替えても日にちは保持される。
逆に例えば10月31日を選択されているときはd変数に31が格納されるが、月を9月にすると31日が存在しないため、生成されるoptionタグにselectedが付かず9月--日となり31日がリセットされるため間違った日にちが入ることがない。
実際の日付フォームの動作は下記のリンクをご参照ください。
JavaScriptでフォームで無効な日付を絶対選択させないサンプル