カスタム・コンポーネント
他の Zen コンポーネントと自動的に連携して動作する再使用可能な新しいコンポーネントを簡単に開発できることは、Zen フレームワークの最も強力な特徴の 1 つです。
このドキュメント "Zen の使用法" の最初の章、“Zen の概要” では、Zen のアプリケーション開発フレームワークは拡張可能であることを述べました。この考えは事実です。一方、Zen では、ユーザが自身で追加しようと考える機能の多くが既に考慮されています。カスタム開発に労力を費やす前に、Zen で使用できるコンポーネントをすべて調べてみる価値はあります。必要な機能が、すでに存在している Zen コンポーネントに用意されている可能性があります。
"Zen コンポーネントの使用法" というドキュメントでは、既存の Zen コンポーネントをカテゴリ別に詳しく紹介しています。これらのカテゴリとしては、テーブル、メータ、グラフ、フォーム、コントロール、メニュー、ポップアップ、およびその他があります。これらの章をすべて調べた後でも、カスタム・コンポーネントの作成が必要になる場合があります。その場合は、この章を読み進めて、そのためのオプションと説明を参照してください。
どのような大文字と小文字の組み合わせにかかわらず、ZEN.Component パッケージ以下にクラスを作成しないことを強くお勧めします。ZEN.Component というパッケージを作成すると、クライアント側コードを生成するための Zen フレームワークが損なわれます。
通常、Zen を拡張する最も一般的な方法は、カスタム・コンポーネントを作成することです。カスタム・コンポーネントは、最小限の処理で既存の Zen フレームワークに適合します。カスタム・コンポーネントを使用することにより、Zen のレイアウト規約に従い、Zen のクライアント/サーバ・フレームワークを活用しながら、必要なスタイルと動作を実現できます。次のリストでは、カスタム・コンポーネントを作成するためのオプションについて説明しています。また各オプションを説明しているこの章のセクションへのリンクもあります。
-
“複合コンポーネント” では、複合コンポーネントの作成方法について説明します。複合コンポーネントは、既存の組み込み Zen コンポーネントのグループを、特定の方法で配置したものです。これは、ページ上に単一のコンポーネントのように配置できます。
-
“コンポーネント・スタイルのオーバーライド” では、組み込み Zen コンポーネントのサブクラスを作成し、その XData Style ブロックをオーバーライドすることにより、組み込み Zen コンポーネントのスタイルに単純な変更を加える方法について説明します。
-
“カスタム・コンポーネントの作成” では、Zen コンポーネントの標準のベース・クラスのいずれかのサブクラスである、新しいコンポーネント・クラスを記述することにより、Zen コンポーネントのラインナップを拡張する方法について説明します。結果として得られるクラスは、あらゆる Zen ページの XData Contents ブロックで使用できるように、自動的に XML として投影されます。
この章は、“カスタム・コンポーネントの作成” をサポートするセクションで構成されています。
-
“カスタム・スタイル” は、サブクラスの XData Style ブロックを配置します。
-
“カスタム・プロパティ” は、ベース・クラスから継承したものを含めたプロパティを定義します。
-
“%DrawHTML メソッド” は、クライアント側での表示を作成するうえで必要な HTML (または SVG) を提供するメソッドが必要です。
-
“カスタム・メソッド” は、%DrawHTML および ベース・クラスから継承されたものを含めたメソッドを定義します。
-
“サンプル・コード” では、サンプル・カスタム・コンポーネント・クラスを提供し、Zen ページ・クラスの XData Contents ブロックからの参照方法を示します。
-
-
“カスタム・メータの作成” では、クライアントで基本のメータ・クラスのサブクラスを作成し、新しいメータの SVG コンテンツの描画に必要なメソッドの呼び出しを追加することにより、Zen に新しいタイプのメータを追加する方法を示します。
複合コンポーネント
複合コンポーネントは、組み込み Zen コンポーネントのグループをまとめて、XData Contents から単独のコンポーネントのように参照できるようにしたものです。Zen では、ページのオブジェクト・モデルにある複合コンポーネントの子が、XData Contents から明示的に参照されているかのように配置されます。この簡単な方法は便利で、同じコンポーネントの配置を別のページで繰り返す際のエラーも防止できます。
以下のテーブルは、複合コンポーネント・クラスを構築する際のチェックリストです。チェックリストのすべての項目が、すべての複合コンポーネントで必要なわけではありません。このチェックリストには、使用する可能性のある項目がすべて表示され、オプションの項目には注が付いています。テーブルの後の複合コンポーネント・クラスの例を参照してください。
必須 | オプション | 説明 |
---|---|---|
サブクラス | %ZEN.Component.compositeOpens in a new tab を拡張して、新しいクラスを作成します。例では、MyApp パッケージに myComposite という複合コンポーネント・クラスを作成します。%ZEN.Component.compositeOpens in a new tab を拡張したクラスはすべて、"Zen の使用法" の “Zen のレイアウト” の章の “グループのレイアウトとスタイルの属性” の説明にあるすべての属性を備えたグループです。 | |
パラメータ | クラス・パラメータと適切な値を指定します。例えば、NAMESPACE パラメータは、複合コンポーネントにネームスペースを割り当てるために必要です。複合コンポーネントを Zen ページに配置する際には、このネームスペースを参照する必要があります。 | |
プロパティ | 必要に応じてプロパティを指定します。この例では、サブクラスの新しいプロパティは不要です。 | |
メソッド | コンポーネントの動作での必要に応じて、サポートするメソッドを指定します。この例では、ユーザが複合コンポーネントのいずれかのボタンをクリックするとアクティブになるイベント・ハンドラ・メソッドを指定します。 | |
XData Contents | 複合コンポーネント・クラス内で、<composite> を最上位要素として使用する XData Contents ブロックを定義します。この例では、<composite> 内に <button> 要素を 2 つ指定しています。 | |
XML 要素 | ページに複合要素を追加するには、対応する XML 要素をページ・クラスの XData Contents ブロックに配置します。これには特定の構文があります。このテーブルの後の例を参照してください。 | |
コンパイル順序 | 複合コンポーネントや他のタイプのカスタム・コンポーネントに適用されるコンパイル順序の詳細は、“カスタム・コンポーネント・クラスのコンパイル順序” を参照してください。 |
以下は、ボタンを 2 つ指定する複合コンポーネント・クラスの例です。
Class MyApp.myComposite Extends %ZEN.Component.composite
{
/// Define xml namespace for this component
Parameter NAMESPACE = "http://www.intersystems.com/myApp";
/// Contents of this composite component:
XData Contents [XMLNamespace="http://www.intersystems.com/zen"]
{
<composite>
<button caption="OK"
onclick="zenThis.composite.okBtn();"/>
<button caption="Cancel" />
</composite>
}
ClientMethod okBtn() [Language = JavaScript]
{
alert('ok');
}
}
XData Contents ブロックからこの複合コンポーネントを正しく参照する方法は、以下のとおりです。
XData Contents [XMLNamespace="http://www.intersystems.com/zen"]
{
<page xmlns="http://www.intersystems.com/zen"
xmlns:myApp="http://www.intersystems.com/myApp">
<myApp:myComposite />
</page>
}
以下はその説明です。
-
<page> 要素は、開いている <page> 要素内に以下の属性を指定することにより、複合コンポーネントに定義されたネームスペースを参照し、そのエイリアスを定義します。
xmlns:myApp="http://www.intersystems.com/myApp"
この文では、複合コンポーネント・クラスで定義されたネームスペースに、エイリアス myApp を定義します。
Parameter NAMESPACE = "http://www.intersystems.com/myApp";
-
<myApp:myComposite> 要素は、myComposite コンポーネントを参照します。この参照の形式は以下のとおりです。
<alias:component>
ここで、alias は <page> 要素で定義されたネームスペースのエイリアス (この場合は myApp)、component はカスタム・コンポーネント・クラスの名前 (この場合は myComposite) です。
composite プロパティ
プログラムを使用して複合コンポーネントを扱う場合、複合コンポーネント内の各コンポーネントには、それが属する複合オブジェクトを参照する composite というプロパティがあります。これにより、複合クラスのメソッドを参照する複合コンポーネントのアクションの定義が簡単になります。これは、上記の例にある最初の <button> 要素を見るとわかります。
<button caption="OK"
onclick="zenThis.composite.okBtn();"/>
この <button> 定義の onclick 属性値では、zenThis.composite を使用して、それが属する複合オブジェクトを表します。この規約を使用すると、<button> から、複合クラス内で定義された okBtn メソッドを呼び出すことができます。
複合コンポーネントとペイン
ペインについて調べ、そのコンテンツがどのように定義されているか確認するには、>Zen の使用法> の “Zen のレイアウト” の章の “ペイン” を参照してください。
<pane> コンポーネントを複合要素に配置すると、このペインのコンテンツをその複合クラス (または、複合クラスのサブクラス) で定義できます。実行時に、複合クラスはまず、指定された名前を持つペインを現在のページで検索し、そこに目的のペインが存在しない場合は複合クラスで検索します。
コンポーネント・スタイルのオーバーライド
既に組み込み Zen コンポーネントのいずれかのサブクラスを作成している場合は、コンポーネントに定義したスタイルをオーバーライドできます。"Zen の使用法" の “Zen のスタイル” の章にある “組み込みスタイルのオーバーライド” を参照してください。以下に簡単に説明します。
-
該当する CSS スタイル名を判断します。
-
組み込み Zen コンポーネントのサブクラスを作成します。
-
Zen スタイル・ウィザードを使用して、XData Style を編集します。
ただし、まったく新しい CSS スタイルを (新しい名前で) 定義し、そのスタイルをコンポーネントに適用する場合は、実行する手順が増えます。CSS スタイルを定義するだけでなく、カスタム・コンポーネントを HTML として表示するクラス・コードからそのスタイルを参照する必要もあります。この時点で、本当のカスタム・コンポーネントを作成することになります。詳細は、“カスタム・コンポーネントの作成” を参照してください。
カスタム・コンポーネントの作成
各 Zen コンポーネントはクラスとして実装され、Zen コンポーネントとして必要なものをすべて備えています。コンポーネント・クラスでは、1 つの論理ユニット、つまりクラス内に動作 (サーバのメソッドとクライアントのメソッド) と外観 (SVG または HTML、DHTML、およびスタイルシート) が指定されています。各コンポーネント・クラスには XML プロジェクションがあります。このプロジェクションは以下により構成されています。
-
クラス (<page>、<html>、<hgroup> など) と同じ名前を持つ XML 要素
-
そのクラスのプロパティ (幅、高さなど) である XML 属性
Zen ページを構築するには、使用可能な XML 要素と属性から目的のものを選択して、Zen ページ・クラスの適格な XML ドキュメントに配置します。このドキュメントのコンテナを、XData Contents と呼びます。コンパイル時に、そのコンポーネントに対して選択されたレイアウト、スタイル、および動作でブラウザにページを表示するために必要なコードが生成されます。実行時には、表示の詳細が Zen ですべて処理され、コンポーネントやページ・クラスに埋め込まれたり、それらで参照されている JavaScript、HTML、または CSS のあらゆるスニペットが正しく実行されます。
Zen コンポーネントでは、これらすべての機能はベース・クラスから継承されているので、自動的に提供されます。これが、ユーザ自身が実行できることです。カスタム・コンポーネントを作成するには、適切なベース・クラスを選択して拡張するだけで済みます。新しいクラスは、自動的に以下の機能を備えます。
-
ページ・クラスの XData Contents で使用する XML プロジェクション
-
親のすべてのプロパティ、メソッド、パラメータ、またはその他の特性
-
該当のクラスに属する、以下のすべてのクライアント側素材を適切に処理する機能
-
JavaScript
-
CSS スタイル定義
-
HTML
-
SVG
-
-
プロパティは設定として公開し、クライアント側の getProperty メソッドおよび setProperty メソッドを使用して確認および変更できます。
以下のテーブルは、カスタム・コンポーネント・クラスを作成する際のチェックリストです。テーブル内の各項目の構文と使用法の詳細を確認するには、テーブル内のリンクをクリックするか、テーブルの後に登場するトピックを参照してください。
必須のタスク | オプションのタスク | 説明 |
---|---|---|
パッケージ | すべてのカスタム・コンポーネント・クラスに対して、1 つのクラス・パッケージを使用することをお勧めします。これにより、コンパイル順序などの各種の問題を解決しやすくなります。 | |
XML ネームスペース | すべてのカスタム・コンポーネントに対して、1 つの XML ネームスペースを使用することをお勧めします。 | |
サブクラス | 簡単な候補のリストからベース・クラスを選択します。 | |
パラメータ | NAMESPACE や INCLUDEFILES などのクラス・パラメータを指定します。 | |
XData Style | コンポーネント・クラス内で、CSS スタイルを定義する XData Style ブロックを指定します。 | |
プロパティ | 必要に応じてプロパティを指定します。コンポーネントのさまざまなプロパティは設定として公開し、クライアント側の getProperty メソッドおよび setProperty メソッドを使用して確認および変更できます。 | |
%DrawHTML | 可視コンポーネントは、クライアント側での表示を作成するうえで必要な HTML (または SVG) を描画する必要があります。カスタム・コンポーネント・クラス内の %DrawHTML メソッドが、このクラスで定義されている任意の新しい CSS スタイルを参照していることを確認する必要があります。 | |
メソッド | %DrawHTML に加えて、正しいコンポーネントの動作を実現するために、必要に応じてコンポーネント・メソッドを作成またはオーバーライドしてください。 | |
コンパイル順序 | Zen ページがカスタム・コンポーネントを参照している場合や、カスタム・コンポーネントを参照している複合コンポーネントを参照している場合は、コンパイル順序の問題が発生する可能性があります。 | |
XML 要素 | ページにカスタム・コンポーネントを追加するには、対応する XML 要素をページ・クラスの XData Contents ブロックに配置します。これには特定の構文があります。“サンプル・コード” を参照してください。 |
カスタム・コンポーネント・クラスのパッケージ
どのような大文字と小文字の組み合わせにかかわらず、ZEN.Component パッケージ以下にクラスを作成しないことを強くお勧めします。ZEN.Component というパッケージを作成すると、クライアント側コードを生成するための Zen フレームワークが損なわれます。
すべてのカスタム・コンポーネント・クラスに対して、1 つのクラス・パッケージを使用することをお勧めします。これらの規約が掲げられているのには、次のような理由があります。
-
Zen フレームワークでは、カスタム・コンポーネント用の JavaScript および CSS スタイルシートのインクルード・ファイルが自動的に生成されます。これらのファイルは、クラス・パッケージごとに生成されるので、カスタム・コンポーネントを専用のパッケージに収めておけば、その編成がたいへん容易になります。
-
Zen ページがカスタム・コンポーネントを参照している場合や、カスタム・コンポーネントが含まれた複合コンポーネントを参照している場合は、コンパイル順序の問題が発生する可能性があります。コンパイル順序の問題を防止するためのいくつかの方法については、後出のセクション “カスタム・コンポーネント・クラスのコンパイル順序” で説明します。1 つの手法は、すべてのカスタム・コンポーネントを 1 つのパッケージに配置して、Zen ページ・クラスが含まれたどのパッケージよりも前に、そのパッケージをビルド・プロシージャによってコンパイルすることです。
Zen ページの XData ブロック内のカスタム・コンポーネントを参照するときは、パッケージ名を使用しないでください。その場合は、次のセクション “カスタム・コンポーネント・クラスの XML ネームスペース” の例で示すように、クラス名のみを使用してください。
カスタム・コンポーネント・クラスの XML ネームスペース
カスタム・コンポーネントには、他のコンポーネントとの名前の競合を防ぐために専用の XML ネームスペースが必要です。このネームスペースは次のように定義して参照します。
-
作成する各カスタム・コンポーネント・クラスで NAMESPACE パラメータを指定します。以下に例を示します。
-
カスタム・コンポーネント・クラス名は次のとおりです。
myCustom
-
ネームスペースは次のとおりです。
http://www.mycompany.com/mycomponents
Class MyPackage.myCustom Extends %ZEN.Component.textarea { /// This is the XML namespace for this component. Parameter NAMESPACE = "http://www.mycompany.com/mycomponents"; /// This Style block contains component-specific CSS style definitions. XData Style { } /* Here is the rest of the class... */ }
-
-
カスタム・コンポーネントを参照する各 XData ブロックの先頭で、このネームスペースの接頭辞を定義します。そのうえで、カスタム・コンポーネントを参照する際に、この接頭辞を使用します。以下に例を示します。
-
カスタム・コンポーネント・クラス名は次のとおりです。
myCustom
-
ネームスペースは次のとおりです。
http://www.mycompany.com/mycomponents
-
接頭辞は次のとおりです。
myco
XData demoPane [ XMLNamespace = "http://www.intersystems.com/zen" ] { <pane xmlns="http://www.intersystems.com/zen" xmlns:myco="http://www.mycompany.com/mycomponents" valign="top" > <myco:myCustom id="DemoText" name="DemoText" label="Operator Instructions:" cols="32" rows="8" title="Type comments and drag text into the editing area" hint="Describe how to use the product at this step." enclosingClass="myValid" /> <hgroup align="center"> <button caption="Clear" onclick="zenPage.clearAllValues()" /> <button caption="Revert" onclick="zenPage.revertToSaved()" /> <submit caption="Save" /> </hgroup> </pane> }
-
1 つの XML ネームスペースを定義してそれをすべてのカスタム・コンポーネント用に使用し、その XML ネームスペースはカスタム・コンポーネント専用にすることをお勧めします。
カスタム・コンポーネント・クラスのコンパイル順序
Zen ページが複合コンポーネントまたはカスタム・コンポーネントを参照している場合は、コンパイル順序の問題が発生する可能性があります。コンパイル順序の問題の症状は、コードをリコンパイルするだけで修正できるコンパイル時エラー・メッセージが表示されることです。このような場合は、エラー・メッセージを防止してアプリケーションを正しくコンパイルするには、ビルド・プロシージャは、次のようにまず最下位レベルのクラスをコンパイルして、上に向かって順番にクラスをコンパイルする必要があります。
-
カスタム・コンポーネント。これらは、コンパイル順序における最下位レベルのクラスであるため、最初にコンパイルします。
-
複合コンポーネント。これらは、カスタム・コンポーネントを参照している可能性があるため、すべてのカスタム・コンポーネントの後にコンパイルします。
-
ページ。これらは、複合コンポーネントやカスタム・コンポーネントを参照している可能性があるため、これらのコンポーネントを先にコンパイルしてから、最後にページをコンパイルします。
次のようないくつかの方法で、Zen アプリケーションでのコンパイル順序の問題を防止できます。
-
すべてのクラスが同じパッケージ内に存続できるようにする一方で、下位レベルのクラスを参照する必要のある上位レベルのクラスで DependsOn キーワードを指定します。これは、クラス数が少なく、他のクラスへの参照があまり階層化されていない場合には、ごく簡単に実行できます。下位レベルのクラスを参照する各上位レベル・クラスの定義の先頭に、DependsOn 文を記述するだけです。DependsOn の値には、参照先の下位レベル・クラスのパッケージとクラスの名前を指定する必要があります。次に例を示します。
Class MyPackage.MyZenPage Extends %ZEN.Component.page [ DependsOn = MyPackage.myCustom ] { /* Here is the rest of the class... */ }
-
大規模なアプリケーションの場合は、すべてのカスタム・コンポーネント・クラスを 1 つのパッケージに配置し、すべての複合コンポーネントを 2 つ目のパッケージに配置して、すべての Zen ページ・クラスを 3 つ目のパッケージに配置することをお勧めします。ビルド・プロシージャでは、各パッケージを個別にコンパイルするために別々のコマンドを呼び出して、これら 3 つのパッケージを最下位レベルから最上位レベルに向かって適切な順序でコンパイルする必要があります。
-
すべてのクラスを別々のコンパイル・グループに割り当てる場合は、大規模なアプリケーションでこれらのクラスを同じパッケージ内に保持できるようにすることも可能です。このためには、次のように下位レベル・クラスに System キーワードを追加して、これらのクラスを複数のコンパイル・グループに分類します。
-
カスタム・コンポーネント・クラスを [System=3] に設定して、これらが最初にコンパイルされるようにします。
-
複合コンポーネントを [System=4] に設定して、これらがその次にコンパイルされるようにします。
-
残りのアプリケーション・クラスについては、System のキーワードや値を指定せずに、これらが最後にコンパイルされるようにします。
System キーワードは、スタジオで設定できます。このプロパティの値を 3 か 4 に設定すると、希望の結果が得られます。既定値の 0 を使用すると、クラスに System 値を設定しない場合と同じ結果になります。
Caution:System キーワードの値を 1 や 2 に設定しないことを強くお勧めします。5 以上の値はサポートされていないため、スタジオ・インスペクタではこれらの値を選択できません。
-
Zen コンポーネント・ウィザード
新しい Zen コンポーネント・クラスを作成するには、スタジオの新規 Zen コンポーネント・ウィザードを使用します。このウィザードを起動するには、スタジオの [ファイル]→[新規作成] コマンドを選択し、[Zen] タブをクリックし、[新規 Zen コンポーネント] アイコンをクリックします。
コンポーネントのベース・クラス
コンポーネントを新規作成するときは、そのベース・クラスを選択する必要があります。選択肢は 5 つあります。以下の図とテーブルは、その選択肢の概要を示しています。
ベース・クラス | 目的 | 継承される属性 |
---|---|---|
%ZEN.Component.componentOpens in a new tab | 表示可能な、HTML ベースのコンポーネント。 | Zen コンポーネント |
%ZEN.Component.controlOpens in a new tab | HTML ベースのコンポーネントは、ユーザが値を入力できるフォームに配置できます。 | Zen コンポーネント、Zen コントロール |
%ZEN.SVGComponent.svgComponentOpens in a new tab | 表示可能な、SVG ベースのコンポーネント。 | SVG コンポーネント |
%ZEN.SVGComponent.meterOpens in a new tab | 動的に更新されて値を表示する SVG グラフィック。 | SVG コンポーネント、メータのコンポーネント |
%ZEN.Component.objectOpens in a new tab | 非表示のコンポーネント。通常、これは、表示可能なコンポーネントで使用するヘルパー・オブジェクトで、クライアント側でのオブジェクト表現が必要となります。 | — |
コンポーネントのクラス・パラメータ
カスタム・コンポーネントに選択したベース・クラスに応じて、さまざまなクラス・パラメータを使用できます。各コンポーネントのベース・クラスによって、そのコンポーネントのクラス・パラメータが、コンポーネントの種類で最も役に立つ値に設定されます。必要に応じて、これらの値を再設定できます。次のテーブルは、重要と考えられるクラス・パラメータを示しています。
これ以外のクラス・パラメータは、使用しているベース・クラスのクラス・リファレンス・ドキュメントで調べることができます。その手順は次のとおりです。InterSystems のオンライン・ドキュメントを開きます。 ドキュメントのホーム・ページの上部にあるメニュー・バーで [クラスリファレンス] を選択します。%SYS ネームスペースおよび %ZEN.Component または %ZEN.SVGComponent のいずれかのパッケージを選択します。クラス名をクリックします。
パラメータ | 意味 |
---|---|
DEFAULTVISIBLE | True (1) または False (0)。%ZEN.Component.objectOpens in a new tab ベース・クラスでは、DEFAULTVISIBLE が 0 に設定されています。ページに表示する必要のある Zen コンポーネントでは、この値を 1 に変更します。このクラス以外の、前のテーブルで挙げたすべてのベース・クラスではこの値が 1 に設定されているので、カスタム・コンポーネント・クラスがこれらのクラスを継承すれば、そのコンポーネントは既定で表示されるようになります。 |
INCLUDEFILES | 該当のコンポーネントをページに表示するときにインクルードする JavaScript (.js) ファイルまたはカスケーディング・スタイル・シート (.css) ファイルのコンマ区切りリスト。これらのファイルの物理パスには、シンプルなファイル名のみを使用できます。“Zen アプリケーション・プログラミング” の章の “Zen アプリケーションの構成” を参照してください。 |
NAMESPACE | コンポーネントに使用する XML ネームスペース。“カスタム・コンポーネント・クラスのネームスペース” を参照してください。既定の NAMESPACE 値は "http://www.intersystems.com/zen" です。 |
POSTCOMPILEACTIONS |
このクラスをコンパイルした後で実行するアクションのコンマ区切りリスト。このリストは空でもかまいません。このコンマ区切りリストに記述できる文字列は次のとおりです。
%ZEN.Component.objectOpens in a new tab ベース・クラスは、Zen のコンポーネントとコントロールに適切な "schema,HTML" を既定の文字列として設定します。%ZEN.SVGComponent.svgComponentOpens in a new tab ベース・クラスは、メータを含む Zen SVG コンポーネントに適切な "schema,SVG" を既定の文字列として設定します。 MODULE を定義して、HTML または SVG のいずれかを含めるように POSTCOMPILATIONACTIONS を設定した場合、生成される JavaScript はページでインラインで処理されるのではなく、外部ファイルに配置されます。この機能を使用して、クライアント上のキャッシュの利点を得ることができ、コンテンツ処理における全体的なオーバーヘッドを減らすことができます。 |
カスタム・スタイル
カスタム・コンポーネントに新しい CSS スタイルを定義するには、XData Style ブロックをサブクラスに配置します。このブロックに、<style type="text/css"> タグとそれに対応する </style> タグを置きます。この <style> 要素に、目的の CSS スタイル定義を記述します。
組み込みクラス %ZEN.Component.groupOpens in a new tab には、以下の XData Style ブロックがあります。
XData Style
{
<style type="text/css">
/* @doc="Table used by groups." */
table.group {
padding: 0px;
}
/* @doc="Cell within table used by groups." */
table.group td {
padding: 0px;
}
/* @doc="Header within table used by groups." */
table.group th {
padding: 0px;
}
</style>
}
上記の例にある /* @doc="text" */ 構文に注目してください。この構文を使用して XData Style エントリにコメントを記入すると、Zen スタイル・ウィザードでは、使用可能なスタイルのリストにスタイルの説明が自動的に追加されます。スタジオで Zen クラスを編集する際にこのリストを表示するには、[ツール]→[テンプレート]→[テンプレート] を選択するか、Ctrl-T キーを押して Zen テンプレートのリストを表示します。[Zen スタイル・ウィザード] を選択すると、すべての定義済みスタイルのリストが表示されます。このリストでは、コンポーネント名のアルファベット順でスタイルが並べられています。
Zen スタイル・ウィザードでスタイルのリストを表示しているときは、スタイルの名前の横にあるラジオ・ボタンを選択して [OK] をクリックすると、そのスタイルを編集できます。これらのスタイルのテンプレートが、XData Style ブロックに表示されます。
組み込み Zen コンポーネントのいずれかのサブクラスで既存のスタイルをオーバーライドする場合は、Zen スタイル・ウィザードを使用して、オーバーライドするスタイルを選択する方法が最も便利です。
上記の例の XData Style は、組み込み Zen コンポーネントである %ZEN.Component.groupOpens in a new tab に対するスタイルの定義です。まったく新しいスタイルでカスタム・コンポーネントを作成するとします。その場合、コンポーネントに適したスタイル名を作成する必要があります。MyComponent というコンポーネントに、以下の例に示すような、XData Style ブロックが存在する場合を考えてみます。XData Contents ブロックで <MyComponent> を使用しているすべてのページに対して、このスタイル定義が自動的に指定されます。
XData Style
{
<style type="text/css">
/* @doc="Main style definition for MyComponent." */
.MyComponent {
color: blue;
background: yellow;
white-space: nowrap;
}
</style>
}
単に XData Style ブロックを定義しただけでは十分ではありません。このコンポーネント・クラスでは、それが生成した HTML の中で、新しく定義した CSS スタイルを実際に使用する必要があります。これを実行するには、カスタム・コンポーネント・クラスの HTML を表示する %DrawHTML メソッドでスタイルへの参照を指定する必要があります。以下の例の %DrawHTML メソッドは、上記の例の XData Style で定義した MyComponent スタイルを参照します。
Method %DrawHTML()
{
&html<<div class="MyComponent">Message</div>>
}
規約では、上記の例のように、XData Style ブロックで指定した CSS スタイル名には、そのコンポーネントの名前に関連する名前を付けることになっています。これにより競合 (これは CSS の性質上、事前に検知できません) が回避され、ユーザはスタイルのオーバーライド方法を判断しやすくなります。コンポーネントでは、他のコンポーネントにより定義されたスタイルを再定義したり、要素全体にわたるスタイル・セレクタ (“input” や “table” など) を定義したりすべきではありません。これは他のコンポーネントへの干渉の原因となります。
コンポーネント、ページ、およびアプリケーション・クラスで定義されている CSS スタイルの優先順位に関する規則を確認するには、"Zen の使用法" の “Zen のスタイル” の章の “スタイルのカスケード” を参照してください。カスタム・コンポーネントは、これらの規則に従います。
XData SVGStyle
Style は、Zen SVG コンポーネントには適用されません。Zen SVG コンポーネントでは、XData SVGStyle を使用します。
カスタム Zen SVG コンポーネント・クラスのスタイルを定義するには、XData SVGStyle ブロックを指定し、<style type="text/css"> タグと、終了タグの </style> との間に CSS 文を追加します。以下はその例です。
XData SVGStyle
{
<style type="text/css">
.customSVGComponent {
fill: url(#myGrad);
stroke: black;
stroke-width: 2px;
}
</style>
}
XData SVGDef
前述の例の XData SVGStyle は、SAMPLES ネームスペースのクラス ZENTest.customSVGComponentOpens in a new tab に基づいています。これは、色の myGrad を customSVGComponent シェイプの塗りつぶし色として参照します。
myGrad は同じクラスの、XData SVGDef という別のブロックで定義します。このブロックは、myGrad を青から赤へ変化する階調として定義しています。
XData SVGDef
{
<defs>
<linearGradient id="myGrad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:darkblue" />
<stop offset="30%" style="stop-color:#FF00FF" />
<stop offset="70%" style="stop-color:#FF00FF" />
<stop offset="100%" style="stop-color:darkred" />
</linearGradient>
</defs>
}
Zen のカラー定義
組み込みクラス %ZEN.SVGComponent.svgPageOpens in a new tab は、便利なカラー定義をいくつか XData SVGDef ブロックに提供します。
-
グローシルバー色は、<speedometer> メータなどの計測アイテムにメタリックな外観を与えます。
-
信号機などのメータでは、インジケータ・ランプにグローレッド、グローイエロー、グローグリーンを使用します。
-
ランプ色のグローブルー、グローパープル、グローオレンジ、グローティールも使用できます。
<svgFrame> は、svgPage 属性により、このクラスまたはこのクラスのサブクラスを必ず参照するので、これらのカラーはすべての SVG コンポーネントでいつでも使用できます。
カスタム・プロパティ
コンポーネントはクラスであるため、継承されたものではないプロパティを定義できます。これらのプロパティの定義は、サーバでの動作、コンポーネントに対応する JavaScript クラス定義での使用方法、ページの XML 表現での指定方法に影響を与えます。
名前付け規約
Zen のクラスのプロパティには、大文字と小文字を区別する名前付け規約があります。詳細は、"Zen の使用法" の “Zen チュートリアル” の章にある “Zen の名前付け規約” を参照してください。これらの規約の概要をまとめると以下のようになります。
-
クライアントのみのプロパティ : myProperty
-
サーバのみのプロパティ (% が必須) : %MyProperty
-
Javascript でイベント・ハンドラを呼び出すプロパティ : onmousedown
-
サーバ側コールバック・メソッドを特定するプロパティ : OnCreateDataSet
-
その他のプロパティ : myProperty
XML プロジェクション
すべての Zen コンポーネントは %XML.AdaptorOpens in a new tab クラスから派生し、XML の動作の定義にこのクラスのメカニズムを使用します。この詳細は "オブジェクトの XML への投影" を参照してください。特に、このトピックで説明した XMLPROJECTION パラメータについては、“単純なプロパティのプロジェクションが持つ形式の制御” を参照してください。ここには、XMLPROJECTION の各値 ("attribute"、"element"、"wrapped"、"none" など) の影響を説明しているテーブルがあります。
Zen コンポーネントの単純なプロパティにはすべて、XMLPROJECTION 値 "attribute" が設定されています。プロパティを XML で表示しない場合は、以下の例のように、その XMLPROJECTION パラメータを "none" に設定します。
Property beeswax As %ZEN.Datatype.string(XMLPROJECTION="none");
%ZEN.Datatype パッケージのデータ型は、XMLPROJECTION の既定値 "attribute" を使用して、XML 属性として投影されるようにしています。Zen データ型を使用すると、カスタム・コンポーネント・クラスでプロパティを定義する際に便利な点が多数あります。詳細は、“データ型クラス” を参照してください。
setProperty メソッド
カスタム・コンポーネント・クラスにプロパティを追加する場合は、サブクラスの setProperty メソッドをオーバーライドして、カスタム・コンポーネント・クラスに追加した各プロパティのケース処理を実装する必要があります。スーパークラスのプロパティには、スーパークラス・メソッドを既定にすることができます。この章には、この操作の実際例があります。“%DrawHTML のヘルパー・メソッド” にあるコンポーネント・クラスのサンプルを参照してください。
データ型のパラメータ
すべての Zen クラスは、%ZEN.componentParametersOpens in a new tab から以下のプロパティ・パラメータのセットを継承します。このプロパティ・パラメータは、Zen クラスに追加するすべてのプロパティに適用できます。プロパティで以下のパラメータを使用するために、プロパティを Zen データ型とする必要はありません。
ZENCLIENTONLY
クライアント環境のみで意味のある値を持つプロパティを Zen コンポーネントで定義することがあります。その例として、%ZEN.Component.objectOpens in a new tab の window プロパティや SVG コンポーネントで使用する svgGroup プロパティがあります。プロパティのパラメータ ZENCLIENTONLY が 1 (True) に設定されている場合、指定されたプロパティはクライアント・オブジェクト・モデルに属していますが、そのオブジェクトに対するサーバ側からの変更には同期せず、そのオブジェクトのシリアル状態にも反映されません。ZENCLIENTONLY パラメータの値は内部表記であり、普通は Zen 開発者が使用する必要はありません。
ZENENCRYPT
ZENENCRYPT はデータ暗号化ツールではありません。これは、コンポーネントの動作を制御するプロパティがクライアント上で操作されることを防ぐために使用されます。最適な例は、%ZEN.Component.tablePaneOpens in a new tab の showQuery プロパティです。このプロパティで ZENENCRYPT を True に設定して、クライアント上で誰も JavaScript のプロパティを変更できないようにし、テーブル内で実行されているクエリを表示できるようにします。これは、コンポーネントの重要な動作の変更を防ぐための Zen における保護メカニズムです。
ZENEXPRESSION
プロパティの ZENEXPRESSION の値が 1 (True) である場合、そのプロパティでは Zen #()# 式を解釈して実行時にその値を取得できます。詳細は、“Zen アプリケーション・プログラミング” の章の “Zen の実行時式” を参照してください。
プロパティで ZENEXPRESSION=1 を設定して実行時式をサポートすることはできません。組み込みの Zen コンポーネント・クラスで ZENEXPRESSION=1 を設定しているのは、そのプロパティが実行時式をサポートしていることを示すためであって、サポートできるようにするためではありません。
ZENLOCALIZE
ZENLOCALIZE パラメータを 1 (True) に設定した Zen プロパティはすべて、プロパティの値を別の言語に翻訳する際に使用できるメッセージ・ディクショナリ・エントリを自動的に生成します。詳細は、“Zen のローカライズ” の章を参照してください。
Zen アプリケーション・ユーザに伝えるために表示するメッセージを持ち、値が文字列のプロパティはすべて、ローカライズすることをお勧めします。これらのプロパティに Zen データ型 %ZEN.Datatype.captionOpens in a new tab を指定すると便利です。このデータ型では、ZENLOCALIZE は常に 1 に設定されますが、プロパティ定義に ZENLOCALIZE=1 を含めることで、直接 ZENLOCALIZE を設定することもできます。ZENEXPRESSION の制約とは異なり、データ型のパラメータ ZENLOCALIZE=1 を設定すると、実際にそのプロパティが自動的にローカライズ可能になります。
ZENLOCALIZE パラメータの特徴は以下のとおりです。
-
このパラメータを使用するクラスが、DOMAIN クラス・パラメータに値を指定してローカライズ・ドメインも定義している場合にのみ適用されます。
-
ページ・クラスの XData Contents の XML の記述から Zen で生成されるコードにのみ適用されます。プログラム処理で XData Contents をバイパスして Zen ページを扱う場合は、$$$Text マクロの呼び出しなど、同等のローカライズ・タスクをユーザ側で処理する必要があります。“Zen のローカライズ” の章を参照してください。“ ”
ZENSETTING
ZENSETTING を 1 (True) に設定すると、このプロパティをクライアント・クラス定義内の “設定” と見なす必要があることを表します。したがって、以下の点に注意します。
-
コントロール・テスト・ページなどの Zen ユーティリティでこのプロパティが表示されるようになります。
-
クライアント側メソッドである getProperty および setProperty を使用して、値を表示および変更できます。
%ZEN.Datatype パッケージ内のすべてのデータ型クラスでは、ZENSETTING があらかじめ 1 に設定されています。%ZEN.Datatype クラスを使用するときは、設定として扱われないようにしたいプロパティに対してはすべて、ZENSETTING を 0 に設定する必要があります。例えば、%ZEN.Datatype.listOpens in a new tab タイプまたはクライアント上でオブジェクト・タイプとして投影されるプロパティは、getProperty および setProperty ではプロパティが文字列として処理されるため、正しく動作しません。
データ型クラス
Zen には、Zen クラスでプロパティを定義するときに使用可能なデータ型クラスのセットが用意されています。このデータ型クラスは %ZEN.Datatype パッケージにあります。以下のテーブルはその一覧です。
新しい Zen クラスを定義するときには、どのデータ型クラスでも自由に使用できます。%ZEN.Datatype クラスを使用すると、Web アプリケーションのコンテキストで、そのプロパティをどのような目的で使用しているかがわかりやすくなります。また、多くの場合、データ型クラスを使用することにより、従来はユーザ側でのエンコード処理が必要だった機能が自動的に使用できるようになります。これにより、容易なローカライズ、イベント・ハンドラの規約、言語に依存しないブーリアン値とリスト配列などが実現します。
基本的に、すべての Zen データ型クラスは文字列です。以下のテーブルに挙げられているデータ型はすべて、同じベース・クラス %ZEN.Datatype.datatypeOpens in a new tab を共有しています。このベース・クラスの値は、%Library.StringOpens in a new tab 型として定義されています。テーブルのエントリからわかるように、これらの文字列はそれぞれ、有効な独自の方法でサブクラスにより解釈されます。
クラス | 説明 |
---|---|
align | 横方向の配置を示す HTML 値。指定できる値は、“left”、“right”、および “center” です。縦方向の配置の値は、"valign" を参照してください。 |
boolean | ブーリアン値。XData Contents では、"True" または "False" のテキスト値を使用することもできます。サーバで実行している ObjectScript コード、Caché Basic コード、または Caché MVBasic コードからプログラムを使用してアクセスするときは、この値は 1 または 0 になります。クライアントで実行している JavaScript コードからプログラムを使用してアクセスするときは、この値は True または False になります。 |
caption | このプロパティを XData Contents ブロックで初期化したときに、ローカライズされたテキスト・リソースのセットに自動的に追加される文字列。ただしそのためには、ページでローカライズの DOMAIN を定義済みで、ZENLOCALIZE パラメータを 1 に設定している必要があります。詳細は、“Zen のローカライズ” を参照してください。 |
classMember | サーバ側クラスのメンバ名 (プロパティ名やメソッド名など)。このクラスでは、クラス・メンバのタイプを示すデータ型パラメータ MEMBERTYPE を定義します。このデータ型を使用してプロパティを定義する場合は、MEMBERTYPE パラメータの値も指定する必要があります。MEMBERTYPE に指定可能な値は、“PROPERTY”、“METHOD”、“QUERY”、“INDEX”、または “XDATA” です。 |
className | サーバ側クラスの名前。 |
color | CSS カラー値。 |
cssClass | CSS スタイル・クラスの名前。 |
csv | “John,Paul,George,Ringo” など、値をコンマで区切ったリスト。 |
delegator | コールバック・メソッドとして使用する、現在のページ・クラスのサーバ側メソッドの名前。例えば、Zen の <html> コンポーネントには OnDrawContent 属性があります。この属性は &html または WRITE コマンドを使用して HTML コンテンツを提供するサーバ側コールバック・メソッドの名前を指定します。このコールバックを定義しておくと、このコンポーネントが描画されるたびに、サーバ側でそのコールバックが呼び出されます。基になるクラス %ZEN.Component.htmlOpens in a new tab では、OnDrawContent は delegator 型として定義されます。 |
eventHandler |
クライアント側イベントに反応してクライアントで実行される JavaScript 式。この JavaScript 式はイベント・ハンドラとして、このイベントの “ハンドラ” であるクライアント側メソッドを呼び出します。 例えば、Zen の <button> コンポーネントには、そのコントロールをクリックしたときに発生するアクションを指定する onclick 属性があります。基になるクラス %ZEN.Component.buttonOpens in a new tab では、onclick は eventHandler 型として定義されます。 %GetEventHandlers ヘルパー・メソッドを使用して %DrawHTML からイベント・ハンドラにアクセスする場合は、eventHandler 型を使用する必要があります。詳細は、“カスタム・メソッド” を参照してください。 |
expression | サーバ側の ObjectScript 式。 |
float | 浮動小数点値。 |
glvn | “^myGlobal” などの Caché グローバル (多次元配列) の名前。 |
html | HTML を使用してマークアップするテキストの文字列。 |
id | コンポーネントの ID 値。その他の目的では使用できません。 |
integer | 整数値。 |
length | 長さを示す HTML 値。例 : “5”、“5%” |
list | サーバで、list は項目のセットを部分ごとに区切られた文字列として表します。クライアントでは、list は JavaScript 配列に変換されます。このデータ型には DELIMITER パラメータがあり、その値はサーバでの list の表現を区切るために使用されます。DELIMITER の既定値は $C(5) です。%ZEN.Datatype.listOpens in a new tab タイプまたはクライアント上で "object" タイプとして投影されるページ・プロパティは、getProperty および setProperty では ZENSETTING を 0 に設定しない限り正しく動作しません。 |
name | コンポーネントの名前の値。その他の目的では使用できません。 |
resource | Caché リソースの名前。Caché リソースに精通していない場合は、"Caché セキュリティ管理ガイド" の “アセットおよびリソース” の章を参照してください。 |
script | クライアント側 JavaScript 式。 |
sql | SQL 文。既定では、この型のプロパティは、クライアントに送信されたときに暗号化されます (ZENENCRYPT パラメータが 1 に設定されています)。 |
string | 既定の MAXLEN が 250 の文字列。MAXLEN 値はリセットできます。 |
style | CSS スタイル文。例 : "color:red; background: yellow;" |
svgStyle | SVG の CSS スタイル定義。SVG で使用するスタイルは CSS に準拠していますが、CSS にはないスタイルのセットもあるので、このデータ型はそれらを指定します。 |
uri | URI 値。例 : “http://www.intersystems.com/zen” |
valign | 縦方向の配置を示す HTML 値。指定できる値は、“top”、“bottom”、および “middle” です。横方向の配置の値は、"align" を参照してください。 |
value | HTML コントロールの値として使用する値。 |
%DrawHTML メソッド
各カスタム・コンポーネント・クラスは、%DrawHTML メソッドを実装する必要があります。%DrawHTML は、Zen コンポーネントのクライアント側の視覚表現を作成するために必要な HTML (または SVG) を提供する必要があります。メソッドは、そのコンポーネントを持つページが最初に送信されるときに呼び出されます。<tablePane> のクエリが再実行されたときなど、ページでコンポーネントのコンテンツを動的に更新する必要がある場合は、後で呼び出すこともできます。
%DrawHTML メソッドの基本的な処理は非常に単純です。このメソッドが生成するあらゆる出力を、ブラウザに HTML として供給します。以下のように、WRITE コマンドを使用して %DrawHTML から出力できます。
Method %DrawHTML()
{
Write "This is some <b>HTML!</b>",!
}
WRITE の代わりに、埋め込み HTML 文では ObjectScript 構文を使用できます。この構文では、以下の例のように、&html の後に山括弧 <> で囲まれた HTML 文が続きます。
Method %DrawHTML()
{
&html<This is some <b>HTML!</b>>
}
%DrawHTML からの出力はすべて、Zen フレームワークで供給される、コンポーネントのエンクロージング <div> 要素で囲まれます。
この規約が効果的である理由は、%DrawHTML がコンポーネント・クラスのインスタンス・メソッドであるからです。これでロジックを実行して、コンポーネントのプロパティおよびメソッド、さらには基になる Caché データベースにもアクセスできます。ObjectScript 式、CSP #()# 構文、および Zen #()# 式の構文をサポートしています。以下の単純な例では、これらの機能をいくつか使用しています。
Method %DrawHTML()
{
#; draw items as specified by myCount
For i=1:1:..myCount {
&html<This is item #(i)#.<br/>>
}
}
%DrawHTML のヘルパー・メソッド
Zen フレームワークでは、カスタム・コンポーネントの %DrawHTML メソッドで使用する 3 つのサーバ側ヘルパー・メソッド、%MakeId、%Attr、および %GetEventHandlers を定義しています。<button> のクラス・コードは、これらのメソッドを %DrawHTML で効果的に使用する 1 つの方法を次のように示しています。
Class %ZEN.Component.button Extends control
{
Parameter DEFAULTCONTROLCLASS = "button";
/// Caption displayed for this button.<br>
/// This is a localized value.
Property caption As %ZEN.Datatype.caption;
/// defines style sheet used by this component
XData Style
{
<style type="text/css">
/* @doc="Style for button (input)." */
.button {
}
</style>
}
Method %DrawHTML()
{
Set disabled = $S(..disabled:"disabled",1:"")
Set tIgnore("onchange") = ""
&html<
<input type="button" class="#(..controlClass)#"
id="#(..%MakeId("control"))#" #(..%Attr("title",..title))#
#(..%Attr("name",..name))# #(..%Attr("value",..caption))# #(disabled)#
#(..%Attr("style",..controlStyle))# #(..%GetEventHandlers(.tIgnore))#>
>
}
/// This method fills in reasonable default values for
/// this control. Used by tools (such as Control Tester) to
/// dynamically create controls.
Method %SetDefaultValues()
{
Set ..caption = "Button"
}
/// Set the value of a named property.
ClientMethod setProperty(property, value, value2) [ Language = javascript ]
{
switch(property) {
case 'caption':
this.caption = value;
var el = this.findElement('control');
if (el) {
el.value = this.caption;
}
break;
case 'value':
// do not set control value; just internal value
this.value = value;
break;
default:
// dispatch
return this.invokeSuper('setProperty',arguments);
}
return true;
}
}
以下のトピックでは、各 %DrawHTML ヘルパー・メソッドの使用方法について説明します。
-
%MakeId — ページにコンポーネントを表示する HTML 要素の ID 値を生成します。クライアント側メソッド findElement でページの HTML 要素を検出できるように、一貫した名前付け方式を使用します。
-
%Attr — ページにコンポーネントを表示する HTML 要素の属性に値を割り当てます。このメソッドは、コンポーネントの表示に必要なすべての HTML 属性に値を割り当てるために、繰り返し呼び出すことができます。
-
%GetEventHandlers — コンポーネント定義からイベント処理情報をすべて取得します。これにより、そのコンポーネントの HTML 表現で、各ユーザ・イベントと実行するコードが正しく一致するようにします。
HTML 要素の識別
%MakeId サーバ側メソッドを使用すると、出力ページの各 HTML 要素の ID が確実に一意になります。“%DrawHTML のヘルパー・メソッド” にある例では、次のように埋め込み HTML から %MakeId を呼び出し、HTML の <input> 要素の ID を設定します。
id="#(..%MakeId("control"))#"
%MakeId は、呼び出し元が指定する文字列を、アンダースコア文字 “_” を使用して、ページに配置される各コンポーネントに割り当てられた一意の連続番号と連結します。次に、この識別子を Zen に渡して、要素を囲む <div> の ID 属性の値として使用します。さらに、コンポーネントが繰り返しグループの一部である場合、Zen ではさらにアンダースコア文字 “_” の後にタプル番号を追加します。
このように、生成された Zen ページのソースを表示すると、spacer_23 のように生成された ID 値が <div> 要素に囲まれていることがわかります。以下にその例を示します。
<div class="spacer" id="spacer_23" style="width:20px;"/>
以下のより複雑な抜粋では、ラジオ・ボタンの繰り返しグループの各要素に対して、一意の HTML ID 値を Zen で指定する方法を示しています。この抜粋は、SAMPLES ネームスペースのクラス ZENDemo.FormDemoOpens in a new tab を Zen で表示する際の結果となるページの一部です。
<tr valign="top">
<td style="padding: 4px; padding-left: 5px; padding-right: 5px;" >
<span id="zenlbl_26" class="zenLabel" >Marital Status:</span>
<div class="zendiv" id="MaritalStatus" >
<input type="hidden" id="hidden_26" name="$V_MaritalStatus" value="">
<span class="radioSetSpan"><input type="radio" id="textRadio_1_26"
name="r26" value="S" onclick="zenPage.getComponent(26).clickItem(1);">
<a class="radioSetCaption" id="caption_1_26" href=""
onclick="javascript:zenPage.getComponent(26).clickItem(1);return false;">
Single</a> </span>
<span class="radioSetSpan"><input type="radio" id="textRadio_2_26"
name="r26" value="M" onclick="zenPage.getComponent(26).clickItem(2);">
<a class="radioSetCaption" id="caption_2_26" href=""
onclick="javascript:zenPage.getComponent(26).clickItem(2);return false;">
Married</a> </span>
<span class="radioSetSpan"><input type="radio" id="textRadio_3_26"
name="r26" value="D" onclick="zenPage.getComponent(26).clickItem(3);">
<a class="radioSetCaption" id="caption_3_26" href=""
onclick="javascript:zenPage.getComponent(26).clickItem(3);return false;">
Divorced</a> </span>
<span class="radioSetSpan"><input type="radio" id="textRadio_4_26"
name="r26" value="W" onclick="zenPage.getComponent(26).clickItem(4);">
<a class="radioSetCaption" id="caption_4_26" href=""
onclick="javascript:zenPage.getComponent(26).clickItem(4);return false;">
Widowed</a> </span>
<span class="radioSetSpan"><input type="radio" id="textRadio_5_26"
name="r26" value="O" onclick="zenPage.getComponent(26).clickItem(5);">
<a class="radioSetCaption" id="caption_5_26" href=""
onclick="javascript:zenPage.getComponent(26).clickItem(5);return false;">
Other</a> </span>
</div>
</td>
</tr>
クライアント側で %MakeId と同等なものは、makeId という JavaScript メソッドです。カスタム・メータ・コンポーネントの例で、makeId を使用しています。
HTML 要素の検索
クライアント側コードを記述していて、ページ上の特定の HTML 要素にアクセスする必要がある場合は、findElement メソッドを使用します。このメソッドの引数は、ページにコンポーネントを配置する際に id 属性に割り当てた値です。findElement は、この文字列と、出力ページの要素の連続番号の識別子を組み合わせて、出力ページの要素に対して適切な HTML ID を生成します。この情報を使用して、表示するページのページ・オブジェクト・モデルにあるコンポーネント・オブジェクトへのポインタを取得し、そのポインタを返して、コンポーネント・オブジェクトのプロパティとメソッドを使用できるようにします。
通常の Zen コンポーネントは、%ZEN.Component.objectOpens in a new tab から findElement を継承します。SVG コンポーネントでは、%ZEN.SVGComponent.svgComponentOpens in a new tab の findSVGElement を使用する必要があります。カスタム・メータ・コンポーネントの例で、findSVGElement を使用しています。
findElement と findSVGElement は、%MakeId (サーバ) または makeId (クライアント) を使用して HTML ID 値を割り当てた場合にのみ、正常に動作します。
HTML 属性値の設定
%Attr サーバ側メソッドは、ページにコンポーネントを表示する HTML 要素の属性に値を割り当てます。このメソッドは、コンポーネントの表示に必要なすべての HTML 属性に値を割り当てるために、繰り返し呼び出すことができます。以下の %DrawHTML メソッドのサンプルでは、%Attr を <button> コンポーネントの表示に使用しています。
Method %DrawHTML()
{
Set disabled = $S(..disabled:"disabled",1:"")
Set tIgnore("onchange") = ""
&html<<input type="button" class="#(..controlClass)#"
id="#(..%MakeId("control"))#" #(..%Attr("title",..title))#
#(..%Attr("name",..name))# #(..%Attr("value",..caption))#
#(disabled)# #(..%Attr("style",..controlStyle))#
#(..%GetEventHandlers(.tIgnore))#>>
}
<button> の controlStyle 属性の値が、現在は myActionStyle であるとします。%DrawHTML メソッドは HTML を出力するので、式は以下の形式になります。
#(..%Attr("style",..controlStyle))#
以下の出力を生成します。
style="myActionStyle"
HTML 要素へのイベント・ハンドラのアタッチ
%GetEventHandlers サーバ側メソッドは、指定されたコンポーネントのイベント・ハンドラ属性をすべて取得し、それを使用して、出力ページにそのコンポーネントを表示する HTML にイベント・ハンドラ属性をすべて書き出します。
%GetEventHandlers は、基になるプロパティがデータ型クラス %ZEN.Datatype.eventHandlerOpens in a new tab を使用して定義されているイベント・ハンドラ属性のみを検索できます。
Zen フォームのコントロール・コンポーネントに指定できるイベント・ハンドラ属性のリストは、"Zen コンポーネントの使用法" の “Zen コントロール” の章の “コントロールの属性” を参照してください。このリストに挙げられているイベントのタイプには、マウス移動、マウス・クリック、キー・クリックなどがあります。その他のタイプの Zen コンポーネントにはイベント・ハンドラがありますが、Zen コントロールでは、比較用に大規模なプールを 1 つ用意しています。
前述の章では、組み込み Zen コンポーネントのイベント・ハンドラを設定するために、対応するイベント・ハンドラ属性の値として JavaScript 式を指定する必要があることを説明しました。一般的に、この JavaScript 式は、このイベントの “ハンドラ” の役割をするクライアント側メソッドを呼び出します。もちろん、この方法でコンポーネントを設定する場合は、呼び出されるクライアント側メソッドも記述する必要があります。
カスタム・コンポーネントでは、各ユーザ・イベントと適切なハンドラを組み合わせる手順を追加する必要があります。この組み合わせは、カスタム・コンポーネントの %DrawHTML メソッドで行います。<image> コンポーネントの %DrawHTML メソッドを考えてみます。
Method %DrawHTML()
{
#; handle onclick directly
Set tIgnore("onclick")=""
Set tIgnore("onchange")=""
#; select image to display
Set tSrc = ..src
If (..streamId '= "") {
Set tSrc = ##class(%CSP.Page).Link(
"%25CSP.StreamServer.cls?STREAMOID="_$ZCVT(..streamId,"O","URL"))
}
#; disabled logic
Set tSrc = $Case(..disabled,0:tSrc,:$S(..srcDisabled="":tSrc,1:..srcDisabled))
&html<<img id="#(..%MakeId("control"))#"
#($S(..onclick="":"",1:"class=""imageLink"""))#
#(..%Attr("src",tSrc))#
#(..%Attr("title",..title))#
#(..%Attr("width",..width))#
#(..%Attr("height",..height))#
#(..%GetEventHandlers(.tIgnore))#
onclick="zenPage.getComponent(#(..index)#).imageClick();"/>>
}
上記の例では、イベント・ハンドラに関していくつか興味深いことが発生しています。以下の行では、onchange イベント・ハンドラに指定された値を検出しても、それらをすべて無視することを %GetEventHandlers に指示しています。
Set tIgnore("onchange") = ""
上記の例の onclick と onchange で示したように、%DrawHTML で直接処理するイベント・ハンドラのそれぞれに対して、このような行を 1 行指定する必要があります。そのうえで、例に示すように、%DrawHTML の最後で、参照によって変数 tIgnore を %GetEventHandlers に渡します。
#(..%GetEventHandlers(.tIgnore))#
上記の %DrawHTML の例では、onclick と onchange を無視するように %GetEventHandlers に要求していますが、その理由はそれぞれのケースで異なります。<image> は、ユーザ入力を受け付けないため、onchange を無視します。<image> は、すべての onclick イベントを同じ方法で処理するように設計されていて、Zen のプログラマはページ・クラスで異なる動作を指定できないため、onclick を無視します。したがって、%DrawHTML のコードでこのイベントを直接処理します。このように %DrawHTML で明白に無視されないイベント・ハンドラはすべて、Zen のプログラマが定義したとおり正確に、ページに書き出されます。
上記の例にある以下の式について考えてみます。
#($S(..onclick="":"",1:"class=""imageLink"""))#
この式では、ObjectScript の $SELECT 関数を使用して、リストにある式の中で True を返す最初の式を返します。提示された式を見てみます。<image> コンポーネントの onclick 属性値が空白の文字列の場合、この文は空白の文字列を記述します。それ以外の場合、この文は、以下の文字列を書き出すことで、出力ページの HTML 要素をフォーマットします。
class="imageLink"
以下の式では、クライアント側 HTML ページを送信して、対応する HTML 要素の上をユーザがマウスでクリックすると、それに反応してコンポーネントの imageClick メソッドを呼び出します。
onclick="zenPage.getComponent(#(..index)#).imageClick();"
imageClick メソッドは、<image> コンポーネント・クラスのクライアント側 JavaScript メソッドです。このメソッドは、JavaScript ヘルパー・メソッド zenInvokeCallbackMethod を使用して、この <image> コンポーネントの onclick コールバック・メソッドを呼び出します。imageClick メソッドは以下のようになります。
ClientMethod imageClick() [ Language = javascript ]
{
if (!this.disabled) {
// invoke callback, if present
zenInvokeCallbackMethod(this.onclick,this,'onclick');
}
}
ここで、zenInvokeCallbackMethod 引数は以下のとおりです。
-
this.onclick — コンポーネントの onclick 属性値 (クライアント側 JavaScript メソッドを呼び出す JavaScript 式)。
-
this — コンポーネント・オブジェクトへのポインタ。
-
'onclick' — イベントの HTML 名 (引用符が必要)。
これで、HTML 要素、イベント、およびそのハンドラ間の接続が完了します。カスタム・コンポーネントでサポートしようとするすべてのイベントに対して、同様の規約を指定する必要があります。
動的なコンポーネントの HTML
%DrawHTML は、実行時情報に応じて変化したり、SVG を使用して生成されたりするコンポーネントでは動作が異なります。
<calendar> は、静的な HTML を記述しないコンポーネントの例です。%DrawHTML メソッドは、ページでカレンダーの再描画が必要となるたびに呼び出される複雑な JavaScript メソッド renderContents に備えて、現在選択されている月や日などのプロパティ値の設定のみを実行します。renderContents とそのヘルパー・メソッドは、ユーザがカレンダーで現在選択している月と日に基づいて、動的な HTML 文の配列を生成します。詳細は、%ZEN.Component.calendarOpens in a new tab のクラス・コードについて調べてください。
カスタム・メソッド
コンポーネントはクラスなので、継承されたものにはないメソッドを定義できます。これらのメソッドの定義は、そのメソッドを使用する場所や方法に影響を与えます。これらの規則は Zen ページ内のメソッドに対するものなので、Zen コンポーネント・クラスのメソッドに対する規則とまったく同じです。次のテーブルは、Zen クラスのメソッドに対する規約をまとめたものです。詳細は、“Zen アプリケーション・プログラミング” の章の “Zen ページのメソッド” を参照してください。
可能な呼び出し元 | 実行場所 | コード言語 | キーワード | 名前付け規約 |
---|---|---|---|---|
クライアント | クライアント | JavaScript |
ClientMethod [Language = javascript] |
myMethod |
クライアント | サーバ (クライアント上で実行するコードを返送できるもの) | ObjectScript、Caché Basic、Caché MVBasic | [ZenMethod] | MyMethod |
サーバ | サーバ | ObjectScript、Caché Basic、Caché MVBasic | — | %MyMethod |
カスタム・コンポーネント・クラスで最も重要なメソッドは、必須のサーバ側メソッド %DrawHTML です。前のセクションでは、このメソッドの使用方法について説明しています。次のセクションでは、カスタム・コンポーネント・クラスでオーバーライドできるその他のメソッドについて説明します。具体的な内容は次のとおりです。
%OnDrawEnclosingDiv
コンポーネントのサブクラスで定義されている場合、このコールバック・メソッドは、サブクラスが実行時にコンポーネントのエンクロージング <div> 要素に追加の HTML 属性を挿入できるようにします。%OnDrawEnclosingDiv は、入力引数は受け取りません。実装すると、メソッドが %StringOpens in a new tab 値を返します。既に <div> 要素を変更している可能性がある他の属性との競合を防ぐために、文字列の先頭にスペースを付ける必要があります。
%OnDrawTitleOptions
.expando クラスは、サーバ側コールバック・メソッド %OnDrawTitleOptions を提供します。これは .expando のサブクラスで定義されると、<expando> の framed 属性が True に設定されている場合、タイトル・バーの右側にコンテンツを追加する方法を提供します。%OnDrawTitleOptions で記述された HTMLは、<expando> が表示されるときにそのタイトル・バーに挿入されます。詳細は、"Zen コンポーネントの使用法" の “ナビゲーション・コンポーネント” の章にある “<expando>” を参照してください。
データのドラッグ・アンド・ドロップ・メソッド
"Zen の使用法" の “Zen コンポーネントの概念” の章にある “ドラッグ・アンド・ドロップ” の説明に従って、ページにコンポーネントを配置するたびに、コンポーネント属性 onafterdrag、onbeforedrag、ondrag、および ondrop の値を指定できます。ただし、Zen アプリケーションの開発者がコンポーネントごとにデータのドラッグ・アンド・ドロップ属性を設定する必要はなく、ユーザがカスタム・コントロール・コンポーネントに必要な動作を組み込むことができます。この方法によって、ページにコンポーネントを配置する際に、開発者は必要な動作が組み込まれたカスタム・コントロールを選択できます。
カスタム・コントロール・クラスのデータのドラッグ・アンド・ドロップをカスタマイズする場合は、オーバーライド可能なベース・クラス %ZEN.Component.componentOpens in a new tab および %ZEN.Component.controlOpens in a new tab に一連のメソッドがあります。これらのメソッドはそれぞれ 1 つのパラメータ dragData を受け取ります。これは、メソッドとプロパティが Zen クライアント側のライブラリで定義されている JavaScript オブジェクトへのポインタです。また、これらのメソッドは、ZLM.setDragAvatar などのライブラリ内で定義されている関数も呼び出します。これらの項目の詳細は、このドキュメントの “クライアント側ライブラリ” の章を参照してください。
ライブラリは、生成されたクラス・ドキュメントを容易にしない JavaScript で記述されているので、InterSystems のオンライン・ドキュメント・システムにはライブラリのクラス・リファレンス・ドキュメントがありません。詳細は、“クライアント側ライブラリ” の章を参照してください。
以下のテーブルは、ソースの Zen コンポーネントとターゲットの Zen コンポーネント間でドラッグ・アンド・ドロップが行われた際の内部イベントのシーケンスをトレースします。これらのイベントの間、ソース・コンポーネント・クラスとターゲット・コンポーネント・クラス内の特定の JavaScript メソッド は、Zen クライアント側ライブラリ内の特定の JavaScript 関数を呼び出します。コンポーネント・メソッドは、Zen フレームワークによって自動的にトリガされます。カスタム・コントロール・クラスのデータのドラッグ・アンド・ドロップをカスタマイズするときに、これらのメソッドが自動的に呼び出された際のメソッド内での動作の詳細を変更できます。
User | クライアント側ライブラリ | コンポーネント・メソッド | |
---|---|---|---|
1 | ソース・コンポーネントからドラッグを開始します。 | ||
2 | ソース・コンポーネントの dragHandler メソッドを呼び出します。 | ||
3 | ドラッグによって転送されるデータを保持するために、dragData という zenDragData オブジェクトを作成します。 | ||
4 | ソース・コンポーネントの onbeforedrag イベントが定義されていれば呼び出します。onbeforedrag イベントが False を返すか、dragData 値が設定されていない場合は、ドラッグはキャンセルされて、dragHandler が終了します。 | ||
5 | ソース・コンポーネントの dragStartHandler メソッドを呼び出します。このメソッドでは、個々のコンポーネントの既定のドラッグ処理が実装されています。dragStartHandler は、False を返すことでドラッグをキャンセルできます。 | ||
6 | ソース・コンポーネントの ondrag イベントが定義されていれば呼び出します。これにより、コンポーネントはドラッグ・データを修正するか、ドラッグをキャンセルすることができます。ondrag イベントが False を返すと、ドラッグはキャンセルされます。 | ||
7 | ターゲット・コンポーネントにドロップします。 | ||
8 | ターゲット・コンポーネントの dropHandler メソッドを呼び出します。 | ||
9 | ターゲット・コンポーネントの ondrop イベントが定義されていれば呼び出します。ondrop イベントが False を返すと、dropHandler メソッドは終了します。 | ||
10 | ターゲット・コンポーネントの dropStartHandler メソッドを呼び出します。このメソッドでは、個々のコンポーネントの既定のドロップ処理が実装されています。dropStartHandler は、False を返すことでドロップをキャンセルできます。 | ||
11 | ソース・コンポーネントにドラッグが完了したことを通知するために、ソース・コンポーネントの dragNotifyHandler メソッドを呼び出します。 | ||
12 | dragNotifyHandler はソース・コンポーネントの dragFinishHandler メソッドを呼び出し、ソース・コンポーネントの onafterdrag イベントが定義されていれば呼び出します。 |
オーバーライドするために設計されているベース・クラス %ZEN.Component.componentOpens in a new tab および %ZEN.Component.controlOpens in a new tab には、いくつかメソッドがあります。以下の数セクションで、これらのメソッドを示します。前のテーブルの他のメソッドは Zen フレームワークの一部であるため、これらはカスタマイズしないことをお勧めします。オーバーライドするために設計されたメソッドは、以下のとおりです。
getDragData
getDragData は、ユーザが任意のコントロールまたは <image> コンポーネントでドラッグ操作を開始するたびに自動的に呼び出される JavaScript メソッドです。他のコンポーネントは getDragData メソッドをサポートしていません。コントロール・コンポーネントのベース・クラス %ZEN.Component.controlOpens in a new tab は、以下の例のような getDragData ベース・バージョンを実装しています。その目的は、dataDrag オブジェクトの text フィールドおよび value フィールドを設定するためです。
ClientMethod getDragData(dragData) [ Language = javascript ]
{
dragData.value = this.getValue();
if (null != this.text) {
// if there is a text property, use it as the text value
dragData.text = this.text;
}
else {
dragData.text = dragData.value;
}
return true;
}
%ZEN.Component.controlOpens in a new tab のサブクラスは、getDragData をオーバライドしてカスタマイズされた動作を提供できます。メソッドが True を返す前に dataDrag.text および dataDrag.value の値が設定されていれば、メソッド内の動作は何でもかまいません。以下の例は、%ZEN.Component.imageOpens in a new tab が getDragData をオーバーライドする方法を示しています。このメソッドによって、ドラッグ可能な論理値と表示値の両方として <image> text 属性の文字列値が割り当てられます。
ClientMethod getDragData(dragData) [ Language = javascript ]
{
dragData.value = this.text;
dragData.text = this.text;
return true;
}
dragStartHandler
dragStartHandler は、コンポーネント内でドラッグ操作が開始されるたびに自動的に呼び出される JavaScript メソッドです。コントロール・コンポーネントのベース・クラス %ZEN.Component.controlOpens in a new tab は、以下の例のような dragStartHandler メソッドのベース・バージョンを実装しています。dragStartHandler メソッドは、以下を実行します。
-
getDragData を呼び出して、dragData.text および dragData.value を設定します。
-
ページでドラッグされる際にフィールドを表すために、アバター (icon) を作成します。
-
"クライアント側ライブラリ" 関数 (ZLM.setDragAvatar) を呼び出して、このアイコンを使用します。
ClientMethod dragStartHandler(dragData) [ Language = javascript ]
{
// get drag data
if (!this.getDragData(dragData)) {
return false;
}
// avatar
var icon = this.getEnclosingDiv().cloneNode(true);
icon.style.position="absolute";
icon.style.border ="1px solid darkgray";
icon.style.background ="#D0D0F0";
ZLM.setDragAvatar(icon);
return true;
}
%ZEN.Component.controlOpens in a new tab のサブクラスは、dragStartHandler をオーバライドしてカスタマイズされた動作を提供できます。例えば、クラス %ZEN.Component.abstractListBoxOpens in a new tab は、次の例に示すように、dragStartHandler をオーバーライドします。この例は、以下を実行します。
-
getDragData の呼び出しはいずれも省略します。
-
ドラッグを開始する特定のリスト項目へのポインタ (dragItem) を取得します。
-
リスト・コントロール内のこのアイテムへの正確なポインタ (anchor) を検索します。
-
dragData オブジェクトの sourceItem、value、および text の各フィールドを設定します。
-
ページでドラッグされる際にフィールドを表すために、アバター (icon) を作成します。
-
"クライアント側ライブラリ" 関数 (ZLM.setDragAvatar) を呼び出して、このアイコンを使用します。
ClientMethod dragStartHandler(dragData) [ Language = javascript ]
{
var ok = false;
var dragItem = this._dragSource;
if (null != dragItem) {
delete this._dragSource;
var anchor = this.findElement('item_' + dragItem);
if (anchor) {
dragData.sourceItem = dragItem;
ok = true;
dragData.value = this.getOptionValue(dragItem);
dragData.text = this.getOptionText(dragItem);
// avatar
var icon = anchor.cloneNode(true);
icon.style.position ="absolute";
icon.style.width = this.getEnclosingDiv().offsetWidth + 'px';
icon.style.border = "1px solid darkgray";
ZLM.setDragAvatar(icon);
}
}
return ok;
}
dragFinishHandler
dragFinishHandler は、このコンポーネント内で開始されたドラッグ操作が完了するたびに自動的に呼び出される JavaScript メソッドです。このメソッドは、ユーザが “ドラッグ” 操作を行うためにマウス・ボタンを押し続けた後にマウス・ボタンを放すと同時に実行されます。dragFinishHandler は、この時点でソース・コンポーネントに関して残っている可能性がある処理を完了できます。
dropStartHandler
dropStartHandler は、コンポーネント内でドロップ操作が開始されるたびに自動的に呼び出される JavaScript メソッドです。コントロール・コンポーネントのベース・クラス %ZEN.Component.controlOpens in a new tab は、以下の例のような dropStartHandler ベース・バージョンを実装しています。ターゲット・コントロールの値に dragData.toString() が設定されます。この値は、クラス内の別のドラッグ・アンド・ドロップ・メソッドの操作によって以前に設定されたものです。通常、この値はソース・コントロールから取得されます。
ClientMethod dropStartHandler(dragData) [ Language = javascript ]
{
this.setValue(dragData.toString());
return true;
}
%ZEN.Component.controlOpens in a new tab のサブクラスは、カスタマイズされた動作を提供するために dropStartHandler をオーバライドできます。例えば、クラス %ZEN.Component.listBoxOpens in a new tab は、次の例に示すように、ベース・コントロール dropStartHandler をオーバーライドします。この例は、以下を実行します。
-
dragData オブジェクトから value フィールドおよび text フィールドを取得します。
-
この <listBox> が他のコンポーネントからドロップを受け取っている場合は、以下のようになります。
以下のことを実行するために、appendOption を呼び出します。
-
論理値と表示値として value および text の各フィールドを持つ新しいリスト・オプションを作成する
-
この新しいオプションを <listBox> に追加する
-
<listBox> を再表示する
-
-
この <listBox> がそれ自体からドロップを受け取っている場合は、以下のようになります。
-
クライアント側ライブラリ関数の ZLM.getDragInnerDestination を呼び出して、ドラッグ操作が終了した最も内側のエンクロージング <div> の識別子を取得します。
-
これを使用して、適切な dragData.targetItem 識別子を算出します。
-
以下のことを実行するために、moveOption を呼び出します。
-
位置 dragData.sourceItem にあるリスト・オプションを識別された位置 dragData.targetItem に移動する
-
領域を確保するために、その他のリスト・オプションを配置する
-
<listBox> を再表示する
-
-
ClientMethod dropStartHandler(dragData) [ Language = javascript ]
{
var value = dragData.value;
var text = dragData.text;
if (this != dragData.sourceComponent) {
// drag from another component: append
this.appendOption(value,text);
}
else {
// move item within this list
var tgtId = ZLM.getDragInnerDestination().id;
var tgtIndex = -1;
if (tgtId && tgtId.indexOf('item')!=-1) {
tgtIndex = tgtId.split('_')[1];
}
dragData.targetItem = tgtIndex;
var srcIndex = dragData.sourceItem;
this.moveOption(srcIndex,tgtIndex);
}
return true;
}
サンプル・コード
以下は、タイトル・バーを定義するカスタム・コンポーネントの例です。この例は、SAMPLES ネームスペースの ZENDemo パッケージのものです。
Class ZENDemo.Component.demoTitle Extends %ZEN.Component.component
{
/// XML namespace for this component.
Parameter NAMESPACE = "http://www.intersystems.com/zendemo";
/// Domain used for localization.
Parameter DOMAIN = "ZENDemo";
/// Title displayed within this pane.
Property title As %ZEN.Datatype.caption;
/// Category displayed within this pane (above the title).
Property category As %ZEN.Datatype.caption
[ InitialExpression = {$$$Text("ZEN Demonstration")} ];
/// defines style sheet used by this component
XData Style
{
<style type="text/css">
.demoTitle {
color: black;
background: #c5d6d6;
width: 100%;
padding: 0px;
border-bottom: 1px solid darkblue;
font-size: 1.4em;
font-family: verdana;
text-align: center;
}
</style>
}
/// Draw the HTML contents of this component.
Method %DrawHTML()
{
Set tCategory = ..category
&html<<table class="demoTitle" border="0" cellpadding="0" cellspacing="0"
width="100%">
<tr>
<td align="left" width="40">
<img width="185" height="60" src="images/zentitle.jpg"/>
</td>
<td align="left" width="90%" style="padding-left:20px;">
<div style="font-size: 0.6em;">#($ZCVT(tCategory,"O","HTML"))#</div>
<div>#($ZCVT(..title,"O","HTML"))#</div></td>
<td> </td></tr></table>>
}
}
タイトル・バーのカスタム・コンポーネントを定義する目的は、Web アプリケーションの各ページで外観を統一するためです。ZENDemo パッケージのページ・クラスには、カスタム・コンポーネントを参照する正しい方法の例が多数用意されています。正しい参照を指定する XData Contents ブロックは、以下のようになります。
XData Contents [XMLNamespace="http://www.intersystems.com/zen"]
{
<page xmlns="http://www.intersystems.com/zen"
xmlns:demo="http://www.intersystems.com/zendemo"
title="Control Test">
<demo:demoTitle id="title"
title="Zen Control Test Page"
category="Zen Test Suite" />
<!-- more page contents here -->
</page>
}
以下はその説明です。
-
<page> 要素は、開いている <page> 要素内に以下の属性を指定することにより、カスタム・コンポーネントに定義されたネームスペースを参照し、そのエイリアスを定義します。
xmlns:demo="http://www.intersystems.com/zendemo"
この文は、完全なネームスペース名のエイリアス demo を定義します。
-
<demo:demoTitle> 要素は、demoTitle カスタム・コンポーネントを参照します。この参照の形式は以下のとおりです。
<alias:component>
ここで、alias は <page> 要素で定義されたネームスペースのエイリアス (この場合は demo)、component はカスタム・コンポーネント・クラスの名前 (この場合は demoTitle) です。
SAMPLES ネームスペースには他にも、カスタム・コンポーネントとこれらのコンポーネントへの参照の例があります。スタジオで、これらのクラスについて調べることができます。カスタム・コンポーネント・クラスの例には、以下のものがあります。
-
%ZEN.Component.compositeOpens in a new tab のサブクラスである ZENDemo.Component.demoMenuOpens in a new tab
-
%ZEN.Component.componentOpens in a new tab のサブクラスである ZENDemo.Component.sidebarOpens in a new tab
-
%ZEN.Component.objectOpens in a new tab のサブクラスである ZENDemo.Component.bulletOpens in a new tab
-
%ZEN.Component.controlOpens in a new tab のサブクラスである ZENTest.customComponentOpens in a new tab
-
%ZEN.SVGComponent.svgComponentOpens in a new tab のサブクラスである ZENTest.customSVGComponentOpens in a new tab
カスタム・メータの作成
以下のテーブルは、カスタム・メータ・コンポーネントを構築する際のチェックリストです。このテーブルの情報を補足するには、以下の Zen コミュニティのページで公開されているオドメーター、時計、およびカスタム・メータの例を参照してください。
http://www.intersystems.com/community/zenOpens in a new tab
タスク | 説明 |
---|---|
サブクラス | %ZEN.SVGComponent.meterOpens in a new tab を拡張して、新しいクラスを作成します。 |
renderMeter | %ZEN.SVGComponent.meterOpens in a new tab のどのサブクラスであっても、メータ・クラスから SVG を呼び出してメータの SVG コンテンツを表示するには、このメソッドをオーバーライドする必要があります。 |
パラメータ | (オプション) DEFAULTHEIGHT や DEFAULTVIEWBOXHEIGHT などのクラス・パラメータを指定して、適切な値に設定します。 |
プロパティ | (オプション) 必要に応じてプロパティを指定します。例えば、オドメーターでは、表示する桁の最大数を設定します。時計では、メータが表示されるたびに現在の時刻を計算する ObjectScript 式で、基本のメータ・クラスの value プロパティをオーバーライドできます。 |
XData SVGStyle | (オプション) メータに任意の CSS スタイル定義を指定します。 |
XData SVGDef | (オプション) メータに任意の SVG 定義を指定します。 |
setProperty | (オプション) このメソッドをオーバーライドして、メータの特定のプロパティを設定する一意の方法を指定できます。時計の例では、前述の value プロパティに対してこの処理を実行し、その他すべてのプロパティの設定に対してはスーパークラスまで実行を延期できます。 |
メソッド | (オプション) コンポーネントの動作での必要に応じて、サポートするメソッドを指定します。 |
renderLabel | (オプション) %ZEN.SVGComponent.meterOpens in a new tab のサブクラスはいずれも、このメソッドをオーバーライドして、メータ・ラベルの x と y の位置を設定できます。 |
XML 要素 | ページにコンポーネントを追加するには、ページの XData Contents ブロックに XML 要素として配置します。 |