本文へジャンプ

ソフトウェア > Lotus > Lotus Developer Domain > 

Iris Today Archives

新しい Web 技術:ダイナミック HTML をドミノで利用する


Lotus Software
by Michael Patrick
レベル:上級者
対象:Designer R5
原文の掲載:2000年8月1日

Iris Today Archivesの原文(US)

インデックス
タブ付き表の動作を疑似的に実現する
1ページに複数のビューを埋め込む
これからが始まりです

次のような場面を想像してみてください。ユーザーの操作によって、要素が現れたり消えたりするような Web ページの設計をして欲しいと顧客が頼んできました。「おまかせください」とあなたは答えるでしょう。そして顧客は、自転車の車輪に棒切れを突っ込むような発言をします。「でも、新しくページ読み込まないようにしてください。新しいページを読みにいくと煩わしくなるからね。」このような場合2つの選択肢があります。1つは有無を言わさず 「あなたは何を言ってるのか自分で分かってないでしょう!」 と言い放つか (これはお勧めできませんが・・) 、もう1つはダイナミック HTML (DHTML) の剣を振りかざしてドラゴン (これは Web ページを指しており、決して顧客を指しているわけではありません) をやっつけるかのどちらかです。

もし Web の開発をしたことがあれば、既に DHTML について多少はご存知かもしれません。というのも DHTML は別に新しいものではなく、HTML や JavaScript や カスケード・スタイルシート、ブラウザーのドキュメント・オブジェクト・モデル (Document Object Model:DOM) がお互いに連係することによりコンテンツの動的な表現を得るというものです。

ご想像の通り、 DHTML は1つの記事では到底カバーできないぐらい大きなテーマです。この記事では、DHTML の可能性を紹介するために、ドミノでできることと、その範囲内で DHTML をどのように扱えばよいのかということについて考察します。まず最初に、タブを切り替えるたびにサーバーにアクセスせず、1つのフォームでタブ付きの表の動作を疑似的に実現するためのテクニックを紹介します(これは最初の段落で紹介した問題の解決法の1つになります)。 次に、埋め込みビューは各フォームについてたかだか1つしか用いることができない、というドミノの制約について紹介します。

ご注意:DHTML は、特に、対象となるブラウザーが不明な場合など、いかなる状況でも適用できるとは限りません。DHTML は複数の独立した仕様を基にしており、ブラウザーの開発元がそれらの仕様の中でどれを実装するかに大きく依存します。一般的に述べると、Netscape Navigator と Microsoft Internet Exploerer (IE) のバージョン 4.x は基本的な仕様はサポートしています。Internet Explorer 5 のであれば、さらに良いでしょう。また、最近リリースされた Navigator 6 であれば最も標準に近い実装を約束してくれるでしょう。

この記事の例は Microsoft Internet Explorer 4.x と Netscape Navigator 4.x で動作します。これらの例を収めたサンプル・データベース (DHTML.nsf ファイル) は Iris Sandbox から入手できるので、ダウンロードして実際に確認してみてください。この記事では HTML、JavaScript、スタイルシートの基本的な部分についてご理解されていると仮定して話を進めます。

タブ付き表の動作を疑似的に実現する
ノーツ R5 の特長の1つに、見栄えがよく柔軟性のあるタブ付き表があります。これは簡単に入れ子にすることができます。

しかしドミノで利用していたタブ付き表を Web ブラウザーで利用しようとすると問題があります。これはタブをクリックするたびに新しいページをサーバーまで読み込みに行くというものです。不幸なことに、このようなことはクリック回数や待ち時間が多くなることになり、また言うまでもないのですが、ページを移動することによりデータを損失したり、サーバーに負荷を与えることにもつながります。

DHTML を用いてこの問題を回避することができます。フォーム内のさまざまな要素間の関係について多少の注意点はありますが、一度基本的な部分を理解すると後は苦労することはないでしょう。

