JavaScript プログラミング
 自学自習システム作成 前へ 目次へ 次へ 

 5.複数フォームへの対応

 同一ページ内に複数の問題を用意したとき、すなわち複数のフォームがあるとき、それぞれの問題にある「解答チェック」ボタンをクリックすれば、問題ごとに正誤判定が行われる。次のようなイメージである。


問題のイメージ(正誤判定、採点はされない)

問題1 次の計算をしなさい。
 (1) 123 + 654 = (@     )
 (2) 123 * 10  = (A     )

↓1つ目のフォーム
[解答欄] @    A
 
点 正解→

問題2 次の計算をしなさい。
 (1) 123 + 654 = (@     )

↓2つ目のフォーム
[解答欄] @
 
点 正解→
 
↓3つ目のフォーム
問題3 次の説明文の空欄に入れるべき適当な字句を解答群から選んで記号で答えよ。
 コンピュータが直接理解できる言語は(@ )と呼ばれ、(A )と(B )の
組合せだけでできている言語である。そこで、人間に理解しやすいように命令を英字や
数字などの記号で書けるようにした(C )が開発された。このプログラムを(@)に
変換するプログラムを(D )という。その後、数式の書き方や処理手順をもっと
人間にわかりやすい形式で書く言語が開発された。代表的な言語として、入門者用
の(E )、技術計算用の(F )、事務処理用の(G )などがある。
 
解答群
  ア 0   イ 1   ウ BASIC   エ COBOL   オ FORTRAN
  カ アセンブラ   キ アセンブラ言語   ク 機械語
点 正解→
 
↓4つ目のフォーム
問題4 Webブラウザ上で動作するスクリプト言語は何か。
   FORTRAN   COBOL   BASIC   JavaScript  
 
問題 初心者向けといわれるインタプリタ言語は何か。
   FORTRAN   COBOL   BASIC   JavaScript  
 
点 正解→
 
5つ目のフォーム(ページ全体をチェック)

 上に示したように、同一ページ内に4つの問題(フォーム)が存在するとき、4カ所の「解答チェック」ボタンをクリックする必要がある。
 ここでは、5つ目のフォームに示したように、一度のクリックだけで同一ページ内のすべての解答をチェックする処理を追加する。

 同一ページ内に存在するフォームはformsオブジェクト(「10.ドキュメント (1) フォーム」)で参照することができる。
 フォームの個数は document.forms.length で得られる。それぞれのフォームは document.forms[n] のように配列として参照することができる。
 ここでは、次のような処理を追加する。

  1. 同一ページ内のすべての解答をチェックする処理を関数PageCheckとして作成する。ページの別フォームの中に「ページ全体の解答チェック」ボタンを配置し、そのアクションとして設定する。
  2. 「再チャレンジ」のボタンも「ページ全体の解答チェック」ボタンと同じフォームに配置する。
  3. ページ全体のチェックができるようになるので、各設問で用意した「解答チェック」ボタンも省略できるようにする。

 関数PageCheckの処理
 同一ページに存在するフォームの個数(document.forms.length)分だけ解答をチェックする関数AnswerCheckを呼び出しを繰り返す。ただし、自身のフォームは「ページ全体の解答チェック」ボタンと得点欄だけなので処理の対象外とする必要がある。自身のフォームと問題のフォームを区別するため、自身のフォームには名前(name属性)を付けることにし、関数PageCheckの引数として渡す。フォームに付ける名前は ALLCHK とする。

 次にスクリプトを示す。関数AnswerCheckは変更無しである。

// anschk4.js --==*==-- --==*==-- --==*==-- --==*==--

