先のエントリー
AJAX で、動的にテーブルを作る方法(初級)では、感じをつかむために、ベタにテーブルを作成していたため、重複するロジック/コードが多かった。ここではそれをフレームワークっぽくした。こういう軽量なコードを理解した上で、ひな型として自分で持っておくと見通しがよくてよいと思う。
この JavaScript ではできるだけ Java のアプレットにならった構造やメソッド名に近づけた。つまり、
- 基本メソッドは、
- createXMLHttp …xmlhttp オブジェクトを作成する。
- get …サーバと HTTP 通信する。
- repaint …サーバから来た XML データを使って画面を書き換える。
- create …最初の1回だけ画面を作る。
- init …この JavaScript の呼び出しもとの HTML から呼ばれる。
- setTemplate …サーバから得られた XML データが表示される部分を作成する。下の例を元にカスタマイズする。
- update …サーバから得られた XML データを setTemplate で作成した id に埋め込む。下の例を元にカスタマイズする
- 基本プロパティは定数の場合はすべて大文字で表し、配列には英単語の複数形「s」を付けることにした。
- INTERVAL …AJAX での通信間隔(ミリ秒)
- OBJECT …XML データ中で、たとえば ~ イテレーションの中の タグ。その場合は OBJECT = 'book'; と、タグ名を指定する。
- TAGS(配列) …たとえば、book タグに含まれる要素である title、author、publisher タグ
- LABELS(配列) …テーブルのヘッダのカラムで表示したい内容
- TH_ALIGNS(配列) …テーブルで、左から順に各カラム中のヘッダの位置
- TD_ALIGNS(配列) …テーブルで、左から順に各カラム中のデータ位置
- URL …AJAX で通信する URL
- こうすると自分で実装(カスタマイズ)する部分、すなわちメソッドは
- setTemplate …テーブルの元となるテンプレート HTML を吐くようにする。
- update …INTERVAL 間隔で呼び出され、テーブルのデータを更新するようにする。
…の 2つだけでよい。
以下はこのスクリプトを呼び出す HTML 部分の例。
2007/01/10 追記:
IE では、DIVタグに付けた ID を JavaScript から利用する場合は、JavaScript の前に DIV を宣言しなければならないらしい。document.getElementByID(...) is null or not an object というエラーが出る。Firefox だとその順番は関係がない。
また、document.getElementByID(DIV_DATA).insertBefore(table, null); は、IE だと table オブジェクトに tbody オブジェクトを追加してからでないとダメらしい。
<div id="data"></div>
<script src="https://<font color="red"><strong>your</strong></font>domain.com/your_javascript.js" type="text/javascript">
</script>
<script type="text/javascript"><!--
var INTERVAL = 4000; // 1sec = 1000
var OBJECT = 'TAG';
var TAGS = new Array('title', 'author', 'publisher');
var LABELS = new Array('Title', 'Author', 'Publisher');
var TH_ALIGNS = new Array('center', 'center', 'center');
var TD_ALIGNS = new Array('left', 'center', 'right'); // テーブルデータの各カラム中の位置
var URL = 'https://<font color="red"><strong>your</strong></font>domain.com/your_server_process.php';
var DIV_DATA = 'data';
init();
// --></script>
動的なテーブルを作る、よりジェネリックな JavaScript は次の通り。このフレームワークでは setTemplate には何を書いてもよいが、ここでは table オブジェクトを作成することにより、HTML 中で id="data" に埋め込まれる部分にテーブルを当てはめている。また、テーブルを作成すると同時に各カラムに id="タグ名+数字" として、後に update メソッドで XML から抽出したデータを当てはめている。
//<![CDATA[
var isInitialized = false;
var isLock = false;
function createXMLHttp() {
try {
return new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
try {
return new ActiveXObject('Microsoft.XMLHTTP');
} catch(e1) {
try {
return new XMLHttpRequest();
} catch(e2) {
return null;
}
}
}
}
function create(xml) {
isLock = true;
setTemplate(xml);
update(xml);
isLock = false;
}
function init() {
get(URL);
setInterval("get('" + URL + "')", INTERVAL);
}
function repaint(xml) {
!isInitialized ? create(xml) : update(xml);
}
function get(url) {
if(isLock) return;
var xmlhttp = null;
if ((xmlhttp = createXMLHttp()) == null) {
window.alert("XMLHTTP Initialization Failed.");
} else {
xmlhttp.abort();
}
xmlhttp.onreadystatechange = function() {
// readyState value
// 0: uninitialized / 1: loading
// 2: loaded / 3: interactive / 4: complete
if (xmlhttp.readyState == 4
&& xmlhttp.status == 200) { // 200 HTTP OK
xml = xmlhttp.responseXML;
repaint(xml);
}
}
xmlhttp.open('GET', url + '&t=' + new Date(), true); // for avoiding IE's cache
xmlhttp.setRequestHeader('Content-Type', 'text/html');
xmlhttp.overrideMimeType('text/xml'); // optional
xmlhttp.send(null);
}
function update(xml) {
if(xml) {
if(xml.documentElement) { // for IE
var objects = xml.documentElement.getElementsByTagName(OBJECT);
for (var i = 0; i < objects.length; i++) {
for (var j = 0; j < LABELS.length; j++) {
var value = null;
try {
value = objects[i]
.getElementsByTagName(TAGS[j])
.item(0)
.firstChild
.nodeValue;
} catch(e) {
}
switch(TAGS[j]) {
case 'title': // for example...
value = '<strong>' + value + '</strong>';
break;
case 'author': // for example...
case 'date':
value = value ? value : 'n/a';
break;
}
document.getElementById(LABELS[j] + i).innerHTML = value;
} // End of for j
} // End of for i
}
}
}
function setTemplate(xml) {
if(xml) {
if(xml.documentElement) { // for IE
var objects = xml.documentElement.getElementsByTagName(OBJECT);
var table = document.createElement('table');
var tr, td, text;
for (var i = -1; i < objects.length; i++) {
tr = document.createElement('tr');
for (var j = 0; j < LABELS.length; j++) {
if(i < 0) { // ヘッダ
text = document.createTextNode(LABELS[j]);
td = document.createElement('th');
td.setAttribute('style', 'text-align:' + TH_ALIGNS[j] + ';');
td.setAttribute('valign', 'center');
} else {
text = document.createTextNode('');
td = document.createElement('td');
td.setAttribute('style', 'text-align:' + TD_ALIGNS[j] + ';');
td.setAttribute('valign', 'center');
}
td.insertBefore(text, null);
tr.insertBefore(td, null);
td.setAttribute('id', LABELS[j] + i);
}
table.insertBefore(tr, null);
} // End of for
document.getElementById(DIV_DATA).insertBefore(table, null);
isInitialized = true;
}
}
}
//]]>
トラックバック URL:
https://perltips.twinkle.cc/trackback/160