Prototype.js/Ajax

どうも、サーバのCSVを集計して表示するWEBアプリを作んなきゃいけなくなりそうで、良い機会なので Prototype.jsAjax のお勉強。


今年初めに新婚旅行で行ったアイスランドでは、Ajaxとはガラスクリーナーのことだった。


以下習作のプログラム。


実行するシナリオは、
1.ブラウザで total.html を表示する。
2.total.html の「集計」ボタンをクリックする(とサーバの total.asp が実行される)。
3.total.asp はデータは集計して、その結果を xml で出力する。
4.total.html は受け取った xml データをhtmlのテーブルにして画面に表示する。


まあ、このケースだとAjaxである必要性は全く無いのだけどそこはそれ。


集計するデータはコレ
D:\Work\list.csv


1,34,78
2,94,86
3,24,65
4,56,8
5,78,78
6,23,89
7,67,36
8,13,78
9,88,98
10,54,100


データを集計して、xml で返す ASP がコレ
/total.asp


<?xml version="1.0"?>
<% response.ContentType="text/xml" %>
<total>
<%
set fso = CreateObject("Scripting.FileSystemObject")
set f = fso.OpenTextFile("D:\work\list.csv")
is_first_line = true
cnt = 0
dim sum()
dim max()
dim min()
do while not f.AtEndOfStream
l = f.ReadLine()
r = split(l, ",")
if is_first_line = true then
redim sum(ubound(r))
redim max(ubound(r))
redim min(ubound(r))
for i = 0 to ubound(r)
sum(i) = 0.0
max(i) = -1.79769313486231E308
min(i) = 1.79769313486231E308
next
is_first_line = false
end if
cnt = cnt + 1
for i = 0 to ubound(r)
d = cdbl(r(i))
sum(i) = sum(i) + d
if d > max(i) then max(i) = d
if d < min(i) then min(i) = d
next
loop
f.Close()
%>
<cnt><%=cnt%></cnt>
<%
for i = 0 to ubound(sum)
response.write "<record>"
response.write "<avg>" + cstr(sum(i)/cnt) + "</avg>"
response.write "<max>" + cstr(max(i)) + "</max>"
response.write "<min>" + cstr(min(i)) + "</min>"
response.write "</record>" + vbLf
next
%>
</total>


ボタンと、集計結果を表示するロジックの入った html がコレ。
/total.html


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Prototype.jsAjax習作</title>
<style type="text/css">
#panel1 {
background-color: #ddeeff;
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
}
</style>
<script src="prototype-1.4.0.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
function total() {
new Ajax.Request('total.asp', { method: 'get', onComplete: update });
}
function update(req) {
r = req.responseXML;
t = '集計結果(レコード数:'
+ r.getElementsByTagName('cnt')[0].firstChild.nodeValue + ")<br/>";
t += '<table border="1" bgcolor="#FFFFFF">'
t += '<tr><th bgcolor="#CCCCCC">avg</th>'
$A(r.getElementsByTagName('avg')).each(function(r) {
t += '<td>' + r.firstChild.nodeValue + '</td>'
});
t += '</tr>'
t += '<tr><th bgcolor="#CCCCCC">min</th>'
$A(r.getElementsByTagName('min')).each(function(r) {
t += '<td>' + r.firstChild.nodeValue + '</td>'
});
t += '</tr>'
t += '<tr><th bgcolor="#CCCCCC">max</th>'
$A(r.getElementsByTagName('max')).each(function(r) {
t += '<td>' + r.firstChild.nodeValue + '</td>'
});
t += '</tr>'
t += '</table>'
$(panel1).innerHTML = t;
}
</script>
</head>

<html>
<body bgcolor="#ffffff">
<input type="button" id="button1" onclick="total();" value="集計"/><br/>
<div id="panel1"></div>
</body>
</html>


実行結果はこんな感じ。


以下雑感。

total.asp の2行目にある ContentType="text/xml" が1行目に書かれていると正しく動作しない上に一見何が悪いのかさっぱり判らないので嵌る。そんな罠に引っかかって4時間あーでもないこーでもないと無為に過ごしたバッドノウハウをゲット。

しかし世の中のWEBプログラマは良くこんなん使う気になるな・・