タブ区切りテキストを表示する

 第三章ではデータを解析し表示します。まず、手軽に扱えるタブ区切りテキストファイルをページに表示してみましょう。
タブ区切りテキストはデータとデータの間がタブコード(ASCコード9番)で区切られています。この形式のデータはテキストエディタでも作成できますし、Excelなどのデータベースソフトでも出力することができます。ここではExcelで作成したデータ (sample.xls) をUTF-8 (BOM [Byte Order Mark]付き) に文字コードを変換したファイル (sample.txt) を使用します。改行コードはLF (Line Feed : ASCコード10番)にしてあります。
 まず、従来通りデータをサーバーから読み込みます。テキストデータなのでresponseTextでデータを受け取ります。この読み込んだデータを改行コード (LF) で行単位に分けます。分ける前に改行コードを変数に入れておくと楽になります。これは以下のように指定します。

var LF = String.fromCharCode(10);

 行単位にするにはsplit()を使います。split()を使えば改行コード単位で分割された結果が配列として返されます。以下のようにすると行単位に分割され配列変数としてlineDataに格納されます。

lineData = tabText.split(LF);

行単位に分割できたら次にタブコードでデータを切り分けます。まず、タブコードを変数に入れておきます。これは以下のようになります。

var TAB = String.fromCharCode(9);

 データ単位に分割するには、やはりsplit()を使って以下のようにします。

wCount = lineData[i].split(TAB);

 これで変数wCountにデータが配列として格納されます。あとは、データの数だけ繰り返せばタブ区切りテキストの内容を表示することができます。実際のサンプルは以下のようになります。(サンプルを実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>タブ区切りテキストを表示する</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function loadDataFile(fName)
{
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET",fName,true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
$("result").innerHTML = parseTabText(httpObj.responseText);
}else{
$("result").innerHTML = "<b>Loading...</b>";
}
}
// タブ区切りテキストを解析して表示
function parseTabText(tabText)
{
var resultText = "<table border='1' cellspacing='0'>";
var LF = String.fromCharCode(10); // 改行コード (LF)
var TAB = String.fromCharCode(9); // タブコード
lineData = tabText.split(LF);
for (var i=0; i<lineData.length; i++)
{
wCount = lineData[i].split(TAB);
resultText += "<tr>";
for (j=0; j<wCount.length; j++)
{
tData = wCount[j]; // データ
resultText += "<td>"+tData + "</td>";
}
resultText += "</tr>";
}
resultText += "</table>";
return resultText;
}
// --></script>
</head>
<body>
<h1>タブ区切りテキストを表示する</h1>
<p>タブ区切りテキストを読み込み表示します</p>
<form name="ajaxForm">
<input type="button" value="sample.txtファイルを読み込み" onClick="loadDataFile('sample.txt')"><br>
</form>
<div id="result"></div>
</body>
</html>

 タブ区切りテキストの処理は簡単ですが、上記のようなスクリプトの場合、プログラムとデータが分離されていないため後々、問題になることがあります。この問題というのは、表示する際の横幅や背景色などを変更する際に発生します。レイアウトデザインはデザイナーが行うはずですが、その修正作業はプログラマでないとできないということになります。逆にプログラマは出力する結果=レイアウトデザインを知らなければなりません。つまり、相互に大きく依存してしまうことになります。常に社内で共同作業であれば問題も軽減されるかもしれませんが、デザイナーが変わったりプログラマが失踪したりしてしまうと困ったことになります。つまり、なるべくデータとデザインは分離されておくのが後々のためには好ましいということです。
 ただ、現実的にはAjaxではブラウザ依存の部分が大きく、うまくいかない事もあります。とりあえず動く事が重要ですが、一応後々のことも考慮してプログラムを作成しておくと良いでしょう。
 では、上記のプログラムをなるべくデザインに依存しないように書き換えてみましょう。まず、ページ内に出力するテーブルのタグなどを記述しておきます。必要に応じてスタイルシートで背景色や文字サイズなどを指定します(以下のサンプルではスタイルシートは使っていません)。
 まず、HTMLタグで文書レイアウト(構造)を決めておきます。ここではテーブルタグの<tr>〜<tr>で囲まれた部分を複製して利用することにします。テーブルタグ内のtrタグで囲まれた範囲が一行になりますが、この一行部分を複製するためにidを指定しておきます。このtrタグを以下のようにgetElementById()を使って指定します。

var listSourceObj = document.getElementById("priceList");

この一行のデータを複製するにはcloneNode()を使います。引数(パラメータ)はtrueまたはfalseになります。trueを指定すると内包される子要素も複製されます。tdタグも複製するので以下のようにtrueを指定すると一行を複製することができます。

listSourceObj.cloneNode(true);

 複製するとIDまで複製されてしまいます。IDが重複するとプログラムから正常にアクセスできなくなってしまうので以下のようにidプロパティに別のIDを設定します。

trObj.id = "priceList"+i;

 これで行が複製され準備ができました。あとはtdタグ内にデータを表示するだけです。trタグ内にあるtdタグを参照するにはgetElementsByTagName()を利用します。これでtdタグへの参照が配列変数として返されます。これは以下のようになります。

tdObj = trObj.getElementsByTagName("td");