メモ:以下では、文書の編集についての例を示していますが、タブ付き表は読み込み専用のデータをユーザーに示す場合のみ適用することができます。これはしっかりと覚えておいてください。というのも、Netscape Navigator 4.x では FORM タグは基本的に DIV タグに挟まれているものと認識します。以下の例では、Netscape Navigator 4.x で完全には扱えない先進的な機能を利用しています。そのため、このタブ付き表の例は、文書を読むだけなら Navigator 4.x でもきちんと動作しますが、内容を編集する場合はうまく動作しません。

最初に、これから何をしようとしているのかを確認しておきましょう。Internet Explorer ではタブ付きの表 フォームを以下のように表示します。

Tabbed Table form-guitars

Guitars (ギター) と Basses (ベース) と Drums (ドラム) の3つはタブを表しているリンクです。そして現在のタブ (この場合 Guitar タブです) は3つのタブの下に走っている線の色から分かります。3つのタブにはそれぞれ独自のフィールドがあり、それらは文書の一部分で、文書が送信される (Submit ボタンが押される) と保存されます。他のタブをクリックした場合、たとえば Drums タブをクリックすると Guitars タブのフィールドは隠れて Drums タブのフィールドが現れます。

Tabbed Table form-drums

タブ付きの表 フォームで用いられているカスケード・スタイルシートと JavaScript
タブは実際にはどのような構成になっているかを調べる前に、タブを実現させている舞台裏の技術を見てみましょう。まず最初の興味の対象として、フォームのカスケード・スタイルシートを見てみましょう。

カスケード・スタイルシート(CSS, Cascading Style Sheets)を用いることにより内容そのものと、内容の表現方法とを分離できると考えることができます。内容をどのように表現したり振舞わせたりするかは、スタイルシートを用いると1ヵ所に記述するだけで済みますが、スタイルシートが登場する以前は、その正反対に、内容ごとに記述する必要がありました。

簡略化のために、例やサンプル・データベースのスタイルシートの記述は直接フォームに埋め込んであります。このような方法は、そのスタイルシートがたかだか1つのフォームや文書でしか用いられない場合は便利な方法ですが、1つのスタイルシートを複数のフォームや文書で用いたい場合はどうすればよいのでしょうか?スタイルシートには優れた柔軟性があり、リンクすることができます。これはどういうことかというと、フォームには必要があればスタイルシートを参照するように記述することができます。またこの場合、スタイルシート自身の記述は別のファイルにあるということになります。詳細は、「スタイルシートをリンクする」 をご覧下さい。

以下のコードでは、Tabbed Table フォームの HTML Head Content にスタイルシートを埋め込んでいます。

"<STYLE type=\"text/css\">" +
"A.tabs { text-decoration: none};" +
"#tab1{position:absolute;top:40;left:10};" +
"#tab2{position:absolute;top:40;left:10; visibility:hidden};" +
"#tab3{position:absolute;top:40;left:10; visibility:hidden};" +
"</STYLE>"

まず、スタイルシートの内容は STYLE タグで囲まれていることが分かります。タグに囲まれた各行は、スタイルのルールを表しており、これにより HTML 文書の要素が修飾されます。最初のスタイルのルールは、各タブのリンクに下線が引かれないようにするためのものです。これは必ずしも必要というわけではありませんが、ここで説明しておくと分かりやすいので記述してあります。この行が意味しているところは、リンク (つまり、"A" は <A></A> リンクタグを指しています) は、tabs クラスに属しており、このクラスの text-decoration 属性を none に設定するということです。もう少し後で、これを実際に使った例を示します。

#tab で始まっている3つのルールによって、タブ自身の位置とタブを表示させるかさせないかを調整しています。このルールは各タブに1つずつあり、タブ数の増減に応じて変更しなければなりません。最初の属性は position で、この例では属性の値は absolute となっていますが、これはタブを画面上のどこに配置するかを正確に指定することができることを示しています。この例を見ると、各ルールで同じ値が用いられており、ブラウザーのウィンドウの上端から 40 ピクセル、左端から 10 ピクセルの位置に表示されることが分かります。これによって、タブを持つ表を望みどおりに重ねることができます。もし、各ルールで異なった値を用いれば、タブ付きの表は画面上のあちこちに表示されることになってしまいます。あなたはこれをイケてると思ってしまうかもしれませんが、顧客はきっとそうは思わないでしょう!

