ついでにもう一つ、CSS(カスケーディングスタイルシート)を使って画面をデザインする方法も解説します。
【1】「sample010.html」を以下のように更新してください。コピーして貼り付けてもかまいません。
<html>
<head>
<script type="text/javascript" src="sample010.js"></script>
<link href="design.css" rel="stylesheet" type="text/css">
<title>sample010</title>
</head>
<body>
都道府県マスター
<form name="form1">
PREF_CD:<input type="text" name="txtPrefCd" id="txtPrefCd">
<a href="" name="linkMaxCd" id="linkMaxCd">最大値</a>
PREF_NAME:<input type="text" name="txtPrefName" id="txtPrefName">
<input type="button" name="btnInsert" id="btnInsert" value="追加">
<input type="button" name="btnUpdate" id="btnUpdate" value="更新">
<input type="button" name="btnDelete" id="btnDelete" value="削除">
</form>
<div id="sqlDisplay"></div>
<div id="dataDisplay"></div>
</body>
</html>
【2】新たに「design.css」を以下のように作成してください。コピーして貼り付けてもかまいません。
/* デザイン用CSS */
body {
background-color: #ccff99;
}
#selectPref {
width: 300px;
}
【3】「sample010.js」を以下のように更新してください。コピーして貼り付けてもかまいません。
var database;
var txtPrefCd;
var txtPrefName;
onload = init;
onunload = dbClose;
function init() {
//初期設定をする関数
txtPrefCd = document.getElementById("txtPrefCd");
txtPrefName = document.getElementById("txtPrefName");
txtPrefCd.onblur = function (){blur(this);}
txtPrefCd.onfocus = function (){focus(this);}
txtPrefName.onblur = function (){blur(this);}
txtPrefName.onfocus = function (){focus(this);}
document.getElementById("btnInsert").onclick = function (){dataInsert();}
document.getElementById("btnUpdate").onclick = function (){dataUpdate();}
document.getElementById("btnDelete").onclick = function (){dataDelete();}
document.getElementById("linkMaxCd").onclick = function (){return maxCd();}
dbConnect();
dataDisplay();
}
function dbConnect() {
//データベースに接続する関数
database = new ActiveXObject("ADODB.Connection");
database.Open("Driver={Microsoft Access Driver (*.mdb)}; DBQ=c:\\SampleDB010.mdb;");
alert("データベースに接続しました。");
}
function dbClose() {
//データベースを切断する関数
database.Close();
database = null;
alert("データベースを切断しました。");
}
function focus(obj){
obj.style.backgroundColor = "#ffff00";
}
function blur(obj){
obj.style.backgroundColor = "#ffffff";
}
function dataDisplay() {
//データを表示する関数
var mySql = "select * from T01Prefecture order by PREF_CD";
var recordSet = database.Execute(mySql);
document.getElementById("dataDisplay").innerHTML = "";
var tempHtml = "<select size=\"25\" name=\"selectPref\" id=\"selectPref\">\n";
while (!recordSet.EOF){
tempHtml = tempHtml + "\t<option value=\"" + recordSet(0) + "\">" + recordSet(1) + "</option>\n";
recordSet.MoveNext();
}
tempHtml = tempHtml + "</select>";
alert(tempHtml);
document.getElementById("dataDisplay").innerHTML = tempHtml;
document.getElementById("selectPref").onchange = function (){prefChange(this);}
recordSet.Close();
recordSet = null;
}
function dataInsert() {
//データを追加する関数
try{
if(dataCheck(1)){
var mySql = "insert into T01Prefecture values(" + Number(txtPrefCd.value) + ",'" + txtPrefName.value + "')";
sqlDisplay(mySql);
database.Execute(mySql);
dataDisplay();
alert("追加しました。");
}
}catch(error){
alert(error.number + "\n" + error.description);
}
}
function dataUpdate() {
//データを更新する関数
if(dataCheck(1)){
var mySql = "update T01Prefecture set PREF_NAME ='" + txtPrefName.value + "' where PREF_CD = " + Number(txtPrefCd.value);
sqlDisplay(mySql);
database.Execute(mySql);
dataDisplay();
alert("更新しました。");
}
}
function dataDelete() {
//データを削除する関数
if(dataCheck(0)){
var mySql = "delete from T01Prefecture where PREF_CD = " + Number(txtPrefCd.value);
sqlDisplay(mySql);
database.Execute(mySql);
dataDisplay();
alert("削除しました。");
}
}
function sqlDisplay(_mySql) {
//SQLを表示する関数
document.getElementById("sqlDisplay").innerHTML = "<p>" + _mySql + "</p>";
}
function dataCheck(flag){
//データをチェックする関数
var tempStr = "は必ず入力してください。";
if (txtPrefCd.value == "") {
alert("PREF_CD" + tempStr);
return false;
}
if (txtPrefCd.value.match(/[^0-9]/)) {
alert("PREF_CDには半角数字を入力してください!");
txtPrefCd.focus();
return false;
}
if (flag == 1 && txtPrefName.value == "") {
alert("PREF_NAME" + tempStr);
return false;
}
return true;
}
function maxCd(){
//最大値を取得する関数
var mySql = "select max(PREF_CD) from T01Prefecture";
var recordSet = database.Execute(mySql);
txtPrefCd.value = recordSet(0) + 1;
txtPrefName.value = "";
txtPrefName.focus();
return false;
}
function prefChange(obj) {
txtPrefCd.value = obj.value;
txtPrefName.value = obj.options[obj.selectedIndex].text;
document.getElementById("sqlDisplay").innerHTML = "<p>selectedIndex:" + obj.selectedIndex + " value:" + obj.value + "</p>";
}
【4】保存したら sample010.html をダブルクリックしてWebブラウザで開きます。
★sample010.html、design.css、sample010.jsは必ず同じフォルダ内に置いてください。
【5】画面を開くとアラートが表示されます。これはプログラムで選択ボックス(selectタグ)を作っているのですが、タグが正しく作られているか確認するためのものです。あとでアラート部分はコメントにするか削除してかまいません。
【6】selectタグのvalueの値に注目してください。北海道の「1」からはじまり沖縄の「47」で終わっています。valueはデータベースのPREF_CDの値です。
確認したら「OK」をクリックし、アラートを閉じてください。
【7】プログラムで作成した選択ボックスが、ブラウザの画面に表示されました。
ポイントはこの選択ボックスが、あらかじめhtml側に書いたものではなく、データベースにあるデータをもとにプログラムで作成したものであるということです。
【8】「北海道」をクリックすると、PREF_CDとPREF_NAMEに値が自動で入力されます。
*この時、選択ボックスの上に、selectedIndex:0 value:1 と表示されています。
・selectedIndexとは選択ボックスの何番目かを示していて、0番目からはじまります
・valueは先ほどアラートで表示したselectタグのvalueのことです。
selectedIndexとvalueの値がずれている点に注目しておいてください。selectedIndexは選択ボックスのテキストを取り出すときに使います。
【9】「沖縄県」をクリックすると、PREF_CDとPREF_NAMEに値が自動で入力されます。
【解説】
まずhtml側からみていきましょう。前回までのようなテキストエリアでは、一覧からデータを選択した時にどのデータを選択したのかわかりません。そこで選択ボックスを使うことにします。(selectタグ)
選択ボックスはhtml側に直接書くのではなく、プログラムの中で作成します。なぜなら選択ボックスの内容はデータベースのデータによって変化するので、あらかじめ書くことができないからです。ということでテキストエリアの部分を、最初の頃のように「div」でマークし、作成したタグを「.innerHTML」で挿入する方法に戻します。
<textarea name="dataDisplay" id="dataDisplay" rows="20" cols="75"></textarea>
↓
<div id="dataDisplay"></div>
もう一つ設定があります。今回新たに「design.css」というデザイン専用のファイルを作ったので、htmlに読み込むため「headタグ」の中に1行加えます。
<link href="design.css" rel="stylesheet" type="text/css">
次はCSS側の中を見てみましょう。CSSも奥が深くCSSだけで1冊の本になるほどです。しかしここでやっていることは単純で、「body」でブラウザの背景色を設定し、「#selectPref」で選択ボックスの横幅を設定しています。「#」の後は選択ボックスに付けたidと同じにします。
body {
background-color: #ccff99;
}
#selectPref {
width: 300px;
}
背景色や横幅は好きなように変更してください。背景色はRGB(左から2桁ごとに赤緑青に対応)をあらわしています。「px」(ピクセル)は単位です。
デザインをCSSにまとめておくことでhtmlがシンプルになり、htmlが数百ページあっても一度にデザインを変更できるメリットがあります。
ちなみにCSSをはずした時には以下のようなデザインです。選択ボックスの横幅が狭くて見にくいですよね。そのためCSSを設定していたのです。背景色の変更はおまけです。
次はJavaScript側の変更点です。選択ボックスの表示は関数dataDisplay()を変更するだけで済みます。
function dataDisplay() {
省略
var tempHtml = "<select size=\"25\" name=\"selectPref\" id=\"selectPref\">\n";
while (!recordSet.EOF){
tempHtml = tempHtml + "\t<option value=\"" + recordSet(0) + "\">" + recordSet(1) + "</option>\n";
recordSet.MoveNext();
}
tempHtml = tempHtml + "</select>";
alert(tempHtml);
document.getElementById("dataDisplay").innerHTML = tempHtml;
document.getElementById("selectPref").onchange = function (){prefChange(this);}
省略
}
選択ボックスの基本形は以下のようになります。
<select size="25" name="selectPref" id="selectPref">
<option value="1">北海道</option>
.
.
.
</select>
まず変数tempHtmlに<select>の部分を文字列として代入します。注意点は変数に文字列を代入する場合、文字列中の「"」ダブルクォーテーションは「\"」としなければならないことです。「'」を使う方法もありますが統一したほうがわかりやすいです。続いてwhile(){}のカッコ内でデータがあるだけoptionを作ってつなげています。
最後に</select>をつなげて完成です。
sizeは選択ボックスが一度に表示するレコード数です。省略すると以下のよう1レコードだけしか表示されません。(これはこれで使い道がありますが・・・)
「\t」や「\n」はプログラムで作成した選択ボックスのタグを、アラートで確認しやすくするためで、省略すると以下のようになります。
確認のため作ったタグをアラートで表示しています。
alert(tempHtml);
選択ボックスを画面に表示しています。
document.getElementById("dataDisplay").innerHTML = tempHtml;
選択ボックスの値が変化した時(onchange)、関数prefChange()をthisを引数に呼び出す設定です。thisは選択ボックス自身の参照です。
document.getElementById("selectPref").onchange = function (){prefChange(this);}
*ここで重要なのは、選択ボックスを表示した後でないとイベント処理の設定ができないということです。そのため関数init()に書くとエラーになります。
関数prefChange()のobjには選択ボックスの参照が入っています。この関数は選択ボックスで選択したデータをテキストボックスに表示しているだけです。
function prefChange(obj) {
txtPrefCd.value = obj.value;
txtPrefName.value = obj.options[obj.selectedIndex].text;
document.getElementById("sqlDisplay").innerHTML = "<p>selectedIndex:" + obj.selectedIndex + " value:" + obj.value + "</p>";
}
選択ボックスのvalueの値を取り出すのは簡単ですが、テキストを取り出すのは少し手順が必要です。
北海道の例でいうと「1」が代入されます。
txtPrefCd.value = obj.value;
「北海道」というテキストが代入されます。
txtPrefName.value = obj.options[obj.selectedIndex].text;
selectedIndexは選択ボックスの何番目かを示していましたね。(0から始まる)このように「何番目のオプションのテキスト」と明確に指示しないといけないのです。
最後の1行は確認のため表示しているだけですので、コメントにするか削除してもかまいません。
document.getElementById("sqlDisplay").innerHTML = "<p>selectedIndex:" + obj.selectedIndex + " value:" + obj.value + "</p>";
ついでに「最大値」のテキストリンクをクリックした時の動作を少し変えました。最大値をクリックするのは新しいレコードを追加するときですから、PREF_CDに最大値を入力した後は、PREF_NAMEを空にすることにしました。
function maxCd(){
省略
txtPrefName.value = "";
省略
}
以上で一覧から選択したデータを、テキストボックスに入力できるようになりました。少しずつシステムを改良していけるところがプログラミングの楽しさです。