あとはinnerHTMLプロパティに表示するデータを設定します。innerTextではSafariやOperaではデータが表示されますがFirefoxでは表示されません。実際のプログラムは以下のようになります。ただし、Internet Explorer 6では内容が表示されません(サンプルを実行する。innerTextを使ったサンプル(Firefoxでは動かない。innerTextをtextContentに変更するとFirefoxでも動作する)を実行する

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>タブ区切りテキストを表示する2</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function loadDataFile(fName)
{
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET",fName,true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
parseTabText(httpObj.responseText);
}
if ((httpObj.readyState == 4) && (httpObj.status == 404))
{
alert("Error!");
}
}
// タブ区切りテキストを解析して表示
function parseTabText(tabText)
{
// 商品コードと名前、価格を表示させる行のタグIDを取得
var listSourceObj = document.getElementById("priceList");
var listTableObj = document.getElementById("priceTable");
var LF = String.fromCharCode(10); // 改行コード (LF)
var TAB = String.fromCharCode(9); // タブコード
lineData = tabText.split(LF);
for (var i=0; i<lineData.length; i++)
{
wCount = lineData[i].split(TAB);
trObj = listSourceObj.cloneNode(true);
trObj.id = "priceList"+i;
tdObj = trObj.getElementsByTagName("td");
for (j=0; j<wCount.length; j++)
{
tData = wCount[j]; // データ
tdObj[j].innerHTML = tData;
}
listTableObj.appendChild(trObj);
}
}
// --></script>
</head>
<body>
<h1>タブ区切りテキストを表示する2</h1>
<p>タブ区切りテキストを読み込み表示します</p>
<form name="ajaxForm">
<input type="button" value="sample.txtファイルを読み込み" onClick="loadDataFile('sample.txt')"><br>
</form>
<table id="priceTable" border="1">
<tr id="priceList"><td>コード</td><td>商品名</td><td>価格</td></tr>
</table>
</body>
</html>

 上記サンプルはInternet Explorer 6では動作しないので、Internet Explorer 6の場合にはdiv, spanタグを利用するか、tbodyタグにidを指定したサンプルに変更する必要があります。以下が実際のサンプルになります。なお、変更点は赤色で指定してあります。また、スタイルシートでレイアウトを指定しています。(div, spanのサンプルを実行する、tbodyにidを指定した場合のサンプルを実行する

■div, spanタグを利用した場合のスクリプト
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>タブ区切りテキストを表示する(IE)</title>
<link rel="stylesheet" href="main.css" type="text/css" media="all">
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function loadDataFile(fName)
{
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET",fName,true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
parseTabText(httpObj.responseText);
}
if ((httpObj.readyState == 4) && (httpObj.status == 404))
{
alert("Error!");
}
}
// タブ区切りテキストを解析して表示
function parseTabText(tabText)
{
// 商品コードと名前、価格を表示させる行のタグIDを取得
var listSourceObj = document.getElementById("priceList");
var listTableObj = document.getElementById("priceTable");
var LF = String.fromCharCode(10); // 改行コード (LF)
var TAB = String.fromCharCode(9); // タブコード
lineData = tabText.split(LF);
for (var i=0; i<lineData.length; i++)
{
wCount = lineData[i].split(TAB);
trObj = listSourceObj.cloneNode(true);
trObj.id = "priceList"+i;
tdObj = trObj.getElementsByTagName("span");
for (j=0; j<wCount.length; j++)
{
tData = wCount[j]; // データ
tdObj[j].innerHTML = tData;
}
listTableObj.appendChild(trObj);
}
}
// --></script>
</head>
<body>
<h1>タブ区切りテキストを表示する(IE)</h1>
<p>タブ区切りテキストを読み込み表示します</p>
<form name="ajaxForm">
<input type="button" value="sample.txtファイルを読み込み" onClick="loadDataFile('sample.txt')"><br>
</form>
<div id="priceTable">
<div id="priceList">
<span class="itemCode"></span><span class="itemName"></span><span class="itemPrice"></span>
</div>
</div>
</body>
</html>



■tbodyにidを指定した場合のサンプル
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>タブ区切りテキストを表示する(IE6)</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function loadDataFile(fName)
{
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET",fName,true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
parseTabText(httpObj.responseText);
}
if ((httpObj.readyState == 4) && (httpObj.status == 404))
{
alert("Error!");
}
}
// タブ区切りテキストを解析して表示
function parseTabText(tabText)
{
// 商品コードと名前、価格を表示させる行のタグIDを取得
var listSourceObj = document.getElementById("priceList");
var listTableObj = document.getElementById("priceTable");
var LF = String.fromCharCode(10); // 改行コード (LF)
var TAB = String.fromCharCode(9); // タブコード
lineData = tabText.split(LF);
for (var i=0; i<lineData.length; i++)
{
wCount = lineData[i].split(TAB);
trObj = listSourceObj.cloneNode(true);
trObj.id = "priceList"+i;
tdObj = trObj.getElementsByTagName("td");
for (j=0; j<wCount.length; j++)
{
tData = wCount[j]; // データ
tdObj[j].innerHTML = tData;
}
listTableObj.appendChild(trObj);
}
}
// --></script>
</head>
<body>
<h1>タブ区切りテキストを表示する(IE6)</h1>
<p>タブ区切りテキストを読み込み表示します</p>
<form name="ajaxForm">
<input type="button" value="sample.txtファイルを読み込み" onClick="loadDataFile('sample.txt')"><br>
</form>
<table border="1">
<tbody id="priceTable" border="1">
<tr id="priceList"><td>コード</td><td>商品名</td><td>価格</td></tr>
</tbody>
</table>
</body>
</html>

 このような手法以外に、レイアウト内にどのデータを表示するかを指定しておくものもあります。
 次項ではCSV形式のデータを読み込んで表示させてみます。

[第三章 2:CSVデータを表示するへ]
[目次へ]

(2006.1.1, 2006.1.11追加修正, 2006.2.24追加修正)