同一テーブルでプロパティ項目を変更して永続化

[4]クライアント側のプログラム
リスト2は、Webクライアント側のプログラムです。図3から図5の画面表示を行い、リスト1で示したビーンズに対して登録データを送信します。
リスト2: addItem.htm
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8>
<title>商品マスタ登録</title>
<link type="text/css" rel="stylesheet" href="/csslib/style.css"/>
<script type="text/javascript" src="/dwr/interface/itemBean.js"></script>
<script type="text/javascript" src="/dwr/engine.js"></script>
<script type="text/javascript" src="/dwr/util.js"></script>
<script type="text/javascript" src="/jslib/jquery-1.4.2.min.js"></script>
<script type="text/javascript">
//<![CDATA[
window.resizeTo(380,530);
window.moveTo(10,10);
var kind = "desktop";
var query = {};
$(function(){
$("#type").val("デスクトップPC");
$("#kind").click(function(e){ //(1)
var stitle ="", spectag ="";
kind=e.target.id;
if(kind=="desktop"){
stitle ="デスクトップPC";
spectag = '<table width="330" border="1" bgcolor="#eeeeee">'
+ '<tr><th width="100">CPU</th>'
+ '<td><input type="text" size="30" id="cpu"/></td></tr>'
+ '<tr><th>メモリ</th><td><input type="text" id="memory"/></td></tr>'
+ '<tr><th>OS</th><td><input type="text" id="os"/></td></tr>'
+ '<tr><th>ステータス</th><td id="status"></td></tr></table>';
}else if(kind=="display"){
stitle ="液晶ディスプレイ";
spectag = '<table width="330" border="1" bgcolor="#eeeeee">'
+ '<tr><th width="100">サイズ</th>'
+ '<td><input type="text" size="30" id="size"/></td></tr>'
+ '<tr><th>ステータス</th><td id="status"></td></tr></table>';
}else if(kind=="printer"){
stitle ="プリンタ";
spectag = '<table width="330" border="1" bgcolor="#eeeeee">'
+ '<tr><th width="100">用紙サイズ</th>'
+ '<td><input type="text" id="papersize"/></td></tr>'
+ '<tr><th>解像度</th>'
+ '<td><input type="text" id="resolution"/></td></tr>'
+ '<tr><th>ステータス</th><td id="status"></td></tr></table>';
}else{
spectag = '<table width="330" border="1" bgcolor="#eeeeee">'
+ '<tr><th colspan="2">選択エラー</th></tr>'
+ '</table>';
}
$("#stitle").text(stitle);
$("#type").val(stitle);
$("#spec").html(spectag);
});
$("#add").click(function(e){ //(2)
query["kind"]=kind;
query["itemNo"]=$("#itemNo").val();
query["type"]=$("#type").val();
query["itemName"]=$("#itemName").val();
query["price"]=$("#price").val();
if(kind=="desktop"){
query["cpu"]=$("#cpu").val();
query["memory"]=$("#memory").val();
query["os"]=$("#os").val();
}else if(kind=="display"){
query["size"]=$("#size").val();
}else if(kind=="printer"){
query["papersize"]=$("#papersize").val();
query["resolution"]=$("#resolution").val();
}
itemBean.addItem(query, function(stat){ //(3)
$("#status").text(stat);
clear();
});
});
});
function clear(){ //(4)
$.each(["itemNo", "type", "itemName", "price"], function(){
$("#" + this).val("");
});
$("#itemNo").focus();
}
//]]>
</script>
</head>
<body bgcolor="#cccccc">
<h2 style="color: #aa0022">コンピュータ商品登録
<input type="button" id="add" value=" 登録 "/>
</h2>
<div id="kind">
<input type="radio" name="pc" id="desktop" checked="checked"/>デスクトップPC
<input type="radio" name="pc" id="display" />液晶ディスプレイ
<input type="radio" name="pc" id="printer" />プリンタ
</div>
<table width="330" border="1" bgcolor="#eeeeee">
<tr><th id="stitle" colspan="2">デスクトップPC</th></tr>
<tr>
<th width="100">製品番号</th>
<td><input type="text" size="12" id="itemNo"/></td>
</tr>
<tr><th>タイプ</th><td><input type="text" id="type"/></td></tr>
<tr><th>製品名</th><td><input type="text" size="28" id="itemName"/></td></tr>
<tr><th>価格</th><td><input type="text" size="10" id="price"/></td></tr>
</table>
<nobr id="spec">
<table width="330" border="1" bgcolor="#eeeeee">
<tr><th width="100">CPU</th><td><input type="text" id="cpu"/></td></tr>
<tr><th>メモリ</th><td><input type="text" id="memory"/></td></tr>
<tr><th>OS</th><td><input type="text" id="os"/></td></tr>
<tr><th>ステータス</th><td id="status"></td></tr>
</table>
</nobr>
</body>
</html>
このクライアント・プログラムでは、jQueryとDWRの非同期通信メソッドを使用して、サーバーに登録データを送信しています。この連載は、Low-Level APIでのデータ・ストア・アクセスがテーマなので、ここではポイントだけを解説します。
[クライアント側のプログラム処理]
リスト2の(1)は、画面上部のラジオ・ボタン・クリックで製品種別を選択したときに起動される、匿名関数です。e.target.id;で取得されるkindを使用し、基本項目の下に表示されます。選択項目を、図3(b、c)のように、動的に変更表示します。
リスト2の(2)は、「登録」ボタンをクリックしたときに起動される、匿名関数処理です。ここでは、連想配列のqueryに、画面入力データをセットしています。製品種別によって登録項目が異なるため、if文による判断で登録内容を判別しながら処理を行います。queryへのデータ・セットがすべて完了すると、(3)の非同期通信処理に移ります。
リスト2の(3)のように、クライアント側のJavascript処理は、全体としてはjQueryを使用した内容になっています。しかし、サーバーとの非同期通信処理については、DWRのクラス・メソッドを用いた処理内容になっています*4。
- [*4] 非同期通信には、jQueryの$.postなどを使用することもできます。しかし、この場合は、サーバー側でサーブレットを記述する必要があります。もっとも、ユーザー記述のサーブレットを使用する場合でも、サーバー・サイドでDWRデバッグ機能を利用できます。
DWRの非同期通信処理は、大変シンプルです。サーバー側で稼働するitemBeanのaddItemメソッドをそのまま呼び出す形式で記述すればよく、この場合、引数としては、永続化データがセットされている連想配列のqueryを指定するだけです。サーバー側での永続化処理の完了後にクライアント側にステータス情報が返されると、第2引数の匿名関数が起動され、ステータス表示が行われます。
[永続化データの管理画面表示]
最後に、このサンプルのように、異なるプロパティ項目を含むエンティティが登録された場合、App Engineの管理者画面(Datastore Viewer)から参照すると、どのように表示されるのかを確認してみます。
| 図6: 登録後のエンティティ表示(クリックで拡大) |
図6は、このサンプルで登録されたエンティティ項目を、管理者画面で確認した内容です。itemMasテーブルにはエンティティが3つ登録されていますが、それぞれ登録されているプロパティ項目が違います。各登録処理でプロパティ名に対応する値がない場合は"



