以下の条件を満たす入力フォームの作成例です。
もっとスマートなやり方があるかもしれません。。。
- 和暦に対応する
- DatePickerではなくセレクトボックス形式で
- 不正な日付の入力は極力させないよう元号、年、月、日のセレクトボックスを連動させる
完成イメージ
サンプル
1. HTML
HTMLでは<select>タグのみ定義し、<option>タグはJavaScriptで設定します。
レイアウトにはBootstrapのグリッドシステムを使っています。
wareki_sample.html
<div class="container">
<div class="form-group">
<div class="row">
<div class="col-sm-3">
<div>
<select class="form-control" name="date_of_birth_era" id="date_of_birth_era">
</select>
</div>
</div>
<div class="col-sm-3">
<div class="input-group">
<select class="form-control" name="date_of_birth_year" id="date_of_birth_year">
</select>
<span class="input-group-addon">年</span>
</div>
</div>
<div class="col-sm-3">
<div class="input-group">
<select class="form-control" name="date_of_birth_month" id="date_of_birth_month">
</select>
<span class="input-group-addon">月</span>
</div>
</div>
<div class="col-sm-3">
<div class="input-group">
<select id="date_of_birth_day" name="date_of_birth_day" class="form-control" >
</select>
<span class="input-group-addon">日</span>
</div>
</div>
</div>
</div>
</div>
2. JavaScript - 元号のセレクトボックスに<option>を追加する
サーバーサイドのJavaプログラムでフォームへの入力値を受け取ることを想定し、valueにはJavaの和暦クラスで
ERAが返す定数(0~4)を設定しています。
wareki.js
function setEraOption() {
var era = $("#date_of_birth_era");
era.append($('<option>').html('---').val(0));
era.append($('<option>').html('明治').val(1));
era.append($('<option>').html('大正').val(2));
era.append($('<option>').html('昭和').val(3));
era.append($('<option>').html('平成').val(4));
}
3. JavaScript - 年のセレクトボックスに<option>を追加する
元号のvalueに対応した年数をセットします。
平成については現在日付を基準にして最大値を割り出しています。
wareki.js
function setYearOption() {
var year = $("#date_of_birth_year");
var selectEra = $("#date_of_birth_era").val();
year.children().remove();
var maxYear = 0;
switch (selectEra) {
case "1": maxYear = 45; break;
case "2": maxYear = 15; break;
case "3": maxYear = 64; break;
case "4": maxYear = new Date().getFullYear()-1988; break;
default: maxYear = 0; break;
}
year.append($('<option>').html('---').val(0));
for (var i = 1; i <= maxYear; i++) {
year.append($('<option>').html(i).val(i));
}
}
4. JavaScript - 月のセレクトボックスに<option>を追加する
wareki.js
function setMonthOption() {
var month = $("#date_of_birth_month");
month.append($('<option>').html('---').val(0));
for (i = 1; i <= 12; i++) {
month.append($('<option>').html(i).val(i));
}
}
5. JavaScript - 日のセレクトボックスに<option>を追加する
2月の日数は年によって異なるため、年&月に対応した日数の<option>を追加しています。
wareki.js
function setDayOption() {
var day = $("#date_of_birth_day");
var selectYear = $("#date_of_birth_year").val();
var selectMonth = $("#date_of_birth_month").val();
var selectDay = day.val();
//閏年に対応するため和暦から西暦に変換
var seirekiYear = warekiToSeireki($("#date_of_birth_era").val(), selectYear);
var dateobj = new Date(seirekiYear, selectMonth, 0);
day.children().remove();
$("#date_of_birth_day").append($('<option>').html('---').val(0));
for (var i = 1; i <= dateobj.getDate(); i++) {
day.append($('<option>').html(i).val(i));
}
6. JavaScript - 和暦から西暦に変換する
wareki.js
function warekiToSeireki(era, year) {
if (era == 1) {
return parseInt(year) + 1867;
} else if(era == 2) {
return parseInt(year) + 1911;
} else if(era == 3) {
return parseInt(year) + 1925;
} else if(era == 4) {
return parseInt(year) + 1988;
}
}
7. JavaScript - 他のセレクトボックスに連動して日のセレクトボックスの<option>を調整する
年や月のセレクトボックスを変更した際に不整合とならないよう、日のセレクトボックスの<option>を再設定する
wareki.js
function changeDayOption() {
var day = $("#date_of_birth_day");
var selectDay = day.val();
setDayOption();
//日が選択済みの場合、再度選択状態にする
(selectDay == null) ? day.val(day.val()[0]) : day.val(selectDay);
}
8. JavaScript - イベントに応じて上記の関数を呼び出す
wareki.js
// DOM要素の構築完了時にセレクトボックスを初期化する
$(function() {
$(document).ready(
function() {
setEraOption();
setYearOption();
setMonthOption();
setDayOption();
});
});
// 元号を変更したら年のセレクトボックスの<option>をセットする
$(function() {
$("#date_of_birth_era").on("change", function() {
setYearOption();
});
});
// 年を変更し、月が選択済みかつ2の場合、日のセレクトボックスの<option>を調整する(閏年対応)
$(function() {
$("#date_of_birth_year").on("change", function() {
if ($("#date_of_birth_month").val() == 2) {
changeDayOption();
}
});
});
// 月を変更したら日のセレクトボックスの<option>を調整する
$(function() {
$("#date_of_birth_month").on("change", function() {
changeDayOption();
});
});