一般に、XPages の開発は、データを定義するフォームおよびデータをレポートするビューの 2 つのレガシー設計要素に依存しています。しかし、この 2 つの設計要素は絶対的な要件ではありません。JavaScript を使用して、コントロールと Lotus Domino データ・ストア間でデータを移動することができます。JavaScript は難しくありません。
JavaScript によるアプローチは、次のような理由から避けられることがあります。
- フォームとビューを使用すれば、複雑な構造をビジュアルに定義できる。
- 必要なフォームとビューを配置した後は、開発を快適に進められる。たとえば、フォーム上のフィールドを XPage 上のコントロールにドラッグするだけで、フィールドをコントロールにバインドできる。
- XPages を既存の IBM Lotus Domino Designer アプリケーションに組み込む場合は、既存のフォームとビューを活用したくなることがある。
しかし、Lotus Domino Designer を初めて使用する方にとっては、フォームとビューの設計を学習することが負担となります。たとえ Lotus Domino Designer を知っていても、フォームとビューを扱うには、XML パラダイムを抜け出す必要があります。@関数と LotusScript® を使用することになるでしょう。
この記事では、IBM Lotus Domino アプリケーションでの、JavaScript を使用した文書の作成、表示、編集、および削除を取り上げます。これらの文書から、XPage 上のコントロールにデータを結び付ける方法を説明します。
また、XPages での JavaScript の概要についても紹介します。XPages での JavaScript の大きな特長は、広範囲に及ぶライブラリーにアクセスし、ユーザー環境およびバックエンドのデータ・ソースを容易に操作できることです。LotusScript に習熟している開発者であれば、NotesSession、NotesDatabase、NotesDocument、および他の多くの Lotus Domino オブジェクトを知っています。JavaScript では、これらと同じオブジェクトを利用できるだけでなく、ソース・コードへの組み込みがより簡単になっています。
この記事の最後では、XPages ユーザー・インターフェース (UI) で JavaScript を利用するときの場所と方法について説明します。JavaScript を使用して、値 (たとえば、計算結果フィールド) を返すことができます。また、JavaScript をイベント (たとえば、ボタンの onclick イベント) に適用することもできます。さらに、JavaScript を使用して、プロパティー (たとえば、コントロールの Visual プロパティーの true または false) を定義することも可能です。
Lotus Domino Designer を起動し、アプリケーションを作成します。左側のアプリケーション名の下(ナビゲーション)で、「XPages」を右クリックして「新規 XPage」を選択します。XPage に「main」という名前を付け、「OK」をクリックします。この操作によって、ページの中央にエディターが表示され、右側にコントロールのセットが表示されます。コントロールが表示されない、または何らかの理由でそのタブが閉じられている場合は、「ウィンドウ」->「Eclipse ビューの表示」->「コントロール」によってコントロールを再び表示できます。
この新規ページでの最初の設計オペレーションとして、コントロールから中央のパレットに計算結果フィールドをドラッグします (コントロールでスクロールダウンが必要な場合があります)。あるいは、計算結果フィールドをダブルクリックして、エディター内に表示することもできます。計算結果フィールドにフォーカスを置き、「プロパティー」タブを選択すると、画面は図 1 のようになります。
図 1. 計算結果フィールド・コントロールが配置された XPage

それでは、この計算結果フィールドに値をセットしましょう。「プロパティー」で「値」を選択し、「JavaScript」を選択します。表示されるウィンドウに直接スクリプトを入力することもできますが、ウィンドウの右側にある「スクリプト・ダイアログを開く」ボタンをクリックしましょう (図 2 参照)。
図 2. 値をセットするために JavaScript を選択

図 3 に示すように、スクリプト・エディターの左側にグローバル・オブジェクトが表示されています (「参照」タブが選択されていない場合は選択してください。また、「グローバル・オブジェクト」が選択されていない場合は、「ライブラリー」のドロップダウン・メニューから「グローバル・オブジェクト」を選択してください)。リストをスクロールダウンし、「session」をダブルクリックします。エディターに「session」が表示されます。ピリオドを入力し、少し待ちます。メソッドのリストが表示されるので、スクロールダウンして「getCommonUserName(): string」をダブルクリックします。
図 3. session グローバル・オブジェクト用のコンテンツ・アシスト

グローバル・オブジェクトは、Lotus Domino サーバー上の XPages JavaScript で利用できるオブジェクト階層へのエントリー・ポイントです。session オブジェクトは、Lotus Domino セッションとその基礎となるオブジェクトへのアクセスを提供します。左側の「参照」で session を開きます (図 4 参照)。エディターで「session」に続けてピリオドを入力したときに表示されたメソッドと同じメソッドが表示されます。
図 4. 「参照」ペインでの session オブジェクトの展開