// --==*==-- --==*==-- --==*==-- --==*==-- --==*==--
// 解答チェック関係
// --==*==-- --==*==-- --==*==-- --==*==-- --==*==--
// 解答チェック
//   引数:formp = フォーム
//   返却値:なし
// --==*==-- --==*==-- --==*==-- --==*==-- --==*==--
function AnswerCheck(formp){
    // 初期化
    OkColor = "#FFB0B0";    // 正解の色
    NgColor = "#B0B0FF";    // 不正解の色
    tensu = 0;    // 点数用
    seikai_data = "";    // 正解データ作成用
    if(typeof(formp.HAITEN) == "undefined")    // 配点なし=1点
        haiten = 1;
    else
        haiten = parseInt(formp.HAITEN.value);
    // 解答チェック
    if(formp.KAITO.length > 1){    // 解答入力欄複数あり
        for(n = 0; n < formp.KAITO.length; ++n){    // 問題(解答入力欄)数分繰り返す
            if(formp.KAITO[n].value == formp.KOTAE[n].value){    // 正誤の判定
                tensu = tensu + haiten;    // 得点加算
                formp.KAITO[n].style.backgroundColor = OkColor;    // 正解の色
            }else
                formp.KAITO[n].style.backgroundColor = NgColor;    // 不正解の色
            seikai_data = seikai_data + "(" + (n+1) + ") ";    // 正解データ作成 番号
            seikai_data = seikai_data + formp.KOTAE[n].value + " ";    // 正解データ作成 正解
            formp.KAITO[n].disabled = true;    // 入力不可に設定
        }
    }else{    // 解答入力欄1つ
        if(formp.KAITO.value == formp.KOTAE.value){    // 正誤の判定
            tensu = haiten;    // 得点加算
            formp.KAITO.style.backgroundColor = OkColor;    // 正解の色
        }else
            formp.KAITO.style.backgroundColor = NgColor;    // 不正解の色
        seikai_data = seikai_data + formp.KOTAE.value + " ";    // 正解データ作成 正解
        formp.KAITO.disabled = true;    // 入力不可に設定
    }
    if(typeof(formp.CHKB) != "undefined")    // チェックボタンあり
        formp.CHKB.disabled = true;        // ボタン使用不可 
    // 得点・正解表示
    if(typeof(formp.TOKUTEN) != "undefined")    // 得点欄あり
        formp.TOKUTEN.value = tensu;    // 得点表示
    if(typeof(formp.SEIKAI) != "undefined")    // 正解表示欄あり
        formp.SEIKAI.value = seikai_data;    // 正解表示
}
// --==*==-- --==*==-- --==*==-- --==*==-- --==*==--
// 解答チェック済み判定
//   <BODY onload="isReload();">
//   引数:なし
//   返却値:なし
// --==*==-- --==*==-- --==*==-- --==*==-- --==*==--
function isReload(){
    for(ff = 0; ff < document.forms.length; ++ff){    // このページ内のすべてのフォームを処理
        formp = document.forms[ff];    // ff番目のフォーム
        if(typeof(formp.SEIKAI) != "undefined" && formp.SEIKAI.value != ""){    // 正解表示あり
            if(formp.KAITO.length > 1){    // 解答入力欄複数あり
                for(n = 0; n < formp.KAITO.length; ++n)
                    formp.KAITO[n].disabled = true;    // 入力不可に設定
            }else{    // 解答入力欄1つ
                formp.KAITO.disabled = true;    // 入力不可に設定
            }
            if(typeof(formp.CHKB) != "undefined")    // チェックボタンあり
                formp.CHKB.disabled = true;    // 「解答チェック」ボタン使用不可
        }else if(formp.name == "ALLCHK" && formp.TOKUTEN.value != "")  // ページ全体チェックのフォーム
            formp.CHKB.disabled = true;    // 「ページ全体の解答チェック」ボタン使用不可
    }
}
// --==*==-- --==*==-- --==*==-- --==*==-- --==*==--
// 再チャレンジ
//   引数:なし
//   返却値:なし
// --==*==-- --==*==-- --==*==-- --==*==-- --==*==--
function Retry(){
    for(ff = 0; ff < document.forms.length; ++ff){    // このページ内のすべてのフォームを処理
        formp = document.forms[ff];    // 1つ目のフォーム
        if(typeof(formp.SEIKAI) != "undefined")    // 正解表示欄あり
            formp.SEIKAI.value = "";    // 正解消去
    }
    location.reload();    // 更新
}
// --==*==-- --==*==-- --==*==-- --==*==-- --==*==--
// ページ全体の解答チェック及び得点集計
//   引数:なし
//   返却値:なし
// --==*==-- --==*==-- --==*==-- --==*==-- --==*==--
function PageCheck(){
    dtokuten = 0;    // 得点用
    for(ff = 0; ff < document.forms.length; ++ff){  // このページ内のすべてのフォームを処理
        if(document.forms[ff].name != "ALLCHK"){    // このフォーム以外を処理
            AnswerCheck(document.forms[ff]);     // 解答チェック呼び出し
            dtokuten = dtokuten + parseInt(document.forms[ff].TOKUTEN.value);  // 得点計算
        }
    }
    ALLCHK.TOKUTEN.value = dtokuten;    //得点表示
    ALLCHK.CHKB.disabled = true;    // 使用不可に設定
}

 解答チェック済みかを判定する関数isReloadもページ内のすべてのフォームを処理するため、document.forms.lengthの回数だけ繰り返す処理を追加している。

 参考までに、問題のイメージのHTMLリストを次に示しておく。

<HTML>
<HEAD>
<TITLE>サンプル</TITLE>
<SCRIPT language="JavaScript" src="anschk4.js"></SCRIPT></HEAD>
<BODY onload="isReload();">
<P><B>記述問題</B><BR>
2 次の計算をしなさい。<BR>
 (1) 123 + 654 = (@     )<BR>
 (2) 123 * 10  = (A     )</P>