他の属性として visibility がありますが、フォームやページ上の要素は、標準で可視状態 (visible)なので、1番目のタブに対応している最初のルールでは特に属性を指定していません。2番目、3番目のタブは最初は非表示になるように指定しています。

フォームの JS Header にタブ付きの表のコードが書かれています。

var currtab = "tab1";

function showtab( tabnum ) {
tabname = "tab" + tabnum
if ( tabname != currtab ) {
if (window.document.layers) {
handle="window.document.layers";
stylevar="";
}else{
handle="document.all";
stylevar=".style";v }
eval(handle+'["'+currtab+'"]'+stylevar+'.visibility = "hidden"');
eval(handle+'["'+tabname+'"]'+stylevar+'.visibility = "visible"');
currtab = tabname;
}
}

最初に、デフォルトとして currtab 変数を tab1 に設定しています。この変数は現在どのタブを表示しているのかを保持するためのものです。次に showtab 関数を見てみます。この関数は、タブをクリックするたびに呼び出されます。そして、引数として、クリックされたタブの番号を受け取ります。そして、現在表示しているタブ以外のタブがクリックされたことが分かると、次に、どのブラウザーが用いられているのかを調べる必要があります。

Netscape Navigator には、ドキュメント・オブジェクト・モデル (DOM: Document Object Model) の中にレイヤー・オブジェクトがありますが、Internet Explorer にはありません。

if (window.document.layers)

そこで、このような簡単なコードを用いて、現在利用しているブラウザーがレイヤー・オブジェクトをサポートしているかを判別することができます。この例では、Netscape Navigator を使っている場合、handle 変数には "window.document.layers" がセットされ、Internet Explorer を使っている場合は、handle 変数には "document.all" が、stylevar 変数には ".style" がセットされます。

なぜブラウザーによって違いがあるのでしょうか?本質的に Netscape と Microsoft のドキュメント・オブジェクト・モデルはかなり異なっており、ページ上の要素を指定するというような場合は特に顕著になります。今回のコードでは、どちらのブラウザーを使っていても1つのコードで、クリックして新たに選択されたタブの visibility プロパティーを visible に設定し、それ以外のタブについては hidden と設定されるようにしています。最後に、currtab 変数に新たに選択されたタブを設定しています。

Tabbed Table フォーム
どのようにしてタブが作成されているのかを知るために、ドミノ・デザイナーでフォームを見てみましょう。」

Tabbed Table form in Designer

まず最初に気がつくことは、タブは表が連続したもので、各タブは1つの表に対応しているということです。図には2つしか表示されていませんが、3つ目の表は2つ目の表の下にあります。各タブに属するフィールドは表内に配置されています。上の例では、Guitars タブと Basses タブの両方に Make (製造元) フィールドと Strings (弦) フィールドがありますが、各フィールドにはそのタブに対応したそれぞれ固有の値が入っています。

1つ1つのタブの構成をじっくりと見ていきましょう。最初に、DIV タグに囲まれた2つの表 (タブの表とフィールドの表) があることが分かります。これはたとえば、"<DIV ID=tab1></DIV>" のように示されている部分で、ここはパススルー HTML の設定がされています。DIV 要素は複数の要素を論理的にグループ化するためのもので、それらをまとめて参照することができます。その前に、DIV に名前をつける必要があります。1番目の Guitars タブに示されているように、<DIV> タグには ID という属性があります。これは、tab1 という名前をつけることで、この部分を識別するためのものです。もしも後でフォームのスタイルシートを参照する場合 (これはフォームの HTML Head Content オブジェクトにあることを思い出してください)、tab1 というルールをつけたことに気がつくでしょう。そして、ルールは tab1 の部分に適用されて、その部分に含まれるものは絶対的な位置に配置されることになります。

各タブは表内のセルで、これらのセルの中身は以下のようなものになっています。

<DIV ALIGN=center><A CLASS="tabs" href="#"
onClick="javascript:showtab( 1 )">Guitars</A></DIV>