次に、「ライブラリー」のドロップダウン・リストで「Domino」を選択します。スクロールダウンして NotesSession を開きます。図 5 に示すリストと同じリストが再び表示されます。実際、session グローバル・オブジェクトは、現在のユーザーの Lotus Domino NotesSession オブジェクトです。
図 5. 「参照」ペインでの Lotus Domino NotesSession オブジェクトの展開

コードを調整して、次のようにします。
return "Hello " + session.getCommonUserName()
return キーワードは暗黙的に指定されるため、コードは次のように記述することもできます。
"Hello " + session.getCommonUserName()
「OK」をクリックし、スクリプト・エディターを閉じて編集内容を保存します。
「設計」->「Web ブラウザーでのプリビュー」 (または、「Web ブラウザーでのプリビュー」ショートカット) を選択し、ブラウザーを選択することで、これまでの手作業をプリビューすることができます (最初に、少なくとも作成者特権を持つ「Anonymous」をアプリケーションの ACL に追加する必要があります)。ご使用になっているコンピューターで、Lotus Domino によって、プリビュー用に miniserver が起動されます。
プリビューされるページの URL は「http://localhost/foo.nsf/main.xsp」という形式になっています。前にプリビューを行い、Lotus Domino Designer がまだ実行されている場合は、miniserverがまだ実行中であるため、この URL を直接ブラウザーに入力できます。アプリケーションが Lotus Domino サーバーに置かれている場合は、「localhost」ではなく、サーバー名を使用してください。
Lotus Domino Designer 8.5.1 の時点では、「設計」->「Lotus Notes でのプリビュー」 (または、「Lotus Notes でのプリビュー」ショートカット) を選択することもできます。
Lotus Notes® で XPage でアプリケーションを起動するよう設定するには、ナビゲーターの一番下で「アプリケーションのプロパティー」を選択します。アプリケーションのプロパティーが表示されたら、「起動」タブを選択します。「起動」オプションで「指定された XPage を開く (標準クライアント)」を設定し、最初に表示するXPage を指定します。
アプリケーションの起動後に、1 つの XPage から別の XPage に移動する方法については後述します。XPage 以外の設計要素にいる場合は、次の式で示す形式の Lotus Notes URL を適用できます (次の例は、ビュー内のアクションです)。
@URLOpen("notes:///foo.nsf/main.xsp?OpenXPage")
サーバー上では、次のようにサーバー名を挿入します。
@URLOpen("notes://myserver/foo.nsf/main.xsp?OpenXPage")
データの取り扱いの説明に進む前に、もう 1 つ説明しておきたい項目があります。エディターの下の「ソース」を選択します (図 6 参照)。XPageを定義している XML が表示されます。ビジュアル・エディターで作業する代わりに、この XML を直接編集できます。「設計」を選択すると、ビジュアル・エディターに戻ります。
図 6. XPage のソース XML

最初の計算結果フィールドの下に、別の計算結果フィールドを配置します。Enter を押し、もう 1 つの計算結果フィールド・コントロールをダブルクリックするかドラッグします。「プロパティー」タブの「値」をクリックした後、「JavaScript」をクリックし、「スクリプト・ダイアログを開く」ボタンをクリックします。
再び、スクリプト・エディターが表示されます。スクリプト・エディターは開かなくてもかまいません。前述のように、「JavaScript」ボタンの下のウィンドウでスクリプトを編集できます (図 2 参照)。また、「ソース」タブを使用して、XML でスクリプトを編集することもできますが、スクリプト・エディターを使用するとスペースが広くなり、左側には「参照」タブと「アウトライン」タブが表示されます。
「参照」タブの「グローバル・オブジェクト」をスクロールダウンし、「database」をダブルクリックします (図 7 参照)。エディター内に「database」が表示されたら、それに続けてピリオドを入力し、メソッドのリストが表示されるのを待ちます。database は、非常に役に立つもう 1 つのグローバル変数です。このグローバル変数によって、現在のデータベース (つまり、この XPage を含むアプリケーション) の NotesDatabase オブジェクトが作成されます。
図 7. database グローバル・オブジェクト用のコンテンツ・アシスト

