基本のフォームができたら、次は計算ができるフォームへと機能を足していきます。
計算をさせるためにJavaScriptを使います。フォーム内の価格と個数から合計金額を計算して表示します。
実例(p7-2.html)
まずは、ページを開いたときに実行されるスクリプトの初期設定を作ります。
通常であれば、商品コードや商品名、価格といった基礎データはデータベースを作って管理します。そのデータベースは配列変数で管理されます。
専用のデータベースを使わなくても、配列変数に直接データを準備することで、簡易データベースとすることができます。これはデータ管理の手間の違いであって、スクリプト内ではどちらも配列変数によるデータで、違いはありません。
今回は事前に配列変数にデータを書いて置くのではなく、フォーム内にあるデータから簡易のデータベースを作ってみます。データベースに必要なデータは既にフォーム内に用意してあるからです。
データを先に配列変数で用意した場合、そのデータをフォームに書き出して利用します。
今回はその逆で、フォームにあるデータを配列変数に取り込んでデータベースを作ろうとしています。
どちらにせよ、元となるデータを一カ所にして置かないと、修正するときにあちこち直すのでは間違いが生じやすくなるのです。
まずは、データの受け入れをするために配列変数を準備します。商品コード、価格、個数を取得するために「sid」「sprice」「snumber」の3つの配列変数を定義します。
合計金額は変数tpriceを使います。
変数の準備ができたらフォームからそれぞれの情報を取得します。
<script type="text/javascript"> var n,obj; //商品コード sid = new Array(); //価格 sprice = new Array(); //個数 snumber = new Array(); //合計金額 tprice = 0; //価格を取得 obj = document.getElementsByClassName("price"); for(n=0;n<obj.length;n++) { sid[n] = obj[n].id;
sprice[sid[n]] = eval(obj[n].value);
snumber[sid[n] + "n"] = 0;
} //個数にIDを割り当てる
obj = document.getElementsByClassName("number");
for(n=0;n<obj.length;n++) {
obj[n].id = sid[n] + "n";
}
document.order.reset(); </script>
price(クラス)は、フォーム内の価格を表示する<input>タグに割り当てられています。これを変数objに入れた後、for文で1つずつ取り出します。
クラスは複数あるためIDのように直接取得することができないため、getElementsByClassName()を使って、一旦変数に入れるのです。この場合の変数は自動的に配列変数になります。
配列変数objには<input>タグの情報が丸ごと入っていることになるため、それぞれのID名から商品コードを取得し、value属性(入力データ)から価格を取得します。
for文では、変数nを0からobj.lengthより小さい値まで、1ずつ増えて繰り返します。obj.lengthは配列変数objの要素の数(最大値)です。配列変数objに入れたprice(クラス)の数とも言えます。今回は10個ありますので、obj.lengthは10の値となり、「n<10」が繰り返す最後の数になるため、nは9まで増えて処理が終わります。0~9までの10回処理をすることになります。
for文の中では、最初に準備した3つの配列変数に値を入れています。
1つ目が、配列変数sidです。<input>タグのID名(id属性)の値を取って代入しています。これで商品コードが取得できます。
2つ目が、配列変数spriceで、<input>タグのvalue属性から価格の値を取得しています。ただし、そのまま代入せずに関数eval()を使って文字列から数値に変換しています。これは後の計算でエラーがでないようにするためです。フォームから取得したデータは数字であっても文字列なので、数値にしないと正しく計算が実行できません。
3つ目は、配列変数snumberです。これは個数ですから、入力されたデータがないため、ここでは0という数値に設定しておきます。
さて、これら3つの配列変数ですが、sidについては要素に変数nから取得した数値を使っています。しかし、次の2つについては数値を使わず、配列変数sidを使っています。要素には数値だけでなく、文字列を使うことができるため、番号で呼び出さずに名前で呼び出すことができます。今回は商品コードで呼び出すことになります。
具体的に「n=0」の時の要素と値を見てみましょう。
変数nが0のとき、配列変数sid[0]には「s001」が入ります。
次の配列変数spriceの要素に「sid[0]」が使われるので、「sprice["s001"]」となり、「200」が入ります。
そして、配列変数snumberは少し変わっていて、「sid[0] + "n"」が使われていますので、「snumber["s001n"]」となって「0」を入れます。この配列変数snumberにはID名をそのまま要素にせず「n」を付けてます。これは次のfor文で、個数の<input>タグにID名を付けていることに関係してます。価格と同じID名を使えないために「n」を付けて別のものとして後でアクセスするためです。
配列変数の関係を表にすると次のようになります。
for文の変数nの値 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|---|
配列変数sidの要素 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
配列変数sidの値 | s001 | s002 | w001 | w002 | w003 | w004 | w005 | w006 | w007 | w008 |
配列変数spriceの要素 | s001 | s002 | w001 | w002 | w003 | w004 | w005 | w006 | w007 | w008 |
配列変数snumberの要素 | s001n | s002n | w001n | w002n | w003n | w004n | w005n | w006n | w007n | w008n |
2つ目の変数objには、number(クラス)から取得した個数を入力する<input>タグの複数のデータが入ります。やはりこれも配列変数です。
そして、次のfor文を使って、ID名のないnumber(クラス)に対して、1つずつID名を割り当てています。この時、ID名をprice(クラス)と見分ける必要があるため、「商品コード+n」という表記にしています。配列変数snumberの要素はこのID名と同じになるようにしているため、ID名を指定したら即座に個数の入った配列変数を呼び出すことができます。
最後にフォームをリセットしています。これは、フォームを再読込したときに前の数値が残ってしまうことを防ぎ、確実に初期状態に戻すためです。
フォームを先に作ったため、今回は後から配列変数にデータベースを作りました。
もし配列変数で先にデータを準備した場合、その内容に応じてスクリプトで自動的にフォームを書き出すことになるため、スクリプトを正しく書かないとフォームを見ることができません。
今回はHTMLの学習が基本なので、まずフォームを作り、後でフォームを手直しするだけでデータの書き換えができるようにしています。これならHTMLを理解することが重要で、スクリプトは変更不要となります。
フォームに個数を入力し、合計金額が計算できるようにしましょう。
テーブルの商品一覧の下に1行追加して、合計金額の表示位置と計算結果の表示ボタンを作ります。
<tr>
<td>W008</td>
<td>お団子セット(2種類各5本)</td>
<td><input type="text" class="price" id="w008" value="750" size="10" maxlength="5"></td>
<td><input type="text" class="number" size="5" maxlength="3"></td>
</tr>
<tr>
<th>合計</th>
<th><input type="button" value="注文確認" onClick="calc_price()"></th>
<td class="t_right"><span id="total_price"></span></td>
<td> </td>
</tr>
</table>
「注文確認」のボタンを押すとユーザー関数calc_price()が呼び出され、結果がtotal_price(ID)に表示されるようにします。
では、ユーザー関数を作りましょう。
function calc_price() { var n; tprice = 0; for (n=0;n<sid.length;n++) { snumber[sid[n] + "n"] = document.getElementById(sid[n] + "n").value;
tprice += sprice[sid[n]] * snumber[sid[n] + "n"];
} //合計金額 document.getElementById("total_price").innerHTML = tprice + "円"; }
これで、合計の計算ができるようになりました。
「金額確認」のボタンを押すとボタンの右側に「0円」と表示されます。また、個数の欄に数字を入力してから「金額確認」ボタンを押せば、合計金額が表示されます。
スクリプトの動作テストをするとエラーで表示が出ないことがあります。
その場合、IEならF12を押してデバッガーを表示します。HTMLのソースが畳まれて表示されますので、スクリプトのタブを選んでください。
エラーのダイヤログが表示された場合は、「このWEBページをデバッグしますか?」と尋ねてくるので「OK」を選ぶと上記のデバッガーが開きます。
デバッガーは間違いの場所を行数で指示してくれますが、関連する前後で間違いが発生している場合もあるので、指示の部分に間違いがなければ、前後のスクリプトを見直しましょう。
Firefoxの場合は、メニューから「WEB開発」を開き、「WEBコンソール」や「デバッグ」を利用します。
もし、onClickのところでユーザー関数がないというエラーが出た場合は、function calc_price()の部分に誤りがあります。
また、正しく金額を表示しない場合、ユーザー関数の中を良く見ましょう。「getElementById()」の表記で「Id」は大文字のI(アイ)なので注意してください。