<FORM>[解答欄]<BR>
@ <INPUT size="8" type="text" name="KAITO">
   A <INPUT size="8" type="text" name="KAITO"><BR>
 <BR>
<INPUT type="button" name="CHKB" value="解答チェック" onclick="AnswerCheck(this.form);">
 <INPUT size="8" type="text" readonly name="TOKUTEN">点
 正解→<INPUT size="20" type="text" readonly name="SEIKAI">
<INPUT type="hidden" name="KOTAE" value="777">
<INPUT type="hidden" name="KOTAE" value="1230">
</FORM>
<P><BR>
</P>
<P><B>記述問題</B><BR>
2 次の計算をしなさい。<BR>
 (1) 123 + 654 = (@     )</P>
<FORM>[解答欄]<BR>
@ <INPUT size="8" type="text" name="KAITO"><BR>
 <BR>
<INPUT type="button" name="CHKB" value="解答チェック" onclick="AnswerCheck(this.form);">
 <INPUT size="8" type="text" readonly name="TOKUTEN">点
 正解→<INPUT size="20" type="text" readonly name="SEIKAI">
<INPUT type="hidden" name="KOTAE" value="777">
</FORM>
<P><BR>
</P>
<FORM>問題 次の説明文の空欄に入れるべき適当な字句を解答群から選んで記号で答えよ。<BR>
 コンピュータが直接理解できる言語は(@<SELECT name="KAITO">
  <OPTION value="0" selected> </OPTION>
  <OPTION value="ア">ア</OPTION>  <OPTION value="イ">イ</OPTION>
  <OPTION value="ウ">ウ</OPTION>  <OPTION value="エ">エ</OPTION>
  <OPTION value="オ">オ</OPTION>  <OPTION value="カ">カ</OPTION>
  <OPTION value="キ">キ</OPTION>  <OPTION value="ク">ク</OPTION>
</SELECT> )と呼ばれ、(A<SELECT name="KAITO">
  <OPTION value="0" selected> </OPTION>
  <OPTION value="ア">ア</OPTION>  <OPTION value="イ">イ</OPTION>
  <OPTION value="ウ">ウ</OPTION>  <OPTION value="エ">エ</OPTION>
  <OPTION value="オ">オ</OPTION>  <OPTION value="カ">カ</OPTION>
  <OPTION value="キ">キ</OPTION>  <OPTION value="ク">ク</OPTION>
</SELECT> )と(B<SELECT name="KAITO">
  <OPTION value="0" selected> </OPTION>
  <OPTION value="ア">ア</OPTION>  <OPTION value="イ">イ</OPTION>
  <OPTION value="ウ">ウ</OPTION>  <OPTION value="エ">エ</OPTION>
  <OPTION value="オ">オ</OPTION>  <OPTION value="カ">カ</OPTION>
  <OPTION value="キ">キ</OPTION>  <OPTION value="ク">ク</OPTION>
</SELECT> )の<BR>
組合せだけでできている言語である。そこで、人間に理解しやすいように命令を英字や<BR>
数字などの記号で書けるようにした(C<SELECT name="KAITO">
  <OPTION value="0" selected> </OPTION>
  <OPTION value="ア">ア</OPTION>  <OPTION value="イ">イ</OPTION>
  <OPTION value="ウ">ウ</OPTION>  <OPTION value="エ">エ</OPTION>
  <OPTION value="オ">オ</OPTION>  <OPTION value="カ">カ</OPTION>
  <OPTION value="キ">キ</OPTION>  <OPTION value="ク">ク</OPTION>
</SELECT> )が開発された。このプログラムを(@)に<BR>
変換するプログラムを(D<SELECT name="KAITO">
  <OPTION value="0" selected> </OPTION>
  <OPTION value="ア">ア</OPTION>  <OPTION value="イ">イ</OPTION>
  <OPTION value="ウ">ウ</OPTION>  <OPTION value="エ">エ</OPTION>
  <OPTION value="オ">オ</OPTION>  <OPTION value="カ">カ</OPTION>
  <OPTION value="キ">キ</OPTION>  <OPTION value="ク">ク</OPTION>
</SELECT> )という。その後、数式の書き方や処理手順をもっと<BR>
人間にわかりやすい形式で書く言語が開発された。代表的な言語として、入門者用<BR>
の(E<SELECT name="KAITO">
  <OPTION value="0" selected> </OPTION>
  <OPTION value="ア">ア</OPTION>  <OPTION value="イ">イ</OPTION>
  <OPTION value="ウ">ウ</OPTION>  <OPTION value="エ">エ</OPTION>
  <OPTION value="オ">オ</OPTION>  <OPTION value="カ">カ</OPTION>
  <OPTION value="キ">キ</OPTION>  <OPTION value="ク">ク</OPTION>
</SELECT> )、技術計算用の(F<SELECT name="KAITO">
  <OPTION value="0" selected> </OPTION>
  <OPTION value="ア">ア</OPTION>  <OPTION value="イ">イ</OPTION>
  <OPTION value="ウ">ウ</OPTION>  <OPTION value="エ">エ</OPTION>
  <OPTION value="オ">オ</OPTION>  <OPTION value="カ">カ</OPTION>
  <OPTION value="キ">キ</OPTION>  <OPTION value="ク">ク</OPTION>
</SELECT> )、事務処理用の(G<SELECT name="KAITO">
  <OPTION value="0" selected> </OPTION>
  <OPTION value="ア">ア</OPTION>  <OPTION value="イ">イ</OPTION>
  <OPTION value="ウ">ウ</OPTION>  <OPTION value="エ">エ</OPTION>
  <OPTION value="オ">オ</OPTION>  <OPTION value="カ">カ</OPTION>
  <OPTION value="キ">キ</OPTION>  <OPTION value="ク">ク</OPTION>
</SELECT> )などがある。<BR>
 <BR>