「getAllDocuments(): NotesDocumentCollection」をダブルクリックします。もう一度ピリオドを入力すると、NotesDocumentCollection オブジェクトに属するメソッドのリストが表示されます。この中に「getCount(): int」があります。このメソッドをダブルクリックし、もう一度ピリオドを入力します。今度は、String クラスのメソッドのリストが表示されます。これは、標準ライブラリーに含まれているものです。「toFixed(): string」をダブルクリックします。この時点で、スクリプトは次のようになっています。
database.getAllDocuments().getCount().toFixed()
このスクリプトは、現在のデータベースに含まれるすべての文書の数を文字列として取得します。スクリプトを次のように変更します。
return "Number of documents in database: "+
database.getAllDocuments().getCount().toFixed()
「OK」をクリックして保存し、プリビューします。新しいアプリケーションでは、プリビューしてもデータベース内に文書がありません。
参考として (サンプル・アプリケーションの一部ではありません)、指定されたデータベースに含まれる文書の数を取得するコードを以下に示します。session.getDatabase への最初のパラメーターはサーバーの名前です。null はローカル・システムを意味します。2 番目のパラメーターはアプリケーションの名前で、Lotus Notes データ・ディレクトリーからの相対パスで記述します。
return session.getDatabase(null, "fooA.nsf").getAllDocuments().getCount().toFixed()
そして、ローカルの Lotus Notes ディレクトリーにあるすべての NSF アプリケーションの名前を取得するコードをリスト 1 に示します。session.getDbDirectory によって返されるオブジェクトの型は NotesDbDirectory です。その getFirstDatabase メソッドと getNextDatabase メソッドによって、NotesDatabase 型のオブジェクトが返されます。
リスト 1. すべての NSF アプリケーションの名前を取得するコードs
var list = "";
var dir = session.getDbDirectory(null);
var db = dir.getFirstDatabase(1247); // 1247 = type DATABASE
while (db != null) {
if (!list.isEmpty()) list = list + ", ";
list = list + db.getFileName();
db = dir.getNextDatabase();
}
return list |
文書を作成するための最初のタスクは、XPage からユーザー・データを取得することです。この目的のために 2 つのフィールドを作成しましょう。1 つは文字列で、もう 1 つは数値です。
- 2×2 の表を作成します。「コンテナー・コントロール」の表コントロールを使用します。
- 初の列に、「subject」と「number」というラベルを持つ 2 つのラベル・コントロールを配置します。
- 2 番目の列に、編集ボックス・コントロールを配置します。
ビジュアル・エディターは図 8 のように表示されます。
図 8. subject と number 用の編集ボックス

もちろん、編集ボックスを使うアイデアは、ユーザーに入力してもらうためです。では、このデータにどのような方法でアクセスするのでしょうか。Lotus Domino フォームを用いて XPage をバックアップしているのであれば、それぞれの編集ボックスをフォーム上のフィールドにバインドする方法があります。この方法については、この記事の最後で簡単に説明します。プログラマチックな目的では、各フィールドをグローバル変数にバインドします。
最初の編集ボックスにフォーカスを置き、「プロパティー」タブの「データ」を選択します。「詳細」を選択します。ドロップダウン・リストで「スコープ変数」を選択します。「パラメーター」フィールドで、リストから「要求の範囲」を選択します。最後に、変数名を指定します。この変数は subject という名前にしましょう。図 9 を参照してください。
図 9. スコープ変数へのフィールドのバインディング

URL 要求に基づいてサーバーがページを処理するときに、ページでこの変数を利用できます。サーバーが URL 要求の処理を終了すると、この変数はスコープを失い、メモリーが解放されます。ドロップダウン・リストを見ると、4種類のスコープ変数があることがわかります。スコープの広い順に、「アプリケーションの範囲」、「セッションの範囲」、「表示範囲」、「要求の範囲」です。
同様の方法で、2 番目の編集ボックスを、number という名前の「要求の範囲」変数にバインドします。ここで、もう 1 つ指定が必要です。この入力値を数値データとして扱いたいので、表示タイプを「数値」に変更することが重要です。図 10 を参照してください。
図 10. 数値型のスコープ変数へのフィールドのバインディング

それでは、文書を作成する作業を始めましょう。決して難しくありません。
編集ボックスの下にボタン・コントロールを配置します。ラベルを「Create document」に変更します。
「イベント」タブを選択します。このコントロールで使用できるイベントが左側に表示されています。デフォルトで強調表示されている onclick を使用します。次に、「サーバー」タブが選択されていることを確認し(デフォルトで選択されています)、「スクリプト・エディター」を選択します。図 11 を参照してください。
図 11. ボタンのイベントの指定

