JavaScriptによるクライアントサイドプログラミング
web ページ http://hands.ei.tuat.ac.jp/yorifuji/jikken/order.html にアクセスしてみてください.これは商品注文用 web ページ(もちろん例)です.適当に個数を設定して注文ボタンを押すと,総額が表示され本当に注文するかが聞かれるページが表示されます.
<HTML> <BODY> <FORM name="fruit" method="POST" action="http://hands.ei.tuat.ac.jp/yorifuji/cgi-bin/order.cgi"> <TABLE> <TR><TD>商品名</TD><TD>単価</TD><TD>個数</TD></TR> <TR><TD>りんご</TD><TD>200</TD><TD><input type="text" value=0 size=5 name='apple'></TD></TR> <TR><TD>ぶどう</TD><TD>500</TD><TD><input type="text" value=0 size=5 name='grape'></TD></TR> <TR><TD>みかん</TD><TD>100</TD><TD><input type="text" value=0 size=5 name='orange'></TD></TR> </TABLE> <input type="submit" value="注文"> </FORM> </BODY> </HTML>
この web ページは CGI を利用しています.入力された各商品の個数をサーバに送信し,サーバ側で合計を計算し,確認ページを生成,返信することで,ブラウザに確認ページが表示されます. さて,ここで単に総額を表示するだけの目的で,わざわざサーバにデータを送り,確認用ページを送ってもらうのは通信の無駄だと思いませんか.JavaScript を用いると,この無駄を解消することができます.
次の HTML コードは,先程の web ページコードに総計を表示する場所(フォーム部品)の追加と,JavaScript コードを記述する準備をしたものです.
<HTML> <HEAD> <SCRIPT language="JavaScript"> <!-- --> </SCRIPT> </HEAD> <BODY> <FORM name="fruit" method="POST" action="http://hands.ei.tuat.ac.jp/yorifuji/cgi-bin/order.cgi"> <TABLE> <TR><TD>商品名</TD><TD>単価</TD><TD>個数</TD></TR> <TR><TD>りんご</TD><TD>200</TD><TD><input type="text" value=0 size=5 name='apple'></TD></TR> <TR><TD>ぶどう</TD><TD>500</TD><TD><input type="text" value=0 size=5 name='grape'></TD></TR> <TR><TD>みかん</TD><TD>100</TD><TD><input type="text" value=0 size=5 name='orange'></TD></TR> <TR><TD>総 計</TD><TD>---</TD><TD><input type="text" value=0 size=5 name='sum'></TD></TR> </TABLE> <input type="submit" value="注文"> </FORM> </BODY> </HTML>
総計を計算するためには各商品の注文個数を知る必要があります.各商品の個数はフォーム部品(テキスト)に入力されています.これを JavaScript からアクセスするには,たとえば,
var a = document.fruit.apple.value;
と書きます.これは,りんごの注文個数を変数 a に格納します.なんとなく想像できるでしょうか.
document とは JavaScript が実行されているブラウザに表示されているドキュメントオブジェクトを指します.fruit は上記コードのフォームの部分の名前です.続く apple は上記コードのりんごの個数を入力するためのフォーム部品の名前です.それらをドットでつなげた document.fruit.apple は,現在処理しているドキュメント内の fruit という名前のオブジェクト(フォーム)内の apple という名前のオブジェクト(フォーム部品)を指し示します.そして最後の value はオブジェクトのプロパティの一つでオブジェクトに格納されている値そのもののを指し示します.したがって,つまるところ,document.fruit.apple.value はりんごの個数を入力するフォーム部品に入力されている値ということになります.
なお,フォーム部品(テキスト)から取り出せる値は数値ではなく文字列です.数値として計算したい場合は,parseInt 等を用いて変換をする必要があります.
計算した総計をフォーム部品(テキスト)に表示したいときの方法は,フォーム部品からの値の取り出し方がわかれば,容易に想像できると思います.たとえば,総計を1000にしたいのであれば,
document.fruit.sum.value = 1000;
とすればよいのです.
さて,ここでちょっとしたテクニックを教えておきます.もし,オブジェクトの名前が変数 name に格納されてとき,そのオブジェクトをアクセスしたい場合は,
document.all.item( name )
と書くことでアクセスすることができます.つまり,次の文は先程の総計の欄に1000を表示するコードとまったく同じ動きをします.なお,このコードを正しく動かすためには,同じドキュメント内に同じ名前のものがないようにする必要があります.
var a = 'sum'; document.all.item( a ).value = 1000;
これで,各商品の個数を得る方法と,総計を表示する方法がわかりました.次に,いつ書き換えたらよいかを考えてみましょう.一番単純なのがユーザにボタンを押させ,そのときに書き換えるものでしょう.そこで,画面に総計計算用のボタンを用意するために,次のようにフォーム部品を追加ます.
: </TABLE> <input type="submit" value="注文"> <input type="button" value="総計計算"> </FORM> :
では,このボタンが押されたときに,なんらかの処理をさせるにはどうしたらよいでしょうか.この答えはイベントの利用です.次のようにフォーム部品の記述を変更すると,ボタンが押されたときに関数 calc が呼び出されます.
<input type="button" onclick="calc()" value="総計計算">
いわゆるイベントドリブン型です.この関数 clac の中で総計を計算し,表示する処理を行えば,当初の目的が達成できます.
しかし,いちいちボタンを押させるのもスマートではありません.総計は各商品の個数が変わったときに変化するものです.この個数の変化が起こったときに処理を行う方法はないでしょうか.もちろんあります.先程はボタンがクリックされたらというイベントを処理のきっかけに利用していましたが,次のように書くことでフォーム部品の値が変化したらというイベントをきっかけにすることができます.
<input type="text" value=0 size=2 name='apple' onChange="calc()">
これら「イベントが起こったら〜する」の記述のことをイベントハンドラと呼びます.イベントハンドラにはこれ以外にも,onDblClick, onKeyDown, onKeyPress, onKeyUp, onMouseDown, onMouseUp, onMouseOver, onMouseOut, onMouseMove, onLoad, onUnload, onFocus, onBlur, onSubmit, onReset, onResize, onMove, onDragDrop, onAbort, onError, onSelect などがあります.
さて,もし個数を入力するところに数ではないもの,たとえば'あ'などと入力するとどうなってしまうでしょうか.paseInt で数字列でないものを数値に変換しようとすると,NaN という特殊な値が返されます.これを用いて計算を続けるともちろんきちんとした答えが出ません.
CGI を用いた web ページなどでは入力に誤りがあると,それを訂正するようにしたメッセージと共に,再度入力画面が表示されます.JavaScript を用いれば,そのようなチェックもリアルタイムに行うことができます.個数の値が変わったときに,その値の正当性をチェックしてあげればよいのです.もし,入力されたのが数でなかったら,たとえば値を0に書き換えたりすることができるわけです.なお,数値が NaN であるかどうかは関数 isNaN を利用します.
isNaN( parseInt('あ') )
は true を返します.
では,ここまで説明したことを実際にコード化してみてください.,下に示すコードにいくつかの処理を書き加えて,
ようにしてください.
<HTML> <HEAD> <SCRIPT language="JavaScript"> <!-- --> </SCRIPT> </HEAD> <BODY> <FORM name="fruit"> <TABLE> <TR><TD>商品名</TD><TD><単価></TD><TD>個数</TD></TR> <TR><TD>りんご</TD><TD>200</TD><TD><input type="text" value=0 size=5 name='apple'></TD></TR> <TR><TD>ぶどう</TD><TD>500</TD><TD><input type="text" value=0 size=5 name='grape'></TD></TR> <TR><TD>みかん</TD><TD>100</TD><TD><input type="text" value=0 size=5 name='orange'></TD></TR> <TR><TD>総 計</TD><TD>---</TD><TD><input type="text" value=0 size=5 name='sum'></TD></TR> </TABLE> </FORM> </BODY> </HTML>