これはパススルー HTML として示されています。細かく分析すると、セルの中身もまた DIV タグで囲まれています。これは、DIV 要素の ALIGN 属性を "center" とすることにより、タブの中身をセンタリングするためのものです。各セルやタブ内のリンクには興味深いものがあります。リンクタグ <A> に注目してください。これには、CLASS="tabs" という属性があることが分かります。もう一度フォームのスタイルシートを参照すれば、これは、このクラスのリンクには下線を引かないという指定と一致することが分かります。当然のことですが、このフォーム上のリンクは tabs クラスに属さないので影響はありません。

また、リンクの一部として、JavaScript の関数を呼び出しています。これは、HREF の中で直接そのような呼び出しをするのを避けるための良い習慣と言えます。リンクを設定する場合 HREF が必ず必要となります。しかしながら、このような場合には HREF は何もするべきではないので、"#" で終結させます。その代わりに、フォーム内に設定された JavaScript の関数である showtab をリンクの onClick イベントから呼び出して、そのタブの値を渡すというようにしています。

この例に関して、最後に指摘すべきポイントがあります。タブ付きの表 フォームをブラウザーで表示した場合とドミノ・デザイナーで表示した場合とを比べると、最初のセルとタブがあり、タブの下に黄色いセルが伸びているのが確認できます。セルの高さはどのように指定されているのでしょうか?その答えは、R5 デザイナーには統合開発環境 (IDE) で作成された表を調節するためのオプションがありますが、これまでよりもさらに多くのオプションを提供しているということです。〔表〕プロパティー・ダイアログ・ボックスの最後のタブを見てください。

Table Properties diarog box

これを見ると、最初のタブである Guitars タブを制御するコードが書かれています。〔セルのHTMLタグ〕セクションの〔その他〕フィールドに、セルの背景色を指定する 16進数の値があります。(この例では、暗い黄色を表しています) 。これは、あらかじめ決められた色の値を用意するには手軽な手段になります。またセルの高さを 25 に指定しています。タブの下にあるセルは同じ色の値で、高さは 5 に設定されています。要するに、R5 デザイナーでは、好きなようにテーブルの見栄えを調節できるということです。

見た目には Tabbed Table フォームはごちゃごちゃしていますが、その多くが冗長なものだと分かれば、単純なものです。(ブラウザーでどのように動作するかを見るには、DHTML.nsf ファイルのサンプル・データベースにあるコードが利用できます)

この例から離れる前に2つのポイントを挙げておきます。

  • タブ付きの表は必ずしも HTML の表から作成する必要はありません。タブを画像にして、複数の画像を切り替える方法も使えます。ここでの例で HTML 表を利用した理由として、作成しやすいということと、複数の画像をダウンロードするよりも早くダウンロードできるということです。
  • ネストしたタブ付きの表とは何でしょう?このタブ付きの表の例を拡張したいと思った人のために、サンプル・データベースに Nested Tabbed Tables フォームを用意しました。これの相違点は、基本的な部分を分かっていれば明らかです。Nested Tabbed Tables フォームは Internet Explorer でしかうまく動作しません。

 
上に戻る
 
1ページに複数のビューを埋め込む
ノーツやドミノの専門家の期待とは裏腹に、Web ブラウザーのほうがノーツ・クライアントよりも優れている点があります。そのひとつに、複数のビューをサポートするアプレットに頼らずに、1つのページで複数のビューを表示できるというものがあります。ノーツ・クライアントでこのようなことができるでしょうか!以下の画面はこの様子を実際にあらわしています。

Two views embedded on a page

この例では、水平線の上部は、Basses ビューを表示し、水平線の下部では Guitars2 ビューを表示しています。必ずしもビューの数は2つに制限されているわけではありません。つまり、好きなだけ多くのビューを加えることができます。また、Basses と Drums のリンクが上部にあることに注目してください。Internet Explorer では、これらのリンクを押すとページを再読み込みすることなく実際にビューを切り替えます。たとえば、Basses ビューが表示されている場合、Drums のリンクをクリックすると上部のビューは Drums ビューに変わります。再び Basses ビューを表示するには、Basses リンクをクリックするだけです。(このようなスイッチとして機能するリンクは Netscape Navigator ではうまく動作しないので、Netscape Navigator で見るとこれらのリンクは表示されません。非表示にする方法は、後で紹介します)

