セクションを追加または削除するボタンを作成する

インタラクティブなフォームデザインでは、ユーザーが選択するまで表示されないセクションをフォーム内に 1 つまたは複数設けることが一般的です。Designer では、スクリプトを定義したボタンを追加して、ユーザーがボタンをクリックするとフォームの特定のセクション(サブフォーム)がダイナミックに追加または削除されるように設定できます。

例えば、サンプルのインタラクティブ発注書フォームでは、ユーザーが「コメントを追加」ボタンをクリックすると、コメントセクション(comments サブフォーム)が表示されます。このボタンには現在のサブフォームの状態に応じて「コメントを追加」または「コメントをクリア」のどちらかのキャプションが表示され、その表示は交互に切り替わります。ユーザーがボタンをクリックするたびに、スクリプトが comments サブフォームの表示状態をチェックし、その結果に応じてボタンのキャプションを更新します。

ボタンによって実行されるスクリプトでは、XML フォームオブジェクトモデルのオブジェクトである instanceManager が使用されています。このオブジェクトは、フォームオブジェクトのインスタンスの作成、削除および移動を管理します。エンドユーザーが Comment サブフォームを削除すると、 instanceManager オブジェクトは、フォームデータの文書オブジェクトモデル(DOM)とデータ DOM の両方から、そのサブフォームを削除します。

instanceManager では、 addInstance removeInstance moveInstance および setInstances の 4 つのメソッドが使用されます。命名規則に従って、 instanceManager には、サブフォーム名の前にアンダースコアを加えた名前( _subformname )が付けられます。 instanceManager の構文は、 _subformname.methodname() です。

サンプルのインタラクティブ発注書フォームでは、スクリプトエディターを使用して次の JavaScript スクリプトが入力されています。このスクリプトは、 setInstances メソッドを使用して comments サブフォームの追加と削除、およびボタンのキャプションの変更を行います。 comments.count == 0 property はインスタンス化されたサブフォームインスタンスの数を返します。

// Invoke the Instance Manager to add and remove the comments subform. 
 
if (_comments.count == 0) {// The count property specifies the current number      
                                            // of instances instantiated. 
    _comments.setInstances(1);                                                // Add the comments subform. 
    this.resolveNode("caption.value.#text").value = "Clear Comments";                                                                                                            // Change the button's caption. 
} 
 
else { 
    _comments.setInstances(0);                                                // Remove the comments subform. 
    this.resolveNode("caption.value.#text").value = "Add Comments";                                                                                                            // Change the button's caption. 
}
ツールメニューのアクションビルダーダイアログボックスを使用すると、スクリプトを記述しないで、編集可能なレイアウトを含むフォームに一般的なインタラクティブ機能を作成できます。

追加ボタンおよび削除ボタンを作成する

インタラクティブフォームにボタンを追加すると、発注書フォームの項目行などのセクションを定義するサブフォームで、インスタンスの追加や削除などの操作をエンドユーザーが実行できるようになります。

また、削除ボタンにツールヒントを追加して、ユーザーがボタンの上にポインターを置くと「アイテムを削除」という文字列を表示させることもできます。行ごとに個別の削除ボタンを用意すると、ユーザーがフォームから特定の行を削除できて便利です。

例えば、サンプルのインタラクティブ発注書フォームには、それぞれの detail サブフォームについて、「アイテムを追加」ボタンと、削除ボタン(「X」というマークの付いたボタン)が含まれています。「アイテムを追加」ボタンをクリックすると、スクリプトによって項目行が 1 行追加されます。また、ユーザーがいずれかの削除ボタンをクリックすると、スクリプトによって関連付けられた項目行が削除されます。

ツールメニューのアクションビルダーダイアログボックスを使用すると、スクリプトを記述しないで、編集可能なレイアウトを含むフォームに一般的なインタラクティブ機能を作成できます。 フォームのアクションの作成 を参照してください。

「アイテムを追加」ボタン

「アイテムを追加」ボタンの click イベントに含まれる次のスクリプト(JavaScript)は、ユーザーがサンプルのインタラクティブ発注書フォームに項目行を追加できるよう定義されています。また、このスクリプトでは新しい行が Total フィールドの計算に含まれるようフォームを再計算します。

ユーザーは「アイテムを追加」ボタンを使用して項目行の追加のみ行うので、このスクリプトは最小(オカレンス)値を検証する必要がありません。

// Invoke the Instance Manager to add one instance of the detail subform. 
_detail.addInstance(1); 
 
//Invoke the recalculate method to include the field values from the added subform in calculations. 
xfa.form.recalculate(1);

削除ボタン

削除ボタンの click イベントに含まれる次のスクリプト(JavaScript)は、ユーザーがサンプルのインタラクティブ発注書フォームから detail サブフォームのインスタンスを削除できるよう定義されています。また、このスクリプトでは削除した行が Total フィールドでの計算に含まれないようフォームを再計算します。

// Invoke the Instance Manager to remove the current instance of the detail subform. 
_detail.removeInstance(this.parent.index); 
 
// Invoke the recalculate method to update the form calculations. 
xfa.form.recalculate(1);

detail サブフォームの最小オカレンス値の初期値は 2 なので、スクリプトで最小オカレンス値を減らし、フォームのレンダリング時に自動的に表示される 2 つの項目行をフォーム入力者が削除できるようにする必要があります。このスクリプトは detail サブフォームの initialize イベントに追加されます。

// Reset the minimum occurrence value of the detail subform. 
this.occur.min = "0";

このフォームではユーザーが detail サブフォームのすべてのインスタンスを削除できるので、Total フィールド( numTotal )の calculate イベントのスクリプトで、detail サブフォームに numAmount フィールドのインスタンスが少なくとも 1 つ存在することを検証する必要があります。検証しないと、計算時に numAmount フィールドのオカレンスを見つけられないので、エラーが表示されます。このスクリプトは、 numTotal フィールドの Calculate イベントに追加されます。

// Verify at least one instance of the numAmount field exists. 
if (exists(detail[0].numAmount) == 1) then 
    Sum(detail[*].numAmount) 
endif