解答群<BR>
  ア 0   イ 1   ウ BASIC   エ COBOL   オ FORTRAN<BR>
  カ アセンブラ   キ アセンブラ言語   ク 機械語<BR>
<INPUT type="button" name="CHKB" value="解答チェック" onclick="AnswerCheck(this.form);">
 <INPUT size="8" type="text" name="TOKUTEN" readonly>点
 正解→<INPUT size="50" type="text" name="SEIKAI" readonly>
<INPUT type="hidden" name="KOTAE" value="ク">
<INPUT type="hidden" name="KOTAE" value="ア">
<INPUT type="hidden" name="KOTAE" value="イ">
<INPUT type="hidden" name="KOTAE" value="キ">
<INPUT type="hidden" name="KOTAE" value="カ">
<INPUT type="hidden" name="KOTAE" value="ウ">
<INPUT type="hidden" name="KOTAE" value="オ">
<INPUT type="hidden" name="KOTAE" value="エ">
<INPUT type="hidden" name="HAITEN" value="5">
</FORM>
<P><BR>
</P>
<FORM>問題 Webブラウザ上で動作するスクリプト言語は何か。<BR>
  <INPUT type="radio" name="a1" onclick='KAITO[0].value="1";'> FORTRAN
  <INPUT type="radio" name="a1" onclick='KAITO[0].value="2";'> COBOL
  <INPUT type="radio" name="a1" onclick='KAITO[0].value="3";'> BASIC
  <INPUT type="radio" name="a1" onclick='KAITO[0].value="4";'> JavaScript
  <INPUT size="3" type="text" name="KAITO" readonly><BR>
&nbsp;<BR>
問題 初心者向けといわれるインタプリタ言語は何か。<BR>
  <INPUT type="radio" name="a2" onclick='KAITO[1].value="1";'> FORTRAN
  <INPUT type="radio" name="a2" onclick='KAITO[1].value="2";'> COBOL
  <INPUT type="radio" name="a2" onclick='KAITO[1].value="3";'> BASIC
  <INPUT type="radio" name="a2" onclick='KAITO[1].value="4";'> JavaScript
  <INPUT size="3" type="text" name="KAITO" readonly><BR>
 <BR>
<INPUT type="button" name="CHKB" value="解答チェック" onclick="AnswerCheck(this.form);">
 <INPUT size="8" type="text" name="TOKUTEN">点
 正解→<INPUT size="20" type="text" name="SEIKAI">
<INPUT type="hidden" name="KOTAE" value="4">
<INPUT type="hidden" name="KOTAE" value="3">
<INPUT type="hidden" name="HAITEN" value="2">
</FORM>
<FORM name="ALLCHK">
<INPUT type="button" value="ページ全体の解答チェック" name="CHKB" onclick="PageCheck()">
 <INPUT size="8" type="text" name="TOKUTEN" readonly>点
 <INPUT type="submit" onclick="Retry();" value="再チャレンジ">
</FORM>
</BODY>
</HTML>

 ここまでで、各問題の「解答チェック」ボタン、「得点欄」と「正解表示欄」を省略できるようにしてきたが、ページ全体の解答チェックの処理として追加した関数PageCheckで「得点欄」の得点を集計するようにしているので、「得点欄」は省略できなくなった。もし、「得点欄」を省略したい場合は、隠しフィールドとする。


前へ 目次へ 次へ 
 JavaScript プログラミング Copyright © 2003 Hiroshi Masuda 

 

 

inserted by FC2 system