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

 4.再入力不可の処理

(1) 再入力不可の処理
 解答を入力して「解答チェック」ボタンをクリックすると正誤が判定され、正解が表示される。正解表示後も再度解答が入力できる。
 ここでは、この解答の再入力ができないような処理を追加する。

 1度、「解答チェック」ボタンをクリックすると、そのページを表示している間は再度、解答入力ができないようにする。
 ひとつの方法として、1行テキストなどの入力部品は readonly属性を設定すると入力ができなくなる。スクリプト(プログラム)では、disabledプロパティをtrueに設定すると入力不可に設定できる。ただし、ブラウザの更新ボタンをクリックするとこの設定は無効になり、再入力が可能になる。これではあまり意味がない。

 正解が表示されたら再入力不可にする。正解表示欄に解答が表示されているかどうかで判定する。ただし、ブラウザの更新ボタンをクリックすると解答入力欄は入力可能になってしまうことには変わりない。
 HTMLファイルが読み込まれたとき<BODY>タグのonloadイベントが発生する。ここへ、処理を追加する。
 追加する処理は、次のとおりである。

  1. 「解答チェック」ボタンがクリックされたとき、正誤判定とともに解答入力欄のdisabledプロパティをtrueに設定して入力不可にする。
  2. 「解答チェック」ボタンを使用不可にする。 disabledプロパティ = true;
  3. ラジオボタンがあれば使用不可にする。 disabledプロパティ = true;
  4. ブラウザの更新ボタンがクリックされたとき、正解表示欄の状態によって解答入力欄を入力不可にする。

 次に、HTMLリストを示す。問題部分に変更はない。<BODY>タグにアクションを追加している。

<HTML>
<HEAD>
<TITLE>サンプル</TITLE>
<SCRIPT language="JavaScript" src="anschk3.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>
</BODY>
</HTML>

 次に、スクリプトを示す。解答入力欄と「解答チェック」ボタンを使用不可に設定する処理を追加している。また、解答済みを判定する関数isReloadを追加している。

// anschk3.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;    // 入力不可に設定
    }
    formp.CHKB.disabled = true;    // ボタン使用不可
    for(n = 0; n < formp.elements.length; ++n){    // ラジオボタンを探す
        if(formp.elements[n].type == "radio")
            formp.elements[n].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(){
    formp = document.forms[0];    // 1つ目のフォーム
    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;    // 入力不可に設定
        }
        formp.CHKB.disabled = true;    // ボタン使用不可
    }
}

 ラジオボタンには、グループごとに異なった名前を付けているので、elementsオブジェクトを使用してラジオボタンを探している。elementsオブジェクトの使い方については「10.ドキュメント (2) 入力部品」を参照のこと。

再入力の可否について
 HTMLリストに余分な設定(<BODY onload="isReload();">)が増えてしまったが、これで再入力ができないようにすることができた。
 ただし、解答チェック済みかどうかは、正解表示欄に文字がある/なしで判定しているので、正解表示欄を省略したときはブラウザの更新ボタンをクリックすることで解答の再入力ができる。


(2) 再チャレンジ
 再入力不可の設定にするとブラウザの更新ボタンをクリックしても解答が入力できなくなる。そこで、もう一度同じ問題にチャレンジできるように処理を追加する。処理は正解表示欄の文字を消し、ページを再表示(ブラウザの更新ボタンと同じ働き)するだけである。

// --==*==-- --==*==-- --==*==-- --==*==-- --==*==--
// 再チャレンジ
//   引数:なし
//   返却値:なし
// --==*==-- --==*==-- --==*==-- --==*==-- --==*==--
function Retry(){
    formp = document.forms[0];    // 1つ目のフォーム
    if(typeof(formp.SEIKAI) != "undefined"){    // 正解表示欄あり
        formp.SEIKAI.value = "";    // 正解消去
        location.reload();    // 更新
    }
}

 フォーム内の適当な場所に「再チャレンジ」のボタンを配置し、onclickイベントのアクションとして関数Retryの呼び出しを追加する。

<INPUT type="button" value="再チャレンジ" onclick="Retry();">   // ボタン


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

 

 

inserted by FC2 system