ウィンドウ内に直接スクリプトを入力できます。あるいは、右側の「スクリプト・ダイアログを開く」ボタンをクリックします。この操作によって、左側に「参照」タブのあるモーダル・スクリプト・エディターが表示されます。
リスト 2 にスクリプトを示します。
リスト 2. 文書を作成する JavaScript
var doc = database.createDocument();
doc.replaceItemValue("subject", requestScope.subject);
doc.replaceItemValue("number", requestScope.number)
doc.save();
requestScope.subject = null;
requestScope.number = null |
1 行目で NotesDocument オブジェクトを作成します。その次の 2 つの行で、編集ボックス・コントロールにバインドされたグローバル変数に基づくアイテム値をセットしています。指定方法が、スコープ、ピリオド、変数名の順番になっていることに注意してください。ここでは、ユーザーがこれらのボックスに値を入力したことを前提としています。また、subject と number が引用符で囲まれています。これは開発者が指定する部分で、文書内のアイテムの名前を記述します。save メソッドが実行されるまで、データ・ストアでは何も起こりません。最後に、古い値を UI に表示しないように、また将来のイベントに影響を与えないように、スコープ変数をクリアします。
ページを保存してプリビューします。subject と number に入力し、「Create document」をクリックします。ボタンのクリックにより、ページ情報を持つ URL が Lotus Domino サーバー (または、プリビューの場合は miniserver) に送られます。サーバーがイベント・コードを処理し、処理後のページをブラウザー (または Lotus Notes クライアント) に返します。何回か試してみると、文書数が増加することがわかります。
文書数が増加するのを見ると、そこで何かが起きていることがわかります。詳細を調べると役に立ちます。一般に、レガシー Lotus Domino でデータを表示するには、ビュー設計要素を使用します。XPages には、ビュー設計要素を組み込むビュー・コントロールがあります。ただし、ここではデータ表コントロールと簡単な JavaScript を使用します。
ボタンの下にフォーカスを置きます。「コンテナー・コントロール」でデータ表コントロールをダブルクリックするか、ドラッグします。「プロパティー」で「JavaScript」を選択し、文書のコレクションを返すスクリプトを入力します。コレクション名の rowdoc を指定することが、この例における 2 番目の重要なポイントです。図 12 を参照してください。
図 12. データ表コントロールの指定

データ表は、指定されたコレクション上で機能します。この例では、データベース内のすべての文書のコレクションが返されます。全文検索や文書のサブセットを返すなど、プログラミングでコレクションを変更する方法はたくさんあります。
データ表の内部で右クリックし、「列の挿入」または「列の追加」を選択します。表示された列が 3 つの行を持っていることに注目してください。一番上と一番下の行は静的な特性を持ち、この行に配置した要素のコピーが1つ含まれます。一番上の行をヘッダーとして使用します。「subject」というラベルを持つラベル・コントロールを挿入してください。
中央の行は、本質的には繰り返しコントロールです。繰り返しコントロールは役に立ちます。データ表の場合、繰り返しコントロールによって複数の行が生成されます。行数はベース・コレクションに含まれるオブジェクト数に応じて変わります。それぞれの行は、コレクションの 1 つのメンバーを表します。この例では、現在のデータベース内のすべての文書を含む NotesDocumentCollection コレクションを使用します。コレクションの各メンバーは NotesDocument 型のオブジェクトです。コレクション名が rowdoc であることを思い出してください。この名前は、現在の行、つまりユーザーが現在操作している行に対応する NotesDocument オブジェクトを示しています。
中央の行にフォーカスを置きます。「コア・コントロール」で、計算結果フィールド・コントロールをダブルクリックするか、ドラッグします。「プロパティー」タブの「値」を選択します。値として、「JavaScript」を選択してスクリプトを入力します。スクリプトでは、rowdoc (前述したように NotesDocument オブジェクト) の getItemValueString メソッドを使用して subject アイテムの値を取得します。図 13 を参照してください。
図 13. 繰り返し行のための値の指定

コンテンツ・アシストについて付け加えます。残念ながら、rowdoc の後にピリオドを入力しても、メソッドのリストは表示されません。エディターが rowdoc の型を認識できないからです。参照ペインまたはドキュメンテーションを使用し、メソッド名を正確に入力するよう注意してください。参照ペインでメソッドをダブルクリックすることにより、そのメソッドをエディター内に表示できます。あるいは、型を識別する補助的なコード行を最初に入力することで、強制的にコンテンツ・アシストを機能させる方法を適用することもできます。たとえば次のコードでは、rowdoc が NotesDocument 型であるとコンテンツ・アシストによって認識され、メソッドのリストが表示されます。
rowdoc:NotesDocument == null;
return rowdoc.
プリビューすると、「subject」という列ヘッダーを持つ 1 列の表が表示されます。また、現在のデータベースに含まれる各文書の subject 値が表示されます。
列ではなく、データ表にフォーカスを置き、右クリックして「列の追加」を選択します。前述と同じ手順を実行し、number アイテム用の列を作成します。今度の計算結果フィールド用のスクリプトは次のようになります。
return rowdoc.getItemValueDouble("number")
最後に、更新日を表示する 3 番目の列を追加します。スクリプトは以下のとおりです。
return rowdoc.getLastModified()
プリビューすると、subject、number、および最終更新日を示す 3 つの列が表示されます。
既存の文書を編集する方法を追加しましょう。
データ表に別の列を追加します。ボタン・コントロールをダブルクリックするか中央の行までドラッグし、そのラベルを「edit」にします。「イベント」タブを選択し、onclick と「サーバー」タブが選択されていることを確認して、「スクリプト・エディター」を選択します。次のスクリプトを入力します。
sessionScope.docUnid = rowdoc.getUniversalID();
requestScope.subject = rowdoc.getItemValueString("subject");
requestScope.number = rowdoc.getItemValueDouble("number")
このコードは、グローバル変数の値として、文書のユニバーサル ID と 2 つのアイテムの値をセットします。ユニバーサル ID は 2 つの要求にわたって使用されるため、sessionScope 変数であることが必要です。
最後の 2 つの変数は編集ボックスにバインドされています。ユーザーが「edit」ボタンをクリックすると、URL が Lotus Domino サーバーに送られます。サーバーは、2 つの編集ボックスにデータ表の行からの値がセットされたページを送り返します。ユーザーはこのデータを編集できます。ユーザーが 2 番目の行の「edit」ボタンをクリックしたときのようすを図 14 に示します。
図 14. 編集用にデータの行を取得

