メニューからの選択に応じてメニューとテキスト入力欄を切り替えるスクリプトです。
これに依り、状況に依りフォームの形を変えると言った複雑なフォームを実現する事が可能です。
何度も書いておりますが、JAVAスクリプトは必須の技術ではないため、閲覧者の中には使えないように設定している者もいます。
このスクリプトの場合、非対応環境へはかなりの工夫が必要になるでしょう。
以下のフォームは、利用する列車を入力すると言うものです。
スクリプトを実行できる環境なら(ネットスケープは6.0以降、オペラは7.0以降)、列車の系統をラジオボタンで撰べるようになっております。
選択すると、それに応じてメニューが変わるのが分かります。
更に、在来線列車を表す「その他」を選択すると、列車名の入力欄が現れます。
ネットスケープ 3.x〜4.x及びオペラ 6.xでは、このような高度な操作が出来ないため、スクリプト対応となっていても、単純なメニューが表示されます。
但し、在来線列車を表す「その他」を選択すると、次の画面で列車名入力を行う事を知らせるようにしております。
一方スクリプトが実行出来ない環境でも、旧型ブラウザと同じ表示になりますが、不正な選択肢でもエラーになりません。
まず、JAVAスクリプトではメニューを後から変える事は可能ですが、メニューをテキスト入力欄に変えたりするような事は出来ません。
このような事をするには、ダイナミックHTMLの技術を用いてメニューを非表示、テキストを表示などと言うような操作を行なわなければなりません。
ダイナミックHTMLはネットスケープ 4.x及びインターネットエクスプローラ4.x以降から利用可能になっておりますが、ネットスケープ 4.xでは実装が不充分なためこの機能を利用する事は難しい状況です。
また、オペラ 6.xでもダイナミックHTMLの一部が利用出来ません。
そこで、ネットスケープ 4.xなどの旧式ブラウザでは単純なメニューとして、新たなテキスト入力が必要な場合はCGIが次の画面を案内するようにすれば良い事にし、現行のCSS対応ブラウザでは表題のように動的にフォームを操作すると言うやり方を採る事にしました。
メニューに応じてテキスト入力欄を変えるスクリプト「ChangeMenu2.js」「ChangeMenu2-2.js」は以下のようになっております。
NoDHTML=(!document.all && !document.getElementById) || (navigator.useAgent.indexOf('Opera/6.')>=0) || (navigator.useAgent.indexOf('Opera 6.')>=0);function changeMenu2(n) {if (NoDHTML) return;if (n==100) {if (document.all) {document.all['TNAME'].style.display='none';document.all['TNAME2'].style.display='inline';}else if (document.getElementById) {document.getElementById('TNAME').style.display='none';document.getElementById('TNAME2').style.display='inline';}with(document.forms[0].TNAME) {options.length=1;options[0].text='列車名を入れて下さい'; options[0].value='';}document.forms[0].TNAME2.value='列車名を入れて下さい';}else {if (document.all) {document.all['TNAME2'].style.display='none';document.all['TNAME'].style.display='inline';}else if (document.getElementById) {document.getElementById('TNAME2').style.display='none';document.getElementById('TNAME').style.display='inline';}document.forms[0].TNAME2.value='';if (n==0) {with(document.forms[0].TNAME) {options.length=4;options[0].text='のぞみ'; options[0].value='nozomi';options[1].text='ひかり'; options[1].value='hikari';options[2].text='こだま'; options[2].value='kodama';options[3].text='つばめ'; options[3].value='tsubame';}}else if (n==1) {with(document.forms[0].TNAME) {options.length=5;options[0].text='はやて'; options[0].value='hayate';options[1].text='やまびこ'; options[1].value='yamabiko';options[2].text='なすの'; options[2].value='nasuno';options[3].text='つばさ'; options[3].value='tsubasa';options[4].text='こまち'; options[4].value='komachi';}}else if (n==2) {with(document.forms[0].TNAME) {options.length=3;options[0].text='とき'; options[0].value='toki';options[1].text='たにがわ'; options[1].value='tanigawa';options[2].text='あさま'; options[2].value='asama';}}else if (n==99) {with(document.forms[0].TNAME) {options.length=1;options[0].text='成田エクスプレス'; options[0].value='NEX';}}else {with(document.forms[0].TNAME) {options.length=1;options[0].text='********'; options[0].value='';}}}document.forms[0].TNAME.options[0].selected=true;}function checkEnter2() {if (!document.forms[0].TNAME.options[document.forms[0].TNAME.selectedIndex]) {alert('列車名が選択されておりません!'); return(false);}var i=document.forms[0].TNAME.options[document.forms[0].TNAME.selectedIndex].value;if (NoDHTML) {if (i=='') {alert('列車名が選択されておりません!'); return(false);}if (i!='?' && document.forms[0].tnumber.value=='') {alert('列車番号が入力されておりません!'); return(false);}if (i=='?') {alert('【ご案内】成田エクスプレス以外の在来線列車名は次の画面で入力して下さい。'); return(true);}return(true);}if (document.forms[0].TNAME.options[document.forms[0].TNAME.selectedIndex].value=='' &&(document.forms[0].TNAME2.value=='' || document.forms[0].TNAME2.value=='列車名を入れて下さい')) {alert('列車名が選択されておりません!'); return(false);}if (document.forms[0].tnumber.value=='') {alert('列車番号が入力されておりません!'); return(false);}return(true);}if (!NoDHTML) {document.write('<p>ご乗車予定の列車を選択して下さい。</p>'+'<ul>'+' <li><label><input type="radio" name="train" onclick="changeMenu2(0);" onkeypress="return(true)" selected="selected" />東海道・山陽・九州新幹線</label></li>'+' <li><label><input type="radio" name="train" onclick="changeMenu2(1)" onkeypress="return(true)" />東北・山形・秋田新幹線</label></li>'+' <li><label><input type="radio" name="train" onclick="changeMenu2(2);" onkeypress="return(true)" />上越・信越新幹線</label></li>'+' <li><label><input type="radio" name="train" onclick="changeMenu2(99);" onkeypress="return(true)" />成田エクスプレス</label></li>'+' <li><label><input type="radio" name="train" onclick="changeMenu2(100);" onkeypress="return(true)" />その他の在来線特急</label></li>'+' </ul>'+'</li>'+'<li>');}
if (!NoDHTML) {document.write('<input type="text" name="TNAME2" id="TNAME2" value="" size="20" />');}
<body onload="changeMenu2(-1);">
<table class="forNN4" border="0" cellspacing="0" cellpadding="0" summary="この表はネットスケープ 4.xでの表示崩れ対策で導入されているものです。"><tbody><tr><td><form action="(略)" method="post" onsubmit="return(checkEnter2());"><fieldset><legend>ご利用列車</legend><ol><li><script type="text/javascript" charset="shift_jis" src="ChangeMenu2.js"></script><p>列車名を選択して、列車番号を入力して下さい。</p><div><select name="TNAME" id="TNAME"><option value="">【東海道・山陽・九州新幹線】</option><option value="nozomi">のぞみ</option><option value="hikari">ひかり</option><option value="kodama">こだま</option><option value="tsubame">つばめ</option><option value="">【東北・北海道・山形・秋田新幹線】</option><option value="hayate">はやて</option><option value="yamabiko">やまびこ</option><option value="nasuno">なすの</option><option value="tsubasa">つばさ</option><option value="komachi">こまち</option><option value="">【上越・信越新幹線】</option><option value="toki">とき</option><option value="tanigawa">たにがわ</option><option value="asama">あさま</option><option value="">【在来線列車】</option><option value="NEX">成田エクスプレス</option><option value="?">その他</option></select><script type="text/javascript" charset="shift_jis" src="ChangeMenu2-2.js"></script><input type="text" name="tnumber" value="" size="4" />号</div></li><li><p>入力を確認して、<samp>送信</samp>ボタンを押してください。</p><p><input type="submit" value="送信" /></p></li></ol></fieldset></form></td></tr></tbody></table>
このスクリプトは、以下のような仕組みになっております。
changeMenu2()の定義を行ない、checkEnter2()の定義も行ない、changeMenu2(-1)」を起動することで、スクリプトが使えない環境でのメニューを、スクリプトが使える環境でのものに書き換えてしまいます。
基本的には、選択に応じてメニューを変えるスクリプトと殆ど同じなので、そちらをご覧頂く事として、ここでは、フォームの表示の切り替えについて解説します。
フォームを出したり消したりする動作は、ダイナミックHTMLと呼ばれる技術が必要です。
具体的には表示させる可能性のあるフォームアイテムを予め用意し、適宜表示/非表示を切り替えると言う動作を行ないます。
尚、単純に表示を切り替えるだけでは、フォームが送り出すデータに影響を与える事は出来ませんので、適宜フォームの内容を修正する事になります。
まず、「ChangeMenu2.js」の一行目でダイナミックHTMLに対応していないブラウザかどうかを判定しております。
NoDHTML=(!document.all && !document.getElementById) || (navigator.useAgent.indexOf('Opera/6.')>=0) || (navigator.useAgent.indexOf('Opera 6.')>=0);
基本的にダイナミックHTMLはCSSのプロパティ操作であるため、CSSを実装していないブラウザでは動作しません。
また、ネットスケープ 4.xではダイナミックHTMLの仕様が不充分なため、やはり利用出来ません。
前半の「(!document.all && !document.getElementById)」は、ネットスケープ 4.x以外のCSS実装ブラウザである事をチェックしております。
後半の「(navigator.useAgent.indexOf('Opera/6.')>=0) || (navigator.useAgent.indexOf('Opera 6.')>=0)」はオペラ 6.xを弾くための措置です。
ダイナミックHTMLに関しての詳細は「ダイナミックHTML」をご覧頂く事として、ここでは簡単に説明しておきます。
ダイナミックHTMLでは、HTML文書中のオブジェクトを操作するのにid属性値で与えられたID名を利用します。
そこで、表示を切り替えたいフォームアイテムにはid属性を与えておく事になります。
このスクリプトでは、列車名を撰ぶメニューには「TNAME」、在来線列車の名前を直接入力する入力欄には「TNAME2」と言うIDを与えておきます。
さて、このようにIDを与えられたHTMLの要素は、ダイナミックHTMLに対応したブラウザ(ネットスケープ 4.xを除く)なら、そのCSSのプロパティ定義をスクリプトから切り替える事が可能になります。
CSSでは表示/非表示はdisplayプロパティで切り替えられますので、スクリプトでもそのように切り替えを行なっております。
具体的な処理は以下のようになっております。
if (n==100) {if (document.all) {document.all['TNAME'].style.display='none';document.all['TNAME2'].style.display='inline';}else if (document.getElementById) {document.getElementById('TNAME').style.display='none';document.getElementById('TNAME2').style.display='inline';}with(document.forms[0].TNAME) {options.length=1;options[0].text='列車名を入れて下さい'; options[0].value='';}document.forms[0].TNAME2.value='列車名を入れて下さい';}else {if (document.all) {document.all['TNAME2'].style.display='none';document.all['TNAME'].style.display='inline';}else if (document.getElementById) {document.getElementById('TNAME2').style.display='none';document.getElementById('TNAME').style.display='inline';}document.forms[0].TNAME2.value='';(以下略)
函数本体の「if (n==100)」と言うのは、ラジオボタンで「その他の在来線特急」を撰んだ際に成立するもので、この場合は列車名選択メニューは消して、代りに列車名入力欄を表示させます。
それ以外の場合h逆に列車名入力欄を非表示にして列車名選択メニューを表示させます。
これらの切り替えには、当該要素オブジェクトのCSSで言うdisplayプロパティを切り替えればいいので、そのようにしております。
尚、ダイナミックHTMLには、ネットスケープ 4.x独自仕様の他、インターネットエクスプローラ独自仕様とW3Cが策定した標準規格仕様があり、それぞれをチェックする事で対処しなければなりません。
具体的には、document.allオブジェクトが定義されている場合はインターネットエクスプローラ独自仕様に従って処理し、document.getElementByIdオブジェクトが定義されている場合は標準規格仕様に従って処理すれば良い訳です。
当たり前ですがダイナミックHTMLには対応していない環境もあります。
そのような環境では使えないと言うのは明らかに問題なので、非対応環境への配慮を行なう事となります。
具体的には、
そこで、
changeMenu2()函数の冒頭では、ダイナミックHTML非対応環境では何もせずに戻るようにします。checkEnter2()函数の冒頭では、ダイナミックHTML非対応環境ではフォームの形式が異なっているので、それに合わせた判定を別に行ないます。前者の「ダイナミックHTML非対応環境では何もせずに戻るようにする処理」は以下のようになります。
function changeMenu2(n) {if (NoDHTML) return;
一方、後者「ダイナミックHTML非対応環境に合わせた判定」は以下のようになります。
function checkEnter2() {if (!document.forms[0].TNAME.options[document.forms[0].TNAME.selectedIndex]) {alert('列車名が選択されておりません!'); return(false);}var i=document.forms[0].TNAME.options[document.forms[0].TNAME.selectedIndex].value;if (NoDHTML) {if (i=='') {alert('列車名が選択されておりません!'); return(false);}if (i!='?' && document.forms[0].tnumber.value=='') {alert('列車番号が入力されておりません!'); return(false);}if (i=='?') {alert('【ご案内】成田エクスプレス以外の在来線列車名は次の画面で入力して下さい。'); return(true);}return(true);}
以上のようにして、ダイナミックHTML非対応環境でも問題が起こらないようにします。
今回はフォームにダイナミックHTML対応環境向けの入力欄などを埋め込むやり方を採りましたが、他にも方法はあります。
実際のスクリプトは書きませんが、以下のようにしても良いでしょう。
display: none」プロパティを与え、且つ専用のフォーム乙を代りに書き出して使う。つまり、フォームをなるべく共用するのではなく、フォームを完全に分けてしまう訳です。
Copyright ©平成17年-平成24年 さいたま・しらぎくさいと 版権所有
marguerite.site@gmail.com