どうやってこのようなことを実現しているのでしょうか?ドミノ・デザイナーで Multiple Embedded Views フォームを見てみましょう。

Multiple Embedded Views form in Designer

フォームの先頭に ThisDb フィールドがあります。これは、編集することはできますが、HTML Attributes が "Type=\"Hidden\"" と設定されているため非表示になっています。これにより、フィールドをブラウザーに隠しながらページのコードとして参照して利用することができます。このことは、フォームの JS Header 内に書かれたスクリプトを動作させる上で重要になってきます。ThisDb はデータベースのパスを計算するための式です。

@ReplaceSubstring (@Subset (@DbName; -1); "\\" : " "; "/" : "+")

Drums と Basses のリンクをちょっとスキップします、それに続くブロックはパススルー HTML としてマークされていて、フォームの上部にビューを埋め込むためのものです。

<<計算結果の値> ID=switchview height=200 width=750 scrolling="yes"
src="/<計算結果の値>/basses?openview">
</<計算結果の値>>

同様に、水平線 (<hr> タグのことです) の下部に Guitars2 ビューのためのコードがあります。

最初と最後の計算結果テキストの行で実際の動作を記述しており、以下のようになっています。

@If(@BrowserInfo( "BrowserType" ) ="Notes"; "IFRAME";
@BrowserInfo( "BrowserType") = "Microsoft"; "IFRAME frameborder=0";
@BrowserInfo( "BrowserType") = "Netscape"; "ILAYER";
"")

最初の行と最後の行との違いは、後者の計算結果テキストでは frameborder=0 というパラメータが省略されていることです。これは、閉じるタグに属性を記述しても意味がないからです。

ここでは一体何をしているのでしょうか?この部分のコードでは IFRAME や ILAYER を持ち出しています。これによりブラウザーの種類に応じて、ウィンドウやフレームを作成します。作成されたウィンドウやフレームは、元のページとは関係なく独自の内容を持つことができます。最初のほうで述べたように、1ページにつき1つ以上のウィンドウやフレームを作成することができ、興味深い可能性があると言えます。

IFRAME は HTML4 の仕様の一部で、Internet Explorer でサポートされています。したがって、@BrowserInfo("BrowserType") でブラウザーがノーツまたは Internet Explorer だと判断した場合に使用されます。ILAYER は Netscape 独自のタグで IFRAME と同じようなものですが、IFRAME でサポートしているスクロール機能をサポートしていません。スクロール機能があるので、IFRAME を用いるとページのデザインがどのように変化してもうまく収まります。ブラウザーのウィンドウとは別にスクロール・バーがあるので、IFRAME の中身だけをスクロールさせることができます。ILAYER ではスクロールをサポートしていないので、ILAYER を用いる場合は、内容がすべてきちんと表示されるようにサイズを十分大きめにとるようにしてください。

また、ID=switchview という指定によって IFRAME や ILAYER に名前をつけています。これは先程も見たように、Internet Explorer の場合でしか意味がありません。
最後に、先頭近くのタグでさらに height、width、scrolling、SRC といった属性を与えています。SRC には表示したい内容がどこにあるのかを指定します。上のコードでは、SRC 属性の計算結果テキストは、フォームの ThisDb フィールドになっており、Basses ビューへの相対 URL の一部になっています。このようになっているのは、フォームが開いたときに上部のビューには標準で Basses ビューが表示されるようになっているためです。(例では、ドミノが生成する一般的なフォーマットを使用していますが、すべてのビューは $$ViewTemplate フォームを通して表示させることができます)

このように、コードをつけ加えずに、1つのフォームやページ上に2つのビューを配置できました。それでもまだ十分ではないようなので、IFRAME の内容を切り替える方法を話題にすることで結びとします。(Internet Explorer 上でしかうまく動作しないということを思い出してください。そのため、これらのコントロールは Netscape Navigator では表示されないようにする設計を以下に説明します。それ以外の点については、Netscape Navigator でも動作します。)