次に、置換用のボタンが必要となります。このボタンを「Create document」ボタンの横に配置し、「Replace document」というラベルを付けます。「Create document」ボタンをコピー・アンド・ペーストして作成を始めることもできます。この onclick イベントに、リスト 3 の JavaScript コードを使用します。このコードは、最初の行を除いて「Create document」ボタンと同じコードであり、文書を作成する代わりに、ユニバーサル ID を使用して既存の文書を取得します。
リスト 3. 文書内の値を置換する JavaScript
var doc = database.getDocumentByUNID(sessionScope.docUnid);
doc.replaceItemValue("subject", requestScope.subject);
doc.replaceItemValue("number", requestScope.number)
doc.save();
requestScope.subject = null;
requestScope.number = null |
また、次のコードを持つ「Cancel」ボタンを作成するとよいでしょう。このボタンは、データベースを変更せずに、編集ボックスをブランクにします。
requestScope.subject = null;
requestScope.number = null
使いやすさを向上させるために、「edit」ボタンの onclick イベントに次のコード行を追加します (省略可能)。
sessionScope.editMode = true
さらに、「Replace document」ボタンと「Cancel」ボタンの onclick イベントに次のコード行を追加します。
sessionScope.editMode = false
この追加により、ユーザーが編集中のときにのみ、グローバル変数 editMode が true になります。それ以外の場合は、初期化されていない状態または false となります。それでは、上記の表の上にある 3 つのボタンのプロパティーに移ります。「表示」プロパティーにアクセスします。ひし形をクリックし、「値の計算」を選択します。「Create document」ボタンには、次のスクリプトを使用します。
sessionScope.editMode != true
「Replace document」ボタンおよび「Cancel」ボタンには、次のスクリプトを使用します。
sessionScope.editMode == true
これで、「Create document」ボタンが表示されているときにのみ、ユーザーは文書に移ることができます。ユーザーが「edit」ボタンをクリックすると、「Create document」ボタンが非表示となり、それ以外の 2 つのボタンが表示されます。
文書の削除も簡単です。列をもう 1 つ追加し、中央の行にボタンを配置します。ボタンのラベルを「remove」にします。ボタンの onclick イベントに次のコードを使用します。
rowdoc.remove(true)
これまでに見てきたコードは、すべてサーバー・サイドのコードです。これらのコードは、ブラウザーまたは Lotus Notes クライアントがページをサーバーに渡した後で実行されます。JavaScript は例外をほとんど持たない標準ですが、追加のライブラリー、特に Domino オブジェクトのライブラリーにアクセスできます。
また、クライアント・サイドの JavaScript も作成できます。このコードは、ページがサーバーに渡される前に、ブラウザーまたは Lotus Notes クライアントで実行されます。JavaScript は、ユーザーが使用しているクライアントの標準であり、標準 Web DOM にアクセスできます。
同じイベントに対し、サーバー・サイドとクライアント・サイドの両方のスクリプトを提供できます。クライアント・サイド・スクリプトは false を返すことにより、サーバー・サイド・オペレーションの実行を防止できます。
このサンプル・アプリケーションでは、クライアント・サイド・スクリプトを使用して文書の削除を確認することができます。もう一度、「remove」ボタンの onclick イベントに移動します。このイベントには、すでにサーバー・コードが記述されています。図 15 に示すように、「クライアント」タブを選択し、「スクリプト・エディター」を選択して次のコードを入力します。
return window.confirm(“Do you really want to delete this document?”)
図 15. イベントのクライアント・サイド・コード

ユーザーがこのボタンをクリックすると、クライアント・サイド・スクリプトによって確認ウィンドウが表示されます。「OK」をクリックすると true が返され、サーバー・サイド・スクリプトが実行されます。「キャンセル」をクリックすると false が返され、サーバー・サイドのコードは実行されません。
ユーザーが別のページからデータを送信する、より一般的なシナリオについて考えてみましょう。始める前に、main XPage のコピーを作成しておくとよいでしょう。
「create」という名前の XPage を作成します。編集ボックスを持つ 4×4 の表を main XPage ページから切り取り、create XPage に貼り付けます。「Create document」ボタンと「Cancel」ボタンを main XPage からコピーし (切り取りではありません)、 create XPage に貼り付けます。create XPage でフォーカスを「Create document」ボタンに置き、ボタンのラベルを「Submit」に変更します。どちらのボタンも、常に表示されるよう「表示」プロパティーを変更します。図 16 を参照してください。
図 16. 文書を作成する XPage

