別のサイトで下のような選択フォームを作りました
1月、3月、5月、7月、8月、10月、12月は日付を31日まで選択できますが、
4月、6月、9月、11月は30日まで、2月は年によって28日か29日になります。
(西暦は大正元年にあたる1912年まで対応)
誤入力を防止するため、存在しない日付は表示しません。
たとえば、今年、今月を選択すれば、1日から今日の日付までしか選べません。
昭和64年は1月7日までなので、昭和64年1月を選べば7日まで、平成元年1月を選べば
8日からの表示となります。
元号年から西暦への変換も出来ます。
たとえば平成1年を選択した後に、西暦を押すと1989年と表示されます。
これを実現するのに以下のソースを書いてFirefoxで試したらうまくいきました。
ところが、IE(インターネット エクスプローラー)ではset_select関数が動きません。
Internet ExplorerではselectタグのinnerHTMLへの挿入はサポートしていないそうです。
フォーム
<!-- 起動するまでdisplay:noneで非表示にして、誤作動防止 --> <form id="age_form" style="display:none;text-align:center"> <p style="color:#00f;font-weight:bold">年齢計算フォーム</p> <p> <input type="radio" name="gengou" onclick="gengou_changed(this)" checked="checked" /> 西暦 <input type="radio" name="gengou" onclick="gengou_changed(this)" /> 平成 <input type="radio" name="gengou" onclick="gengou_changed(this)" /> 昭和 <input type="radio" name="gengou" onclick="gengou_changed(this)" /> 大正 </p> <select onchange="year_changed(this)"> <option value="0">---</option> </select> 年 <select onchange="month_changed(this)"> <option value="0">---</option> </select> 月 <select onchange="day_changed(this)"> <option value="0">---</option> </select> 日 <span></span> </form>
スクリプト
var today=new Date(); var taisyou_gannen=1912; //これだとIEでは動きません var set_select=function(select,min,max,diff){ var option=select.getElementsByTagName('option'); var selected=parseInt(option[select.selectedIndex].value,10); select.innerHTML='<option value="0">---</option>'; if(!min&&!max){ return; } for(;min<=max;min++){ var num=min+diff; var attr=num==selected?' selected="selected" ':''; select.innerHTML+= '<option value="'+num+'"'+attr+'>'+min+'</option>'; } } var is_urudoshi=function(year){ //閏年ならtrue if(year%4){ return false; } if(year%100){ return true; } if(year%400){ return false; } return true; } var day_changed=function(elem){ var select=elem.parentNode.getElementsByTagName('select'); var span=elem.parentNode.getElementsByTagName('span'); if(select.length!=3||span.length!=1){return;} var option=select[2].getElementsByTagName('option'); var day=parseInt(option[select[2].selectedIndex].value,10); if(!day){ span[0].innerHTML=''; return; } option=select[1].getElementsByTagName('option'); var month=parseInt(option[select[1].selectedIndex].value,10); option=select[0].getElementsByTagName('option'); var year=parseInt(option[select[0].selectedIndex].value,10); //現在の年齢を算出 var today_num=(today.getFullYear()*10000) +((today.getMonth()+1)*100)+today.getDate(); var age=Math.floor((today_num- ((year*10000)+(month*100)+day))/10000); span[0].innerHTML='現在の年齢:'+age+'歳'; } var month_changed=function(elem){ var input=elem.parentNode.getElementsByTagName('input'); var select=elem.parentNode.getElementsByTagName('select'); if(input.length!=4||select.length!=3){return;} var option=select[1].getElementsByTagName('option'); var month=parseInt(option[select[1].selectedIndex].value,10); option=select[0].getElementsByTagName('option'); var year=parseInt(option[select[0].selectedIndex].value,10); //誤作動防止のため最大範囲(1〜31)で初期化 set_select(select[2],1,31,0); if(!month){ //月が「---」なら日も「---」 set_select(select[2],0,0,0); }else if(year==1989&&month==1&&input[1].checked){ //平成元年は1月8日から set_select(select[2],8,31,0); }else if(year==1989&&month==1&&input[2].checked){ //昭和64年は1月7日まで set_select(select[2],1,7,0); }else if(year==1926&&month==12&&input[2].checked){ //昭和元年は12月25日から set_select(select[2],25,31,0); }else if(year==1926&&month==12&&input[3].checked){ //大正15年は12月25日まで //大正最後の日と昭和最初の日は同じ set_select(select[2],1,25,0); }else if(year==1912&&month==7&&input[3].checked){ //大正元年は7月30日から set_select(select[2],30,31,0); }else if(year==today.getFullYear()&&month==today.getMonth()+1){ //今年の今月なら今日まで表示 set_select(select[2],1,today.getDate(),0); }else if(month==2){ if(is_urudoshi(year)){ //閏年の2月は29日まで set_select(select[2],1,29,0); }else{ //それ以外の2月は28日まで set_select(select[2],1,28,0); } }else if(month==4||month==6||month==9||month==11){ //4、6、9、11月は30日まで set_select(select[2],1,30,0); } day_changed(elem); } var year_changed=function(elem){ var input=elem.parentNode.getElementsByTagName('input'); var select=elem.parentNode.getElementsByTagName('select'); if(input.length!=4||select.length!=3){return;} var option=select[0].getElementsByTagName('option'); var year=parseInt(option[select[0].selectedIndex].value,10); //誤作動防止のため最大範囲(1〜12)で初期化 set_select(select[1],1,12,0); if(!year){ //年が「---」なら月も「---」 set_select(select[1],0,0,0); }else if(year==today.getFullYear()){ //今年なら今月まで表示 set_select(select[1],1,today.getMonth()+1,0); }else if(input[2].checked){ if(year==1989){ //昭和64年は1月まで(よって平成元年も1月から) set_select(select[1],1,1,0); }else if(year==1926){ //昭和元年は12月から set_select(select[1],12,12,0); } }else if(input[3].checked&&year==1912){ //大正元年は7月から //大正のそれ以外の年はすべて1〜12月まである set_select(select[1],7,12,0); } month_changed(elem); } var gengou_changed=function(elem){ var input=elem.parentNode.getElementsByTagName('input'); var select= elem.parentNode.parentNode.getElementsByTagName('select'); if(input.length!=4||select.length!=3){return;} for(var i=0;i<input.length;i++){ if(input[i].checked){ //誤作動防止のため最大範囲で初期化 set_select(select[0], taisyou_gannen,today.getFullYear(),0); if(i==1){ //平成元年から今年まで set_select(select[0], 1,today.getFullYear()-1988,1988); }else if(i==2){ //昭和元年から64年まで set_select(select[0],1,64,1925); }else if(i==3){ //大正元年から15年まで set_select(select[0],1,15,1911); } break; } } year_changed(select[0]); } var load_event=function(){ var elem=document.getElementById('age_form'); if(!elem){return;} var select=elem.getElementsByTagName('select'); if(select.length!=3){return;} set_select(select[0],taisyou_gannen,today.getFullYear(),0); elem.style.display='block'; //フォームを表示 } // 詳細は別記事「addEventListenerとattachEvent」を見てください if(window.addEventListener){ window.addEventListener('load', load_event, false); }else if(window.attachEvent){ window.attachEvent('onload', load_event); }
IEに対応させるためにDOMを使って、set_select関数のソースを書き直したらうまく動きました。
var set_select=function(select,min,max,diff){ var option=select.getElementsByTagName('option'); var cnt=parseInt(option[option.length-1].value,10)-diff; //maxまでなければ追加 while(max>cnt){ cnt++; var elem=document.createElement('option'); elem.setAttribute('value',cnt+diff); //optionへのinnerHTMLは書き込み可能 elem.innerHTML=cnt; select.appendChild(elem); } //max以上あったら削除 while(max<cnt){ select.removeChild(option[option.length-1]); cnt--; } cnt=option.length==1?0:parseInt(option[1].value,10)-diff; //min以下があったら削除 while(min>cnt){ select.removeChild(option[1]); cnt++; } //minまでなければ追加 while(min<cnt){ cnt--; var elem=document.createElement('option'); elem.setAttribute('value',cnt+diff); //optionへのinnerHTMLは書き込み可能 elem.innerHTML=cnt; select.insertBefore(elem, select.getElementsByTagName('option')[1]); } option=select.getElementsByTagName('option'); for(var i=1;i<option.length;i++){ //optionへのinnerHTMLは書き込み可能 option[i].innerHTML=min++; } }