Oracle® Fusion Middleware Oracle Application Development Framework Java EE開発者ガイド 11g Release 1 (11.1.1.7.0) B61007-05 |
|
前 |
次 |
この章では、「データ・コントロール」パネルを使用して、編集可能な表や入力表など、ADF Facesコンポーネントに基づいてデータバインドされた基本的な表を作成する方法について説明します。
この章の内容は次のとおりです。
フォームと異なり、表を使用すると、アクセッサによって返されたコレクションのデータ・オブジェクトを一度に複数表示できます。図4-1は、検索によって返された製品を含む、Suppliersモジュールのbrowseページの表を示しています。
単にデータを表示する表を作成することも、データの編集または作成が可能な表を作成することもできます。アクセッサを表としてドロップすると、選択した行に対してなんらかのロジックを実行するアクションにバインドされたコマンド・ボタンを追加できます。また、必要に応じてデフォルトのコンポーネントを変更することもできます。
フォームを構成する個々のUIコンポーネントをコレクションの個々の属性にバインドするフォームとは異なり、表では、ADF Facesのtable
コンポーネントをコレクション全体にバインドするか、コレクションから一度にn個のデータ・オブジェクトのレンジにバインドします。その結果、列にデータを表示するために使用される個々のコンポーネントが属性にバインドされます。イテレータ・バインディングによって各オブジェクトの適切なデータが表示され、table
コンポーネントによって各オブジェクトが行に表示されます。JDeveloperを使用すると、宣言的にこの処理を実行できるため、コードを記述する必要がありません。
データ・コントロールを使用して表を作成するには、返されるコレクションにtable
コンポーネントをバインドします。JDeveloperでは、「データ・コントロール」パネルからコレクションをドラッグ・アンド・ドロップして、宣言的にこの処理を実行できます。
ヒント: コンポーネント・パレットから表コンポーネントをドラッグし、ADF Faces Tableの作成ウィザードを完了して表を作成することもできます。詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』のページでの表の表示方法に関する項を参照してください。 |
データバインドされた表を作成する手順:
「データ・コントロール」パネルから、コレクションを選択します。
たとえば、システム内の製品を表示する簡単な表をSupplerモジュールで作成するには、productFindAll
アクセッサ・コレクションを選択します。
コレクションをJSFページにドラッグし、ポップアップ・メニューから適切な表を選択します。
コレクションをドラッグする場合、次の表のタイプから選択できます。
ADF表: 編集可能な表の列の表示に必要な特定の属性と、データの表示に使用するUIコンポーネントを選択できます。デフォルトでは、ADF inputText
コンポーネントはほとんどの属性で使用され、このコンポーネントにより、表は編集可能となります。日付である属性ではinputDate
コンポーネントが使用されます。さらに、属性にコントロール・タイプのコントロール・ヒントが作成されている場合、または属性がリストとして構成されている場合、ヒントにより設定されたコンポーネントが使用されます。コントロール・ヒントの設定の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』のビュー・オブジェクトの属性コントロール・ヒントの定義に関する項を参照してください。
ADF読取り専用動的表: 返されて表示される属性が実行時に動的に決定される表を作成できます。このコンポーネントは、対応するオブジェクトの属性が実行時まで不明な場合、あるいはJSFページに列名をハードコーディングしない場合に適しています。
次に表示される「表の列の編集」ダイアログには、コレクション内の各属性が表示されます。また、これらの属性がどのように動作し、表の列としてどのように表示されるかを定義できます。
注意: コレクションに構造化属性(Javaのプリミティブ・タイプまたはコレクションのいずれでもない属性)が含まれる場合、その構造化属性の属性も同様にダイアログに表示されます。 |
ダイアログを使用すると、次の操作ができます。
「行選択」チェック・ボックスの選択による、ADFモデル・レイヤーでの選択の処理。このオプションを選択すると、イテレータ・バインディングがイテレータにアクセスして選択した行を決定します。表での選択を実行しない場合以外は、このオプションを選択してください。
「ソート」チェック・ボックスの選択による、ADFモデル・レイヤーでの列のソート処理。このオプションを選択すると、イテレータ・バインディングがイテレータにアクセスし、order-by問合せを実行して順序を決定します。列のソートを実行しない場合以外は、このオプションを選択してください。
「フィルタリング」チェック・ボックスの選択による、入力した基準を使用した、表の列のフィルタリングの実行。このオプションを選択すると、各列の上にあるテキスト・フィールドに基準を入力できます。その後で、この基準を使用してコレクションへのQuery-by-Example(QBE)検索を作成すると、問合せによって戻された結果のみが表に表示されます。詳細は、7.5項「スタンドアロンのフィルタ処理された検索表の作成」を参照してください。
目的の属性(ダイアログでは行として表示)の選択および「グループ化」ボタンのクリックによる、親列下での選択した属性の列のグループ化。図4-2に、表の作成後、グループ化された2つの列がビジュアル・エディタでどのように表示されるかを示します。
テキストまたはEL式を入力して、ラベルの値を他のもの(リソース・ファイルのキーなど)にバインドすることによる、列の表示ラベルの変更。デフォルトでは、ラベルは表バインディング上の属性に定義されたすべてのコントロール・ヒントのlabels
プロパティにバインドされます。このバインディングにより、構造ファイルのラベル・テキストの値を1回のみ変更できます。また、その変更はラベルを表示するすべてのページに反映されます。
バインド対象に別の属性を選択することによる、列の値バインディングの変更。単に列を並べ替える場合は、順序ボタンを使用してください。列の属性バインディングを変更すると、列のラベルも変更されます。
ドロップダウン・メニューを使用した、属性の表示に使用されるUIコンポーネントの変更。UIコンポーネントは、コレクションをページにドロップしたときに選択した表と、対応する属性のタイプ(たとえば、日付である属性にはinputDate
コンポーネントを使用)、およびJavaクラスの構造ファイルでデフォルト・コンポーネントがコントロール・ヒントとして設定されているかどうかに基づいて設定されます。
ヒント: 表の属性の1つが主キーでもある場合、ユーザーが値を変更できないUIコンポーネントを選択します。 |
ヒント: ドロップダウン・メニューに表示されないコンポーネントを使用する場合は、このダイアログを使用して |
順序ボタンを使用した列の順序の変更。
「追加」アイコンを使用した列の追加。追加できる列の数に制限はありません。最初にアイコンをクリックすると、JDeveloperではダイアログの下部に新規列の行が追加され、そこにバインドされたコレクションの最初の属性の値が移入されます。後続の新規列には順序内の次の属性の値が移入され、その後も同様に続きます。
「削除」アイコンを使用した列の削除。
表をページにドロップした後は、プロパティ・インスペクタを使用して表に他の表示プロパティを設定できます。たとえば、表の幅を特定のパーセンテージまたはサイズに設定します。表示プロパティの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「表とツリーの使用」を参照してください。
ヒント: 表の幅を100%に設定すると、表には境界が含まれないため、表の実際の幅はさらに大きくなります。コンテナの幅の100%に表を設定するには、プロパティ・インスペクタの「スタイル」セクションを展開し、「ボックス」タブを選択して |
ユーザーが表の情報を編集し、変更を保存できるようにするには、変更を発行して保存する方法を指定する必要があります。詳細は、4.3項「編集可能な表の作成」を参照してください。ユーザーによるデータ入力が可能な表の作成手順は、4.4項「入力表の作成」を参照してください。
「データ・コントロール」パネルから表をドロップすると、テキスト・フィールドまたはフォームをドロップするのと同じ効果があります。要約すると、JDeveloperによって行われる処理は次のとおりです。
表のバインディングを作成し、ページ定義ファイルにそのバインディングを追加します。
UIコンポーネントに必要なコードをJSFページに追加します。
詳細は、3.2.2項「テキスト・フィールドの作成時の処理」を参照してください。
「データ・コントロール」パネルから表をドロップすると、ツリーの値バインディングが作成されます。ツリーはノードの階層で構成され、各サブノードは上位レベルのノードから分岐します。表の場合、フラット化された階層であり、各属性(列)は表のサブノードになります。フォームで使用される属性バインディングと同様に、ツリーの値バインディングによってアクセッサ・イテレータ・バインディングが参照される一方、アクセッサ・イテレータ・バインディングによってデータ・コントロールのイテレータが参照されます。これにより、コレクションのデータ・オブジェクト全体の反復が円滑に行われます。属性ごとに異なるバインディングが作成されるのではなく、表ノードへのツリー・バインディングのみが作成されます。ツリー・バインディングでは、表の各行で表示または参照に使用する各属性の子要素が、nodeDefinition
要素のAttrNames
要素に含まれています。
ツリーの値バインディングは、FacesCtrlHierBinding
クラスのインスタンスです。このクラスは、コアのJUCtrlHierBinding
クラスを拡張して、次の2つのJSF固有のプロパティを追加します。
collectionModel
: JSFおよびADF Facesで表などのコレクション値コンポーネントに使用するjavax.faces.model.DataModel
オブジェクトを拡張するオブジェクトによってラップされたデータを戻します。
treeModel
: collectionModel
を拡張し、実質的に階層構造であるデータを戻します。詳細は、第5章「マスター/ディテール・データの表示」を参照してください。
例4-1に、productFindAll
アクセッサ・コレクションをドロップすると作成される表の値バインディングを示します。単純にするために、コレクションのいくつかの属性のみを示します。
例4-1 ページ定義ファイルにおける表の値バインディング・エントリ
<bindings> <tree IterBinding="productFindAllIterator" id="productFindAll"> <nodeDefinition DefName="oracle.fodemo.supplier.model.Product"> <AttrNames> <Item Value="productId"/> <Item Value="productName"/> <Item Value="costPrice"/> <Item Value="listPrice"/> <Item Value="minPrice"/> <Item Value="productStatus"/> <Item Value="shippingClassCode"/> <Item Value="warrantyPeriodMonths"/> </AttrNames> </nodeDefinition> </tree> </bindings>
データにアクセスする必要があるのは表のみであるため、(列または個々のセル内のテキスト・コンポーネントではなく)モデルにバインドする必要があるのは表コンポーネントのみです。表のツリー・バインディングは表の個々の構造化属性にドリルダウンするので、表の列は表コンポーネントからその情報を導出できます。
「データ・コントロール」パネルを使用してJSFページに表をドロップすると、表バインディングで指定された各属性に対するADF Facesのcolumn
コンポーネントが含まれたADF Facesのtable
コンポーネントがJDeveloperによって挿入されます。各列には、属性の値にバインドされた別のコンポーネント(inputText
コンポーネントやoutputText
コンポーネントなど)が含まれます。各列のヘッダーは、属性のコントロール・ヒントのlabels
プロパティにバインドされます。
ヒント: 関連付けられている構造ファイルで属性が非表示としてマークされている場合、対応するUIは作成されません。 |
例4-2に、productFindAll
アクセッサ・コレクションを読取り専用表としてドロップして作成した表から抜粋した、簡略化されたコードを示します。
例4-2 ADF Faces表の簡略化されたJSFコード
<af:table value="#{bindings.productFindAll.collectionModel}" var="row" rows="#{bindings.productFindAll.rangeSize}" emptyText="#{bindings.productFindAll.viewable ? 'No data to display.' : 'Access Denied.'}" fetchSize="#{bindings.productFindAll.rangeSize}" rowBandingInterval="0" id="t1"> <af:column sortProperty="productId" sortable="false" headerText="#{bindings.productFindAll.hints.productId.label}" id="c1"> <af:outputText value="#{row.productId}" id="ot8"> <af:convertNumber groupingUsed="false" pattern="#{bindings.productFindAll.hints.productId.format}"/> </af:outputText> </af:column> <af:column sortProperty="productName" sortable="false" headerText="#{bindings.productFindAll.hints.productName.label}" id="c4"> <af:outputText value="#{row.productName}" id="ot7"/> </af:column> . . . </af:table>
ツリー・バインディングは、イテレータ・バインディングによって公開されたデータ全体を反復します。表の値は、collectionModel
オブジェクトにアクセスするcollectionModel
プロパティにバインドされています。表は、イテレータ・バインディングからの結果セットをcollectionModel
オブジェクト内にラップします。collectionModel
により、コレクションの各アイテムは、var
属性を使用して表コンポーネント内で使用できるようになります。
例では、表は、productFindAll
アクセッサ・バインディングの現在レンジの行全体を反復します。バインディングは、現在の行を追跡する行セット・イテレータにバインドします。表のvar
属性をrow
に設定すると、次のaf:outputText
タグの値に示すように、各列はrow
変数を使用して、表タグに示される現在行の現在データ・オブジェクトにアクセスします。
<af:outputText value="#{row.productId}"/>
行変数にバインドするかわりに、ADF表(ADF読取り専用表ではなく)をドロップすると、入力コンポーネントの値は、bindings
プロパティによってバインディング・コンテナ内の特定の行に暗黙的にバインドされます(例4-3を参照)。さらに、入力コンポーネントごとにバリデータ・コンポーネントとコンバータ・コンポーネントが追加されます。bindingsプロパティを使用すると、発生した例外を該当するバインド・オブジェクトにリンクできます。コントローラは、バインディング・コンテナ内のすべての例外を反復処理し、FacesMessage
オブジェクトの作成時にクライアントIDを取得するためのバインディング・オブジェクトを取得します。この取得により、表は、特定のセルのエラーを表示できるようになります。この方法は、リストなどの選択コンポーネントを含め、すべての入力コンポーネントに使用されます。
例4-3 入力コンポーネントを使用したバリデータとコンバータの追加
<af:table value="#{bindings.productFindAll.collectionModel}" var="row" rows="#{bindings.productFindAll.rangeSize}" emptyText="#{bindings.productFindAll.viewable ? 'No data to display.' : 'Access Denied.'}" fetchSize="#{bindings.productFindAll.rangeSize}" rowBandingInterval="0" selectedRowKeys="#{bindings.productFindAll1.collectionModel.selectedRow}" selectionListener="#{bindings.productFindAll1.collectionModel. makeCurrent}" rowSelection="single" filterModel="#{bindings.productFindAllQuery.queryDescriptor}" queryListener="#{bindings.productFindAllQuery.processQuery}" filterVisible="true" varStatus="vs" id="t1"> <af:column sortProperty="productId" sortable="false" headerText="#{bindings.productFindAll.hints.productId.label}" id="c5"> <af:inputText value="#{row.bindings.productId.inputValue}" label="#{bindings.productFindAll.hints.productId.label}" required="#{bindings.productFindAll.hints.productId.mandatory}" columns="#{bindings.productFindAll.hints.productId.displayWidth}" maximumLength="#{bindings.productFindAll.hints.productId.precision}" shortDesc="#{bindings.productFindAll.hints.productId.tooltip}" id="it4"> <f:validator binding="#{row.bindings.productId.validator}"/> <af:convertNumber groupingUsed="false" pattern="#{bindings.productFindAll.hints.productId.format}"/> </af:inputText> </af:column> . . . </af:table>
ADF Facesのバリデータとコンバータの使用方法の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「入力の検証および変換」を参照してください。
表4-1に、「データ・コントロール」パネルを使用して作成されるADF Faces表に対して、デフォルトで定義される他の属性を示します。
属性 | 説明 | デフォルト値 |
---|---|---|
|
一度に表示する行数を決定します。 |
デフォルトで、関連付けられたイテレータ・バインディングの |
|
戻す行がない場合に表示するテキスト。 |
イテレータの表示可能なプロパティに評価されるEL式。表が表示可能で、戻すオブジェクトがない場合、「表示するデータがありません」と表示されます。表が表示できない場合(表に対して認可の制限が設定されている場合など)は、「アクセスが拒否されました」と表示されます。 |
|
データソースからフェッチされるデータの行数。 |
デフォルトで、関連付けられたイテレータ・バインディングの |
|
表の選択の状態。 |
デフォルトでコレクション・モデルの選択された行に評価されるEL式。 |
選択イベントをリスニングするメソッドへの参照。 |
デフォルトでコレクション・モデルの |
|
|
行が選択可能かどうかを決定します。 |
一度に1行のみ選択するには |
列の属性 |
||
|
列のソート基準のプロパティを決定します。 |
列の対応する属性バインディング値に設定します。 |
|
ソートできる列かどうかを決定します。 |
|
|
列の上部に表示されるテキストを決定します。 |
デフォルトで、対応する属性に設定されたラベルのコントロール・ヒントに評価されるEL式。 |
アプリケーションで表を使用し、ADFモデル・レイヤーで行選択を管理できるようにする場合、現在行はイテレータによって決定されます。ユーザーがADF Faces表で行を選択すると、表の行が影付きになり、選択された行がコンポーネントによりイテレータに通知されます。そのためには、例4-4に示すように、表のselectedRowKeys
属性をコレクション・モデルの選択した行にバインドします。
例4-4 表の選択属性
<af:table value="#{bindings.Products1.collectionModel}" var="row" . . . selectedRowKeys="#{bindings.Products.collectionModel.selectedRow}" selectionListener="#{bindings.Products.collectionModel. makeCurrent}" rowSelection="single">
このバインディングは、表の選択したキーをコレクション・モデルの選択した行にバインドします。selectionListener
属性は、コレクション・モデルのmakeCurrent
プロパティにバインドされます。このバインディングは、コレクションの選択した行をイテレータの現在行に設定します。
注意: カスタム選択リスナーを作成した場合、コレクション・モデルの |
表は選択を自動的に処理できますが、オブジェクトの現在行をイテレータにプログラムで設定する必要がある場合があります。
getKey()
メソッドを任意のビュー行でコールして、行を識別する1つ以上のキー属性をカプセル化するKey
オブジェクトを取得できます。Key
オブジェクトは、findByKey()
による行セット内のビュー行の検索にも使用できます。実行時に、setCurrentRowWithKey
またはsetCurrentRowWithKeyValue
のいずれかの組込み操作がデータ・バインディング・レイヤーによって名前で起動されると、findByKey()
メソッドを使用して、パラメータとして渡された値に基づいて行が検索された後、検索された行が現在の行として設定されます。
setCurrentRowWithKey
操作およびsetCurrentRowWithKeyValue
操作ではいずれもrowKey
という名前のパラメータをとりますが、実行時にそのrowKey
パラメータに想定される値はそれぞれで異なります。
setCurrentRowWithKey
では、rowKey
パラメータ値に、ビュー行キーのシリアライズされた文字列表現が想定されています。これは、次のような16進エンコード文字列です。
000200000002C20200000002C102000000010000010A5AB7DAD9
キーのシリアライズされた文字列表現により、ブラウザのURL文字列またはフォーム・パラメータで単一値として渡すことができる方法で、ビュー行のキーを構成する可能性のあるすべてのキー属性がエンコードされます。実行時に、有効なシリアライズされた文字列キーではないパラメータ値を間違って渡すと、oracle.jbo.InvalidParamException
またはjava.io.EOFException
などの例外を結果として受け取る場合があります。Webページでは、ADFコントロール・バインディングのrowKeyStr
プロパティ(#{bindings.SomeAttrName.rowKeyStr}
など)またはADF Faces表の行変数(#{row.rowKeyStr}
など)を参照すると、行のシリアライズされた文字列キーの値にアクセスできます。
setCurrentRowWithKeyValue
操作では、rowKey
パラメータ値がビュー行のキーを表すリテラル値であると想定しています。たとえば、製品番号201
を検索する場合、この値は単に201
になります。
ユーザーが表内の情報を編集し、その変更をデータソースにコミットできるようにする表を作成できます。そのためには、返されるコレクション(またはデータ・コントロール自体)に関連付けられたデータ・レコードを変更できる操作を使用して、コマンド・ボタンを作成し、このボタンを表のツールバーに配置します。たとえば、browse.jspx
ページの表には、ユーザーが製品を削除できるボタンがあります。このボタンによって、現在は、ユーザーが削除を確定できるダイアログが表示されますが、製品を直接削除するメソッドにボタンをバインドすることもできます。
編集可能なフォーム同様、ADFモデル・レイヤーでは、コレクションの新規インスタンスが生成されるまで、行の変更が認識されないことに注意してください。したがって、変更をコミットするには、アクセッサ・イテレータで実行操作を起動する必要があります。詳細は、2.4.4項「イテレータの結果のキャッシュについて」を参照してください。
編集可能なコンポーネントを使用してデータを表示することにした場合、表に一度にすべての行を変更可能として表示するか、ユーザーが行内をダブルクリックするまですべての行を読取り専用として表示するかを選択できます。図4-3は、すべての行に編集可能フィールドがある表を示しています。ページは、ページに追加されたコンポーネント(inputText
、inputDate
、inputNumberSpinbox
コンポーネントなど)を使用してレンダリングされます。
図4-2は、同じ表ですが、データを編集または入力するにはユーザーが行をダブルクリック(または行がすでに選択されている場合はシングルクリック)する必要があるように構成されています。図4-3と同じ入力コンポーネントを使用してページは作成されていますが、outputText
コンポーネントを使用して選択されていない行のデータが表示されることに注意してください。これらのコンポーネントを実際にレンダリングする行は、編集のために選択された行のみです。
ADF Facesの表コンポーネントによる編集の処理方法の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の表、ツリーおよびツリー表のデータの編集に関する項を参照してください。
編集可能な表を作成するには、基本表の作成に類似した手順に従い、続いて操作にバインドされたコマンド・ボタンを追加します。ただし、表にツールバーを含めるには、表の作成に使用されたコレクションのアイテムとツールバーを関連付けるADF Facesコンポーネントを追加する必要があります。
編集可能な表を作成する手順:
「データ・コントロール」パネルから、表に表示するコレクションを選択します。
たとえば、システム内の仕入先を編集できる簡単な表をSuppliersモジュールに作成するには、supplierFindAll
アクセッサ・コレクションを選択します。
アクセッサをJSFページにドラッグし、ポップアップ・メニューから「ADF表」を選択します。
次に表示される「表の列の編集」ダイアログを使用して、属性がどのように動作し、表の列としてどのように表示されるかを決定します。「行選択」チェック・ボックスを必ず選択することにより、ユーザーは編集する行を選択できます。
このダイアログを使用して表を構成する方法の詳細は、4.2項「基本表の作成」を参照してください。
構造ウィンドウで表を選択し、プロパティ・インスペクタの「動作」セクションを展開してEditingMode属性を設定します。全行を編集可能にする場合は、editAllを選択します。ユーザーに1行をクリックさせてその行を編集可能にする場合は、clickToEditを選択します。
構造ウィンドウで、表コンポーネントを右クリックし、ポップアップ・メニューから「囲む」を選択します。
「囲む」ダイアログでは、ドロップダウン・リストで「ADF Faces」が選択されていることを確認し、「パネル・コレクション」コンポーネントを選択して「OK」をクリックします。
panelCollection
コンポーネントのツールバー・ファセットによりツールバーが保持され、そのツールバーによりデータの更新に使用されるコマンド・コンポーネントが保持されます。
構造ウィンドウで、panelCollection
のtoolbarファセット・フォルダを右クリックし、ポップアップ・メニューから「ツールバーの中に挿入」→「ツールバー」の順に選択します。
これにより、ユーザーが表の表示方法を変更できるデフォルトのメニューと、表全体の連結を解除する「連結解除」リンクをすでに含むツールバーが作成され、ブラウザ・ウィンドウの大部分を占めるように表示されます。panelCollection
コンポーネントの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の表メニュー、ツールバーおよびステータス・バーの表示に関する項を参照してください。
「データ・コントロール」パネルから、ロジックの実行対象となるオブジェクトのコレクションに関連付けられているメソッドまたは操作を選択し、構造ウィンドウのtoolbar
コンポーネントにドラッグします。これにより、データバインドされたコマンド・コンポーネントがツールバー内に配置されます。
たとえば、仕入先のレコードを削除する場合、removeSuppliers(Suppliers)
メソッドをドラッグします。図4-5は、Suppliersモジュールの削除メソッドを示しています。
ポップアップ・メニューから「操作」→「ADFツールバー・ボタン」を選択します。
「アクション・バインディングの編集」ダイアログで、メソッドのパラメータに値を移入する必要があります。削除メソッド(およびその他のデフォルト・メソッド)の場合、これが選択されるオブジェクトです。
「パラメータ」セクションで、「値」ドロップダウン・リストを使用して「EL式ビルダーの表示」を選択します。
式ビルダーで、アクセッサのイテレータのノードを展開して「currentRow」ノードを展開し、「dataProvider」を選択します。
これによって、アクセッサのイテレータで現在の行の値と評価されるEL式が作成されます。
「OK」をクリックします。
たとえば、suppliersFindAll
アクセッサを使用して表を作成した場合、JDeveloperによってsuppliersFindAllIterator
という名前のaccessorIterator
バインディングが作成されます。図4-8に示すように、そのイテレータの下の現在の行のdataProvider
オブジェクトを選択する必要があります。この参照は、パラメータ値が、現在選択されている行の値に解決されることを表します。
コレクションが変更されていることをADFモデル・レイヤーに通知するには、イテレータをリフレッシュするメソッドにツールバー・ボタンをバインドする必要もあります。
ファイルを右クリックして「ページ定義に移動」を選択し、JSPXファイルのページ定義を開きます。
ページ定義の構造ウィンドウで、「バインディング」を右クリックし、「バインディングの中に挿入」→「一般バインディング」→「アクション」を選択します。
「アクション・バインディングの作成」ダイアログで、「イテレータの選択」ドロップダウン・リストを使用してコレクションに関連付けるイテレータを選択し、「操作」に「実行」を選択します。
JDeveloperによって、イテレータのexecute
操作に対するアクション・バインディングが作成されます。次に、コマンド・ボタンでこの操作をコールする必要があります。
JSFページで、手順10でメソッドをドロップして作成したコマンド・コンポーネントを選択します。プロパティ・インスペクタで、「アクション」を次のように設定します。
#{bindings.Execute.execute}
コマンド・コンポーネントがクリックされると、actionListener
属性のバインディングの後でaction
属性へのバインディングが評価されます。この順序によって、エンティティの削除後にイテレータでリフレッシュや実行が行われることが保障されます。
編集可能な表の作成は、レコードの編集に使用するフォームの作成と類似しています。「データ・コントロール」パネルからドロップした操作に対してアクション・バインディングが作成されます。詳細は、3.6.2項「値を変更するメソッドの使用時の処理」を参照してください。
ユーザーが表に新しく空白行を挿入し、各列に値を追加することのできる表を作成できます(対応するエンティティ・オブジェクトに設定されたデフォルト値は自動的に移入されます)。
入力表を作成する際に、現在の行セット内の他の行のコンテキストで新しい空白行がユーザーに表示されるようにします。この挿入をできるようにするには、コレクションのアクセッサに関連付けられているcreate
操作を使用する必要があります。たとえば、ユーザーによる新規仕入先の作成が可能な表を作成するには、supplierFindAll
アクセッサ・コレクションから表を作成し、supplierFindAll
アクセッサ・コレクションに対してcreate
操作を使用し、ボタンを追加します。
create
操作はキャッシュに行を作成するだけであるため、新たに作成された行をコレクションに実際にマージするボタンを追加する必要もあります。図4-7は、この表に行が作成された場合を示しています。
ページ全体をリフレッシュするのではなく、他のコンポーネントとの対話に基づいて1つのコンポーネントをリフレッシュするようにADF Facesコンポーネントを設定できます。これは、部分ページ・レンダリングと呼ばれます。ユーザーが新規行を作成するボタンをクリックすると、その新規行が表示されるよう、表をリフレッシュする必要があります。これを行うには、ユーザー・アクションに対応するよう表を構成する必要があります。
始める前に:
4.3項「編集可能な表の作成」で説明しているように、編集可能な表を作成する必要があります。
「データ・コントロール」パネルから、ドロップされたコレクションに関連付けられた「作成」操作をドラッグし、ツールバー・ボタンとしてツールバーにドロップします。
ヒント:
|
構造ウィンドウで、表コンポーネントを選択します。
プロパティ・インスペクタで「動作」セクションを展開し、PartialTriggers属性のドロップダウン・メニューをクリックして「編集」を選択します。
「プロパティの編集」ダイアログで、panelCollection
コンポーネントのツールバー・ファセットを展開し、「作成」コマンド・コンポーネントを含むツールバーを展開します。そのコンポーネントを選択し、「選択済」パネルに移動します。「OK」をクリックします。これにより、そのコンポーネントが、表をリフレッシュするトリガーとして設定されます。
ユーザーが新規オブジェクトをコレクションにマージできるボタンを作成します。「データ・コントロール」パネルから、表の作成に使用されたコレクションに関連付けるマージ・メソッドをドラッグし、ツールバー・ボタンまたはリンクとしてツールバーにドロップします。
ヒント: 永続化後もユーザーが行を更新できるようにする場合、かわりに永続化メソッドを使用してボタンを作成します。詳細は、3.6.3項「マージ・メソッドと永続化メソッドとの違いについて」を参照してください。 |
図4-8は、Suppliers
コレクションのマージ・メソッドを示しています。
create
操作を使用して入力表を作成すると、JDeveloperによって次の処理が行われます。
コレクションのイテレータ・バインディング、create
操作のアクション・バインディング、および表の属性バインディングが作成されます。create
操作は、行セットに新しい行を作成します。マージ・メソッドを使用してコマンド・ボタンまたはリンクを作成した場合、JDeveloperによって、そのメソッドに対するアクション・バインディングも作成されます。
ADF Facesコンポーネントの表のコードがJSFページに挿入されます。
例4-5に、Supplier
コレクションから作成された入力表のページ定義ファイルを示します(属性の中には、コレクションをドロップしたときに、「列の編集」ダイアログで削除されたものがあります)。
例4-5 入力表のページ定義コード
<executables> <variableIterator id="variables"/> <iterator Binds="root" RangeSize="25" DataControl="SessionEJBLocal" id="SessionEJBLocalIterator"/> <accessorIterator MasterBinding="SessionEJBLocalIterator" Binds="suppliersFindAll" RangeSize="25" DataControl="SessionEJBLocal" BeanClass="model.Suppliers" id="suppliersFindAllIterator"/> </executables> <bindings> <action IterBinding="suppliersFindAllIterator" id="Create" RequiresUpdateModel="true" Action="createRow"/> <methodAction id="mergeSuppliers" RequiresUpdateModel="true" Action="invokeMethod" MethodName="mergeSuppliers" IsViewObjectMethod="false" DataControl="SessionEJBLocal" InstanceName="SessionEJBLocal.dataProvider" ReturnName="SessionEJBLocal.methodResults.mergeSuppliers_ SessionEJBLocal_dataProvider_mergeSuppliers_result"> <NamedData NDName="suppliers" NDValue="#{bindings.Create.currentRow.dataProvider}" NDType="model.Suppliers"/> </methodAction> <tree IterBinding="suppliersFindAllIterator" id="suppliersFindAll"> <nodeDefinition DefName="model.Suppliers"> <AttrNames> <Item Value="email"/> <Item Value="phoneNumber"/> <Item Value="supplierId"/> <Item Value="supplierName"/> <Item Value="supplierStatus"/> </AttrNames> </nodeDefinition> </tree> </bindings>
例4-6に、「Create Supplier」および「Commit New Suppliers」コマンド・ツールバー・ボタンを、表をリフレッシュするためのトリガーとして使用し、部分ページ・レンダリングを提供する、JSFページに追加されたコードを示します。
例4-6 表のコマンド・ボタンに設定された部分ページ・トリガー
<af:form id="f1"> <af:panelCollection id="pc1"> <f:facet name="menus"/> <f:facet name="toolbar"> <af:toolbar id="t2"> <af:commandToolbarButton actionListener="#{bindings.Create.execute}" text="Create New Supplier" disabled="#{!bindings.Create.enabled}" id="ctb1"/> <af:commandToolbarButton actionListener="#{bindings.mergeSuppliers.execute}" text="Commit New Suppliers" disabled="#{!bindings.mergeSuppliers.enabled}" id="ctb2"/> </af:toolbar> </f:facet> <f:facet name="statusbar"/> <af:table value="#{bindings.suppliersFindAll.collectionModel}" var="row" rows="#{bindings.suppliersFindAll.rangeSize}" emptyText="#{bindings.suppliersFindAll.viewable ? 'No data to display.' : 'Access Denied.'}" fetchSize="#{bindings.suppliersFindAll.rangeSize}" rowBandingInterval="0" selectedRowKeys= "#{bindings.suppliersFindAll.collectionModel.selectedRow}" selectionListener= "#{bindings.suppliersFindAll.collectionModel.makeCurrent}" rowSelection="single" id="t1" partialTriggers="::ctb1 ::ctb2"> <af:column sortProperty="supplierId" sortable="false" headerText= "#{bindings.suppliersFindAll.hints.supplierId.label}" id="c6"> <af:inputText value="#{row.bindings.supplierId.inputValue}" label="#{bindings.suppliersFindAll.hints.supplierId.label}" required="#{bindings.suppliersFindAll.hints.supplierId.mandatory}" columns="#{bindings.suppliersFindAll.hints.supplierId.displayWidth}" maximumLength="#{bindings.suppliersFindAll.hints.supplierId.precision}" shortDesc="#{bindings.suppliersFindAll.hints.supplierId.tooltip}" id="it4"> <f:validator binding="#{row.bindings.supplierId.validator}"/> <af:convertNumber groupingUsed="false" pattern="#{bindings.suppliersFindAll.hints.supplierId.format}"/> </af:inputText> </af:column> . . . </af:table> </af:panelCollection> </af:form>
create
操作にバインドされたボタンを起動すると、アクションが実行され、ページがレンダリングされることによりコレクションの新しいインスタンスが作成されます。ボタンは、表をリフレッシュするトリガーとして構成されているため、表の最上部に新しい空白行を表示して再描画されます。ユーザーが、マージ・メソッドにバインドされたボタンをクリックすると、行セットに新規作成された行がデータベースに挿入されます。部分ページ・リフレッシュの詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Webユーザー・インタフェース開発者ガイド』の「部分ページ・コンテンツのレンダリング」を参照してください。
表の列のソートが可能で、新規行を挿入する前にユーザーが列をソートした場合、新規行はソートされません。新規行もソートされるようにするには、ユーザーは、希望するソートとは反対のソートを行った後、再度ソートする必要があります。これは、表で列がすでにソートされていると見なされるためで、最初から希望のソート順をクリックしても列には何の効果も現れません。
たとえば、ユーザーが列を昇順でソートし、その後行を新たに追加するとします。最初、その行は最上部に表示されます。ユーザーが列を再度昇順でソートするようクリックすると、表は再ソートされません。これは、列がすでに昇順であると見なされるためです。ユーザーは、降順でソートした後に昇順でソートする必要があります。
行を挿入すると、データが特定の列で特定の順に自動的にソートされるようにする場合、プログラムでコミット後にSortEvent
をキューに入れ、ソートを実行するハンドラを実装します。
「データ・コントロール」パネルを使用して表を作成したら、属性の削除、表示順序の変更、表示に使用されるコンポーネントの変更、コンポーネントの属性バインディングの変更ができます。新しい属性を追加したり、表を新規のデータ・コントロールに再バインドすることもできます。
既存のUIコンポーネントとバインディングの変更の詳細は、『Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイド』の表に表示される属性の変更に関する項を参照してください。