編集ボックスはそのままで正しい状態になっていますが、ボタンのコードは調整が必要です。Submit ボタンの onclick イベントでスクリプト・エディターを開きます。文書を作成する最初の 4 行は同じように機能します。このページから移動するので、編集ボックスを空にする 2 つの行は不要です。最後に、ユーザーを main ページに戻すための 1 行を追加する必要があります。コードはリスト 4 のようになります。
リスト 4. 文書を作成し、別のページを開く JavaScript
var doc = database.createDocument();
doc.replaceItemValue("subject", requestScope.subject);
doc.replaceItemValue("number", requestScope.number)
doc.save();
context.redirectToPage("main") |
context グローバル・オブジェクトは、XSP ライブラリーにある XSPContext 型のオブジェクトです。
「Cancel」ボタンについては、既存のコードを取り除き、「Submit」のスクリプトの最後の行で置き換えます。つまり、ユーザーを main ページに移動します。しかし、このタスクを行う別の方法として、シンプル・アクションを使用する方法があります。このボタンの onclick イベントに移動します。「シンプル・アクション」を選択し (警告が表示された場合は「OK」をクリック)、「アクションの追加」を選択します。表示されるウィンドウで、アクションが「ページを開く」になっていることを確認します。必要であれば、ドロップダウン・メニューから選択してください。開くページとして、ドロップダウン・メニューから「main」を選択します。「OK」をクリックします。図 17 を参照してください。
図 17. 別のページを開くシンプル・アクション