フォームの先頭付近の Drums と Basses リンクのパススルー HTML に戻りましょう。まず、これらのリンクは Netscape Navigator ではうまく動作しないことを思い出してください。そのため、このパススルー HTML は、すでに見たように @BrowserInfo 関数を用いた非表示式を与えられています。

@BrowserInfo("BrowserType") = "Netscape"

この関数の値が真の場合、パススルー HTML の Drums と Basses リンクは Netscape Navigator 上には表示されません。ここにリンクのパススルー HTML を載せておきます。

<A HREF="#" onClick="javascript:showview('basses')">Basses</A>&nbsp;&nbsp;
<A HREF="#" onClick="javascript:showview('drums')">Drums</A>

どちらのリンクでも onClick イベントが発生すると、JavaScript の showview 関数が呼び出されます。また引数として、表示するビューの名前を受け取ります。次に、フォームの JS Header をお見せします。

function showview( view ) {
target = "/" + document.forms[0].ThisDb.value + "/" + view + "?openview";
document.all.switchview.src = target;
}

この関数の最初の行は、表示したいビューへの相対的な URL を作成するために ThisDb フィールドで用いたものの使い回しです。実際にビューが開かれるのは、関数の最後の行によるものです。ここでは、IFRAME (この IFRAME を "switchview" と呼んでいたことを思い出してください) の SRC 属性を上の行で得られた相対 URL に設定しています。たったこれだけで切り替え可能なビューが実現できます。

ドミノの開発者にとって、1つのページに複数のビューを入れることができるというのは、非常に強力な選択肢であり、創造的なソリューションに結びつきます。上で述べたように、ドミノの標準的なビューの表示方法に縛られることはありません。つまり、ビューはさまざまな手段を用いてどのようにでも表示できます。Multiple Embedded Views 2 フォームがサンプル・データベースの中にありますが、下のビューはビューを HTML として扱うように設定されており、このテクニックの柔軟性を示しています。
 
上に戻る
 
これからが始まりです
これらの例が示したドミノ・ベースの Web ソリューションを織り交ぜたり、ここで見てきたことは、独自に DHTML の可能性の探求をするときの土台として役立つでしょう。

DHTML の道のりにはさまざまな問題があり、それは主にブラウザーのサポートしてるレベルによるものだということを見てきました。苦労せずに、ブラウザーに依存しない DHTML の開発ができると期待してはいけません。しかし、DHTML の仕様が進化しつづけるように、Web ブラウザーも進化しつづけるでしょう。障害を乗り越えるため、実際に DHTML の開発に着手する前に十分勉強するのが最も良い方法でしょう。

O'Reilly & Associates, Inc から出版されている、Danny Goodman の "Dynamic HTML:The Definitive Reference" (ISBN 1-56592-494-0) は、非常によい参考文献です。それに加えて、大抵の HTML 4 の参考文献はある程度 DHTML を扱っています。WebMonkey と CNET の Builder.com はオンラインのチュートリアルや実例集としては非常に素晴らしいです。HTML や CSS (スタイルシート) の仕様は World Wide Web Consortium (W3C) で管理されており、ドキュメント・オブジェクト・モデル (DOM) や ECMAScript (JavaScript や JScript はこれから派生して誕生しました) の情報は NetscapeMicrosoft のサイトから得られます。

DHTML について学習を続ける必要がありますが、アプリケーションの開発時に、強力なツールを自由に利用できるなら問題は無いでしょう。DHTML を利用することにより、より速くて直感的なソリューションをユーザに提供できます。結局のところ、ノーツ・クライアントはこれらの便利な機能をずっと前から提供してきましたが、DHTML によって、Web の世界でも同様のそれらの機能が利用できるようになったと言えます。


著者について
Michael Patrick はインディアナ州のインディアナポリスにある Knowledge Resource Group の主任コンサルタントです。彼は、この記事で扱った内容を Synergistics 社の Henry Newberry に広めてもらいたいと考えています。

IBMはIBM Corporationの商標。
Lotus、Lotus Domino、Lotus NotesはIBMの商標。
その他、記載された社名および製品名は、それぞれ各社の商標または登録商標です。

 
上に戻る