参考のために記しますが、main ページに戻る 3 番目の方法があります。ボタンを「キャンセル」タイプに設定し、すべてのイベント・コードを削除します。ページの「プロパティー」タブを選択し、「次頁 (更新の失敗時)」を「main」に設定します。
それでは、main XPage に戻り、フォーカスを「Create document」ボタンに置きます。onclick イベントのコードを削除します (先へ進む前に、必ず削除してください)。このボタンがクリックされたときに、ユーザー をcreate XPage に移動させます。これには、JavaScript の次のコードを使用します。
context.redirectToPage("create")
または、シンプル・アクションを使用することもできます。
ページをプリビューします。「Create document」をクリックします。データをいくつか入力します。「Submit」ボタンを試してみます。また、「Cancel」ボタンも試してみます。
次に、「replace」という名前の XPage を作成します。create XPage からすべてをコピーし、replace に貼り付けます。このページでは、編集ボックスのバインディングを sessionScope 変数に変更する必要があります。これは、データが複数の要求を越えて渡されるためです。
「Submit」ボタンは調整が必要です。文書を作成する代わりに、main XPage で設定されたユニバーサル ID を使用して既存の文書を取得します。また、グローバル変数を sessionScope に変更しなければなりません。sessionScope 変数を使用した後は、リスト 5 に示すように、これらの変数に null をセットします。
リスト 5. 文書内の値を置換し、別のページを開く JavaScript
var doc = database.getDocumentByUNID(sessionScope.docUnid);
doc.replaceItemValue("subject", sessionScope.subject);
doc.replaceItemValue("number", sessionScope.number);
doc.save();
sessionScope.subject = null;
sessionScope.number = null;
context.redirectToPage("main") |
main XPage に戻り、sessionScope 変数を使用して現在のアイテム値を設定し、replace XPage を開くよう「edit」ボタンを変更します。リスト 6 を参照してください。
リスト 6. 既存の文書を編集するためにページを開く JavaScript
sessionScope.docUnid = rowdoc.getUniversalID();
sessionScope.subject = rowdoc.getItemValueString("subject");
sessionScope.number = rowdoc.getItemValueDouble("number");
context.redirectToPage("replace") |
これで、main、create、replace という 3 つのページができました。ユーザーがアプリケーションを開くと main が表示されます。「Create document」ボタンをクリックすると、空の編集ボックスがある create ページに移動します。送信または取り消しアクションを行うと、main に戻ります。「edit」ボタンをクリックすると、データを含む入力ボックスがある replace ページに移動します。再び、送信または取り消しアクションを行うと、main に戻ります。
リッチ・テキストには特別の注意が必要です。変数を単純にセットまたは取得することができません。このセクションのコードをすぐに理解しなくても、レシピとして使用できます。
create フォームで、ダブルクリックまたはドラッグすることにより、リッチ・テキスト・コントロールを編集ボックスとボタンの間に配置します。必要に応じてサイズを調整してください。「プロパティー」タブの「データ」タブを選択し、「詳細」を選択し、「body」という名前の「要求の範囲」変数にコントロールをバインドします。
「Submit」ボタンの onclick イベントに移動します。リスト 7 と同じ内容になるようにスクリプトを調整します。新しいコードは、4 行目 (NotesStream オブジェクトの作成) から始まり、8 行目 (オブジェクトを閉じる) で終わります。リッチ・テキスト・コントロールにバインドされた requestScope.body グローバル変数の型は com.ibm.xsp.http.MimeMultipart です。その getHTML メソッドによって、リッチ・テキスト・コントロールの内容を XML として取得します。次に、バックエンドでリッチ・テキスト・アイテムを NotesMIMEEntity オブジェクトとして作成し、コントロールからの XML コンテンツを使用してオブジェクトの値をセットします。NotesStream オブジェクトは仲介として必要です。
リスト 7. リッチ・テキストを含む文書を作成する JavaScript
var doc = database.createDocument();
doc.replaceItemValue("subject", requestScope.subject);
doc.replaceItemValue("number", requestScope.number)
var stream = session.createStream();
stream.writeText(requestScope.body.getHTML());
var entity = doc.createMIMEEntity("body");
entity.setContentFromText(stream,"text/html;charset=UTF-8", 1725);
stream.close()
doc.save();
context.redirectToPage("main") |
バックエンドからリッチ・テキスト・コントロールにデータを取得するには、NotesMIMEEntity の getContentAsText メソッドを使用します。replace ページで、create ページと同様にリッチ・テキスト・コントロールを編集ボックスの下に追加します。ただし、requestScope 変数ではなく、「body」という名前の sessionScope 変数にこのコントロールをバインドします。main ページで、「edit」ボタンの onclick イベントに移動します。リスト 8 と同じ内容になるように、イベントのコードを調整します。新しいコードは 4 行目から 6 行目までです。バックエンドからリッチ・テキスト文書を NotesMIMEEntity オブジェクトとして取得し、その getContentAsText メソッドを使用して、リッチ・テキスト・コントロールに値をセットします。6 行目のコピーは、replace ページでの比較のために後で必要となります。
リスト 8. リッチ・テキストを含む既存の文書を編集するためにページを開く JavaScript
sessionScope.docUnid = rowdoc.getUniversalID();
sessionScope.subject = rowdoc.getItemValueString("subject");
sessionScope.number = rowdoc.getItemValueDouble("number");
var entity = rowdoc.getMIMEEntity("body");
sessionScope.body = entity.getContentAsText();
sessionScope.bodyCopy = sessionScope.body;
context.redirectToPage("replace") |
replace ページで「Submit」ボタンを修正する必要があります。リッチ・テキスト・コントロールの値が変更された場合のみ、その値を書き出すようにします。create XPage からコードをコピー・アンド・ペーストできますが、必要な変更を行うように注意してください。リスト 9 を参照してください。
リスト 9. リッチ・テキストを含む文書内で値を置換する JavaScript
var doc = database.getDocumentByUNID(sessionScope.docUnid);
doc.replaceItemValue("subject", sessionScope.subject);
doc.replaceItemValue("number", sessionScope.number)
if(!sessionScope.body.toString().equals(sessionScope.bodyCopy.toString())) {
var stream = session.createStream();
stream.writeText(sessionScope.body.getHTML());
var entity = doc.getMIMEEntity("body");
entity.setContentFromText(stream,"text/html;charset=UTF-8", 1725);
stream.close();
}
doc.save();
sessionScope.subject = null;
sessionScope.number = null;
sessionScope.body = null;
context.redirectToPage("main") |
仕上げと比較のために、データをフォームにバインドし、JavaScript を使用せずに、create ページと replace ページを再設計してみましょう。既存の設計を保存したい場合は、XPage のコピーを作成します。
ナビゲーターで「フォーム」を右クリックし、「新規フォーム」を選択します。新しいフォームに「main」という名前を付け、「OK」をクリックします。「作成」->「フィールド」を使用して 3 つのフィールドを作成します。名前が「subject」で種類が「文字」、名前が「number」で種類が「数値」、名前が「body」で種類が「リッチ・テキスト」の 3 つです。図 18 を参照してください。
図 18. 3 つのフィールドがあるフォーム

フィールドはフォーム内の任意の場所に配置できます。この例では外観にはこだわりません。フォームを保存します。
create XPage を開きます。XPage 自体にフォーカスを置き、「プロパティー」タブの「XPage」を選択し、「次頁 (完了または取り消し)」を「main」に指定します。このように選択すると、「Submit」ボタンまたは「Cancel」ボタン (後述します) が実行された後に、main ページがブラウザー (または Lotus Notes クライアント) に送られます。図 19 を参照してください。
図 19. 次に開くページの指定

「データ」を選択し、Lotus Domino 文書データ・ソースを追加します。現在のアプリケーションと main フォームを指定し、さらにデフォルトのアクションとして「文書の作成」を指定します。「document1」という名前はそのまま残しておきます。この設定により、フォームが XPage のデータ定義のソースとなります。図 20 を参照してください。
図 20. フォームを Xpage のデータ・ソースとして指定

まず、最初の編集ボックスにフォーカスを置きましょう。「単純データ・バインディング」を選択します。データ・ソースとして「document1」を指定し、コントロールを「subject」にバインドします。この参照は、main フォームの subject フィールドに対するものです。同じ手順を 2 番目の編集ボックスにも行いますが、「number」にバインドする点だけが異なります。図 21 を参照してください。また、このバインディングは、右側のデータ・パレットからフィールドをコントロールにドラッグすることによっても行うことができます。
図 21. フォーム上のフィールドへのコントロールのバインディング

リッチ・テキスト・コントロールにフォーカスを置きます。これを「body」にバインドします。現在、XPage コントロールは、フォーム上で定義されたデータにバインドされています。
最初のボタンを「送信」タイプに変更します。「イベント」で、すべてのイベント・コードが削除されていることを確認します。このタイプのボタンには、コードが必要ありません。図 22 を参照してください。
図 22. 「送信」タイプのボタンの指定

2 番目のボタンを「キャンセル」タイプに変更します。同様に、すべてのイベント・コードまたはシンプル・アクションが削除されていることを確認します。
このプロセスによって create ページが処理されます。フォームのバインディングと特殊なボタン・タイプで JavaScript を置き換えています。
同様の方法で replace ページを再定義します。コントロールのデータ・バインディングは、create ページの場合と同じです。ボタンも同じです。唯一異なるのは、XPage データのデフォルト・アクションが「文書の編集」である点です。
main ページに移動します。「edit」ボタンの onclick イベントのコードを削除し、これを「ページを開く」シンプル・アクションとして再指定します。replace ページは「文書の編集」モードで開くことにします。rowdoc 変数 (データ表からの変数) を使用して編集する文書を計算し、編集したい文書の UNID を取得します (このために簡単な JavaScript が必要です)。図 23 を参照してください。
図 23. 文書を編集するためにページを開くシンプル・アクション

create ページを開く「Create document」ボタンは、そのまま残しておくことができます。「Replace document」ボタンと「Cancel」ボタンは削除できます。
これで準備が整いました。文書を作成および置換する JavaScript コードは除去されました。現在、これらの機能は、データをフォームにバインドするよう設計することにより実装されています。つまり、「送信」および「キャンセル」タイプのボタンを使用して、送信または取り消しアクション後の次のページをセットアップしています。JavaScript によるソリューションが最も簡単であるため、削除ボタンはそのまま残します。
また、ビュー設計要素を作成し、これをビュー・コントロールのベースとして、データ表の代わりに使用できます。「edit」および「remove」ボタンの機能は、ビュー内に作用させることができます。
Lotus Domino Designer は Lotus Notes プロトコルを使用して、バックエンドのデータを文書メモとして Lotus Domino アプリケーション (NSF ファイル) 内に維持しています。従来からの方法では、フォームおよびビューと呼ばれる設計要素を通じてアクセスを行います。フォームは、データ自体と文書の表示方法の両方を定義しています。また、ビューは、文書のコレクションを表示または操作する手段です。
一方、XPages 設計要素には、ユーザー・インターフェース全体が組み込まれています。データを定義するために、XPages コントロールをフォーム上のフィールドにバインドするという方法を選択できます。あるいは、JavaScript および Domino オブジェクトを通じてデータにアクセスすることもできます。同様に、ビューを使用すると文書の集合へのアクセスと表示が可能ですが、これも、データ表と JavaScript を使用して設計できます。
- ディスカッション・フォーラムに参加してください。
-
Take the developerWorks tutorial, "XPages, Themes, and Mashups in IBM Lotus Domino Web application development."
-
Take the developerWorks tutorial, "Harness the power of XPages in Lotus Domino Designer."
-
Contribute to the Lotus Notes and Domino Application Development wiki.
-
Contribute to the IBM Lotus Domino wiki.
-
Refer to the developerWorks IBM Lotus Notes and Domino product page.
-
Refer to the IBM Lotus Notes and Domino Information Center.
Robert Perron is a technical writer with IBM Lotus in Littleton, Massachusetts. He has developed documentation for Lotus Notes and Domino since the early 1990s with a primary concentration on programmability. He developed the documentation for the LotusScript and Java Domino Objects and co-authored the book 60 Minute Guide to LotusScript 3 - Programming for Notes 4. He has authored several articles for LDD Today (developerWorks) and The View. He has currently turned his attention to XPages.