ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Application Development FrameworkによるFusion Webアプリケーションの開発
12c (12.1.2)
E48099-02
  目次へ移動
目次

前
 
次
 

29 ADFによるデータバインドされた表の作成

この章では、ADFデータ・コントロールおよび編集可能な表、入力表、動的表を含むADF Facesコンポーネントを使用して、ADFビジネス・コンポーネントからモデル化されたデータを使用して表を作成する方法について説明します。

この章には次の項が含まれます:

29.1 ADFによるデータバインドされた表の作成について

フォームとは異なり、表を使用すると、コレクションのデータ・オブジェクトを一度に複数表示できます。

単にデータを表示する表を作成することも、データの編集または作成が可能な表を作成することもできます。コレクションを表としてドロップすると、選択した行に対してなんらかのロジックを実行するアクションにバインドされたコマンド・ボタンを追加できます。また、必要に応じてデフォルトのコンポーネントを変更することもできます。

29.1.1 ADFによるデータバインドされた表のユースケースと例

図29-1は、Oracle ADFのSummitサンプル・アプリケーションの「Inventory Control」タブの製品表を示しています。この表を使用して在庫にある製品のすべてを表示し、ユーザーが隣接したグラフでその在庫ステータスを表示する製品を選択できます。

図29-1 読取り専用表

製品表の抜粋

図29-1に示すような、単に情報を表示するのみの表を作成できますが、図29-2に示すように、ユーザーに情報の編集を許可して新しいレコードを作成することもできます。

図29-2 表の編集

編集可能な注文表の抜粋

29.1.2 データバインド表の追加機能

表およびツリー・コンポーネントを実装する前に、他のADF Faces機能を理解することが役立つ場合があります。また、ページにツリーまたは表コンポーネントを追加した後で、検証やアクセシビリティなどの機能を追加することが必要になる場合があります。表およびツリー・コンポーネントで使用できる他の機能へのリンクを次に示します。

  • ADFビュー・オブジェクト: 表内でのコンポーネントの表示方法および機能のほとんどは、対応するビュー・オブジェクトによって制御されます。詳細は、第5章「ビュー・オブジェクトを使用したSQL問合せの定義」を参照してください。

  • ADFアプリケーション・モジュール: ページにデータバインドされたコンポーネントをドラッグする「データ・コントロール」パネルに、アプリケーション・モジュールに追加したビュー・オブジェクトの表示が移入されます。詳細は、第13章「アプリケーション・モジュールによるビジネス・サービスの実装」を参照してください。

  • アダプタベースのデータ・コントロール: EJBコンポーネントやWebサービスなど他のタイプのビジネス・サービスを使用している場合は、『Oracle ADFデータ・コントロールによるアプリケーションの開発』の説明に従って、ビジネス・サービス用データ・コントロールを作成できます。

  • ADFモデルとデータ・バインディング: ADF Webアプリケーション内でデータバインドされた表を作成する場合は、ADFモデルおよびデータ・バインディングを使用します。詳細は、第17章「Fusion WebアプリケーションでのADFモデルの使用」を参照してください。

  • ADF Faces: ADF Facesを使用した開発の詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』を参照してください。

  • コマンド・ボタン: データ・セットに対して様々な機能を起動するためのコマンド・ボタンやリンクを追加できます。この章で説明したもの以外の高度な機能については、第30章「ビュー・レイヤーで各機能を起動するコマンド・コンポーネントの使用」を参照してください。

  • フィルタ処理された表: フィルタリングを可能にする表を作成できます。これにより、実質的に表内のデータに対し、例による問合せ検索を実行できます。詳細は、33.5項「スタンドアロンのフィルタ処理された検索表を名前付きビュー基準から作成」を参照してください。

  • タスク・フロー: トランザクションに携わる表の場合は(入力表など)、表のレンダリングの前または後に、ADFタスク・フローを使用して特定の操作を起動する必要があります。詳細は、第IV部「ADFタスク・フローの作成」を参照してください。

  • 検証: 特定のフィールドがデータ・ストアに送信される前に、このフィールドを検証する必要がある場合もあります。詳細は、第11章「検証とビジネス・ルールの宣言的な定義」および第18章「ADFモデル・レイヤーでの検証の使用」を参照してください。

  • アクティブ・データ: アプリケーションでアクティブ・データを使用する場合は、データ・ソースのデータが変更されるたびに、表およびツリーのデータを自動的に更新できます。詳細は、第47章「アクティブ・データ・サービスの使用」を参照してください。


    注意:

    アクティブ・データを使用し、アプリケーションでADFビジネス・コンポーネントを使用する場合は、表が次の条件に適合する必要があります。

    • アクセッサが依然として、似たようなアクセッサにアクセスしているとしても、バインディングが同種のデータ(つまり、ルールは1つのみ)を表していること。

    • バインディング・ルールに含まれる属性は1つであること。

    • 表でフィルタを使用しないこと。

    • ツリー・コンポーネントのnodeStampファセットに、単一のoutputTextタグが含まれ、他のタグが含まれていないこと。


29.2 基本表の作成

フォームを構成する個々のUIコンポーネントをコレクション上の個々の属性にバインドするフォームとは異なり、表では、ADF Facesのtableコンポーネントをコレクション全体にバインドするか、コレクションから一度にnデータ・オブジェクトのレンジにバインドします。その結果、列にデータを表示するために使用される個々のコンポーネントが属性にバインドされます。イテレータ・バインディングによって各オブジェクトの適切なデータが表示され、tableコンポーネントによって各オブジェクトが1行で表示されます。JDeveloperを使用すると、宣言的にこの処理を実行できるため、コードを記述する必要がありません。

29.2.1 基本表の作成方法

データ・コントロールを使用して表を作成するには、tableコンポーネントをコレクションにバインドします。JDeveloperでは、「データ・コントロール」パネルからコレクションをドラッグ・アンド・ドロップして、宣言的にこの処理を実行できます。

始める前に:

ADF Facesによるデータバインドされた表について理解しておくと役立ちます。詳細は、29.2項「基本的な表の作成」を参照してください。

また、その他のADF機能について理解しておくと役立ちます。詳細は、29.1.2項「データバインド表の追加機能」を参照してください。

次のタスクを完了する必要があります。

  • 13.2項「アプリケーション・モジュールの作成と変更」で説明する手順に従って、データ・モデルに含めたいビュー・オブジェクトのインスタンスを含むアプリケーション・モジュールを作成します。または、別の種類のビジネス・サービスを使用している場合は、『Oracle ADFデータ・コントロールによるアプリケーションの開発』のデータ・コントロールを使用したビジネス・サービスの公開に関する項を参照してください。

  • 26.3項「Webページの作成」の説明に従って、JSFページを作成します。

データ・バインドされた表を作成するには:

  1. 「データ・コントロール」パネルから、コレクションを選択します。

    たとえば、顧客のすべてを表示するSummit ADFサンプル・アプリケーションの単一表を作成するには、Customersコレクションを選択します。

  2. コレクションをJSFページにドラッグし、ポップアップ・メニューから「表/リスト・ビュー」→「ADF表」を選択します。

  3. 「表の作成」ダイアログには、コレクション内の各属性が表示されます。また、これらの属性が表の列としてどのように動作し、表示されるかを定義できます。

    ダイアログを使用すると、次の操作ができます。

    • 表を読取り専用にします。

    • 「単一行」または「複数行」ラジオ・ボタンを選択することにより、ADFモデル・レイヤーでの選択の処理が可能になります。これらのオプションのいずれかを選択すると、イテレータ・バインディングがイテレータにアクセスして、選択された1つ以上の行を判別します。表での選択を実行しない場合以外は、これらのオプションのいずれかを選択してください。

    • 「ソートの有効化」チェック・ボックスの選択による、ADFモデル・レイヤーでの列のソート処理。このオプションを選択すると、イテレータ・バインディングがイテレータにアクセスし、order-by問合せを実行して順序を決定します。列のソートを実行しない場合以外は、このオプションを選択してください。

    • 「フィルタの有効化」チェック・ボックスの選択による、入力した基準を使用した、表の列のフィルタリングの実行。このオプションを選択すると、各列の上にあるテキスト・フィールドに基準を入力できます。その後で、この基準を使用してコレクションへのQuery-by-Example (QBE)検索を作成すると、問合せによって戻された結果のみが表に表示されます。詳細は、33.5項「スタンドアロンのフィルタ処理された検索表を名前付きビュー基準から作成」を参照してください。


      注意:

      JPAベースのデータ・コントロールの場合、データ・コントロールのネストされたコレクションから作成される表でフィルタリングは機能しません。ページにこのようなコレクションをドロップする場合、実行時エラーを回避するために、このチェック・ボックスを未選択のままにする必要があります。JPAベースのデータ・コントロールの詳細は、『Oracle ADFデータ・コントロールによるアプリケーションの開発』のEJBデータ・コントロールに関する項を参照してください。


    • 目的の属性(ダイアログでは行として表示)の選択およびグループ化ボタンのクリックによる、親列の下の選択した属性の列のグループ化。図29-3に、表の作成後にグループ化された5つの列がビジュアル・エディタでどのように表示されるかを示します。

      図29-3 ADF Faces表のグループ化された列

      郵送先住所としてグループ化されたいくつかの列を持つ表
    • 列の表示ラベルを変更できます。デフォルトでは、ラベルは表バインディング上の属性に定義されたすべてのコントロール・ヒントのlabelsプロパティにバインドされます。このバインディングにより、ビュー・オブジェクトのラベル・テキストの値を1回変更することで、そのラベルが表示されるすべてのページに、その変更を同様に表示できます。

      このデフォルトを使用するかわりにテキストまたはEL式を入力し、ラベル値のバインド先をリソース・ファイルのキーなど、別のものにすることができます。

    • 列の値バインディングの変更。異なる属性にバインドされるように列を変更できます。単に列を並べ替える場合は、順序ボタンを使用してください。列の属性バインディングを変更すると、列のラベルも変更されます。

    • 属性の表示に使用されるUIコンポーネントの変更。UIコンポーネントは、コレクションをページにドロップしたときに選択した表と、対応する属性のタイプ(たとえば、日付である属性にはinputDateコンポーネントを使用)、および対応するビュー・オブジェクトにおいてデフォルト・コンポーネントがコントロール・ヒントとして設定されているかどうかに基づいて設定されます。ドロップダウン・リストを使用して別のコンポーネントに変更できます。


      ヒント:

      表の属性の1つが主キーでもある場合、ユーザーが値を変更できないUIコンポーネントを選択します。



      ヒント:

      ドロップダウン・メニューに表示されないコンポーネントを使用する場合は、このダイアログを使用してoutputTextコンポーネントを選択した後、手動で他のタグをページに追加します。


    • 順序ボタンを使用した列の順序の変更。

    • 「追加」アイコンを使用した列の追加。追加できる列の数に制限はありません。最初にアイコンをクリックすると、JDeveloperではダイアログの下部に新規列の行が追加され、そこにバインドされたコレクションの最初の属性の値が移入されます。後続の新規列には順序内の次の属性の値が移入され、その後も同様に続きます。

    • 「削除」アイコンを使用した列の削除。

    • 「実行時に列を動的に生成」チェック・ボックスを選択して、表を動的にします。動的表の詳細は、29.5項「動的コンポーネントを使用した表の作成」を参照してください。

  4. 表をページにドロップした後は、「プロパティ」ウィンドウを使用して、表の他の表示プロパティを設定できます。たとえば、表の幅を特定のパーセンテージまたはサイズに設定します。表示プロパティの詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』の「表、ツリーおよびその他のコレクションベースのコンポーネントの使用」の章を参照してください。


    ヒント:

    表の幅を100%に設定すると、表には境界が含まれないため、表の実際の幅はさらに大きくなります。コンテナの幅の100%に表を設定するには、「プロパティ」ウィンドウの「スタイル」セクションを開き、「ボックス」タブを選択してBorder Width属性を0(ゼロ)ピクセルに設定します。


  5. ユーザーが表の情報を編集し、変更を保存できるようにするには、変更を発行して保存する方法を指定する必要があります。詳細は、29.3項「編集可能な表の作成」を参照してください。ユーザーによるデータ入力が可能な表の作成手順は、29.4項「入力表の作成」を参照してください。

29.2.2 表の作成時の処理

「データ・コントロール」パネルから表をドロップすると、テキスト・フィールドまたはフォームをドロップするのと同じ効果があります。要約すると、Jdeveloperによって行われる処理は次のとおりです。

  • 表のバインディングを作成し、ページ定義ファイルにそのバインディングを追加します。

  • UIコンポーネントに必要なコードをJSFページに追加します。

詳細は、28.2.2項「テキスト・フィールドの作成時の処理」を参照してください。

29.2.2.1 表のイテレータと値バインディング

「データ・コントロール」パネルから表をドロップすると、treeの値バインディングが作成されます。ツリーはノードの階層で構成され、各サブノードは上位レベルのノードから分岐します。表の場合、フラット化された階層であり、各属性(列)は表のサブノードになります。フォームで使用される属性バインディングと同様で、treeの値バインディングによってイテレータ・バインディングが参照されると同時に、イテレータ・バインディングによってデータ・コレクションのイテレータが参照されるため、コレクションのデータ・オブジェクト全体の反復が円滑に行われます。属性ごとに異なるバインディングが作成されるのではなく、表ノードへのツリー・バインディングのみが作成されます。ツリー・バインディングでは、表の各行で表示または参照に使用する各属性の子要素が、nodeDefinition要素のAttrNames要素に含まれています。

ツリーの値バインディングは、FacesCtrlHierBindingクラスのインスタンスです。このクラスは、コアのJUCtrlHierBindingクラスを拡張して、次の2つのJSF固有のプロパティを追加します。

  • collectionModel: JSFおよびADF Facesで表などのコレクション値コンポーネントに使用するjavax.faces.model.DataModelオブジェクトを拡張するオブジェクトによってラップされたデータを戻します。

  • treeModel: collectionModelを拡張し、実質的に階層構造であるデータを戻します。詳細は、第31章「マスター/ディテール・データの表示」を参照してください。

例29-1に、ADFタスク・フローのProductVO1コレクションのSummitサンプル・アプリケーションをドロップすると作成される表の値バインディングを示します。

例29-1 ページ定義ファイルにおける表の値バインディング・エントリ

<bindings>
  <tree IterBinding="ProductVO1Iterator" id="ProductVO1">
    <nodeDefinition 
            DefName="oracle.summit.model.views.ProductVO"
            Name="ProductVO10">
      <AttrNames>
        <Item Value="Id"/>
        <Item Value="Name"/>
        <Item Value="ShortDesc"/>
        <Item Value="LongtextId"/>
        <Item Value="ImageId"/>
        <Item Value="SuggestedWhlslPrice"/>
        <Item Value="WhlslUnits"/>
      </AttrNames>
    </nodeDefinition>
  </tree>
</bindings>

データにアクセスする必要があるのは表のみであるため、(列または個々のセル内のテキスト・コンポーネントではなく)モデルにバインドする必要があるのは表コンポーネントのみです。表のツリー・バインディングは表の個々の構造化属性にドリルダウンするので、表の列は表コンポーネントからその情報を導出できます。

29.2.2.2 ADF Faces表のJSFページのコード

「データ・コントロール」パネルを使用してJSFページに表をドロップすると、表バインディングで指定された各属性に対するADF Facesのcolumnコンポーネントが含まれたADF FacesのtableコンポーネントがJDeveloperによって挿入されます。各列には、属性の値にバインドされた別のコンポーネント(inputTextコンポーネントやoutputTextコンポーネントなど)が含まれます。各列の見出しは、属性のコントロール・ヒントのlabelsプロパティにバインドされます。


ヒント:

関連するビューまたはエンティティ・オブジェクトで属性が非表示としてマークされている場合、対応するUIは作成されません。


例29-2に、ProductsVO1コレクションを読取り専用表としてドロップして作成した表から抜粋したコードを示します。

例29-2 ADF Faces表のJSFコード

<af:table value="#{bindings.ProductVO1.collectionModel}" var="row"
          rows="#{bindings.ProductVO1.rangeSize}"
          emptyText="#{bindings.ProductVO1.viewable ? 'No data to display.' : 'Access Denied.'}"
          fetchSize="#{bindings.ProductVO1.rangeSize}" rowBandingInterval="0"
          selectedRowKeys="#{bindings.ProductVO1.collectionModel.selectedRow}"
          selectionListener="#{bindings.ProductVO1.collectionModel.makeCurrent}"
          rowSelection="single" id="t1">
    <af:column headerText="#{bindings.ProductVO1.hints.Id.label}" id="c1">
        <af:outputText value="#{row.Id}"
                  shortDesc="#{bindings.ProductVO1.hints.Id.tooltip}"
                  id="ot1">
            <af:convertNumber groupingUsed="false"
                               pattern="#{bindings.ProductVO1.hints.Id.format}"/>
        </af:outputText>
    </af:column>
    <af:column headerText="#{bindings.ProductVO1.hints.Name.label}" id="c2">
        <af:outputText value="#{row.Name}"
                       shortDesc="#{bindings.ProductVO1.hints.Name.tooltip}"
                       id="ot2"/>
    </af:column>
    <af:column headerText="#{bindings.ProductVO1.hints.ShortDesc.label}" id="c3">
        <af:outputText value="#{row.ShortDesc}"
                  shortDesc="#{bindings.ProductVO1.hints.ShortDesc.tooltip}" 
                  id="ot3"/>
    </af:column>
.
.
.
</af:table>

ツリー・バインディングは、イテレータ・バインディングによって公開されたデータ全体を反復します。表の値は、collectionModelオブジェクトにアクセスするcollectionModelプロパティにバインドされています。表は、イテレータ・バインディングからの結果セットをcollectionModelオブジェクト内にラップします。collectionModelにより、コレクションの各アイテムは、var属性を使用して表コンポーネント内で使用できるようになります。

例では、表がProductVO1イテレータ・バインディングの現在レンジの行全体を反復します。イテレータ・バインディングは、現在行の追跡を続行する行セット・イテレータにバインドします。表のvar属性をrowに設定すると、次のaf:outputTextタグの値に示すように、各列はrow変数を使用して、表タグに示される現在行の現在データ・オブジェクトにアクセスします。

<af:outputText value="#{row.Id}"/>

ADF表をドロップし、それを読取り専用として指定しない場合、例29-3で示すように、出力コンポーネントではなく、入力コンポーネントが生成されます。入力コンポーネントの値は、行変数にバインドされるのではなく、bindingsプロパティを使用してバインディング・コンテナの特定の行に暗黙的にバインドされます。さらに、入力コンポーネントごとにバリデータ・コンポーネントが追加されます。bindingsプロパティを使用すると、発生した例外を該当するバインド・オブジェクトにリンクできます。コントローラは、バインディング・コンテナ内のすべての例外を反復処理し、FacesMessageオブジェクトの作成時にクライアントIDを取得するためのバインディング・オブジェクトを取得します。この取得により、特定のセルのエラーを表に表示できるようになります。この方法は、リストなどの選択コンポーネントを含め、すべての入力コンポーネントに使用されます。

例29-3 表内の入力コンポーネント

<af:table value="#{bindings.ProductVO1.collectionModel}" var="row"
          rows="#{bindings.ProductVO1.rangeSize}"
          emptyText="#{bindings.ProductVO1.viewable ? 'No data to display.' : 
          'Access Denied.'}"
          fetchSize="#{bindings.ProductVO1.rangeSize}" rowBandingInterval="0"
          id="t1">
    <af:column headerText="#{bindings.ProductVO1.hints.Id.label}" id="c1">
        <af:inputText value="#{row.bindings.Id.inputValue}"
                      label="#{bindings.ProductVO1.hints.Id.label}"
                      required="#{bindings.ProductVO1.hints.Id.mandatory}"
                      columns="#{bindings.ProductVO1.hints.Id.displayWidth}"
                      maximumLength="#{bindings.ProductVO1.hints.Id.precision}"
                      shortDesc="#{bindings.ProductVO1.hints.Id.tooltip}"
                      id="it1">
            <f:validator binding="#{row.bindings.Id.validator}"/>
            <af:convertNumber groupingUsed="false"
                              pattern="#{bindings.ProductVO1.hints.Id.format}"/>
        </af:inputText>
    </af:column>

ADF Facesのコンバータとバリデータの詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』の「入力の検証および変換」の章を参照してください。

表29-1に、「データ・コントロール」パネルを使用して作成されたADF Faces表に対して、デフォルトで定義された他の属性を示します。

表29-1 ADF Faces表の属性と移入される値

属性 説明 デフォルト値

rows

一度に表示する行数を決定します。

デフォルトで、関連付けられたイテレータ・バインディングのrangeSizeプロパティに評価されるEL式。これにより、データ・コントロールから一度にフェッチされるデータの行数が決定されます。表は戻される行数以上を表示できないため、rows属性の値は、対応するイテレータのrangeSize値以下にする必要があります。

first

レンジの最初の行の索引(ベース0)。

関連付けられたイテレータ・バインディングのrangeStartプロパティに評価されるEL式。

emptyText

戻す行がない場合に表示するテキスト。

イテレータの表示可能なプロパティに評価されるEL式。表が表示可能で、戻すオブジェクトがない場合、「表示するデータがありません」と表示されます。表が表示できない場合(表に対して認可の制限が設定されている場合など)は、「アクセスが拒否されました」と表示されます。

fetchSize

データソースからフェッチされたデータの行数。

デフォルトで、関連付けられたイテレータ・バインディングのrangeSizeプロパティに評価されるEL式。rangeSizeプロパティの詳細は、28.4.2.2項「定義されるイテレータのRangeSize属性」を参照してください。この属性は、rows属性より大きい数値に設定できます。

表でのスクロール動作を向上させるため、表のイテレータ・バインディングが200超の項目で構成されるデータ・セットを管理すると想定され、ビュー・オブジェクトが範囲ページングを使用するように構成されている場合、イテレータは1つの範囲のみではなく範囲のセットを実際には戻します。ビュー・オブジェクトの範囲ページ移動の使用方法の詳細は、9.1.5項「範囲ページ移動を使用した大きい結果セットの効率的なスクロール」を参照してください。JPAベースのデータ・コントロールの範囲ページ移動の詳細は、『Oracle ADFデータ・コントロールによるアプリケーションの開発』のEJBデータ・コントロールのページングされたデータ・フェッチに関する項を参照してください。

selectedRowKeys

表の選択の状態。

デフォルトでコレクション・モデルの選択された行に評価されるEL式。

selectionListener

選択したイベントをリスニングするメソッドへの参照。

デフォルトでコレクション・モデルのmakeCurrentメソッドに評価されるEL式。

rowSelection

行が選択可能かどうかを決定します。

一度に1行のみ選択するにはsingleに設定します。複数の行の選択を許可するには、multipleに設定します。

列の属性



sortProperty

列をソートする対象となるプロパティを決定します。

列の対応する属性バインディング値に設定します。

sortable

ソートできる列かどうかを決定します。

falseに設定します。trueに設定すると、イテレータ・バインディングがイテレータにアクセスし、順序を決定します。

headerText

列の上部に表示されるテキストを決定します。

デフォルトで、対応する属性に設定されたラベルのコントロール・ヒントに評価されるEL式。


29.2.3 表での現在行の設定に関する必知事項

アプリケーションで表を使用し、ADFモデル・レイヤーで行選択を管理できるようにする場合、現在行はイテレータによって決定されます。ユーザーがADF Faces表で行を選択すると、表の行が影付きになり、選択された行がコンポーネントによりイテレータに通知されます。そのためには、例29-4に示すように、表のselectedRowKeys属性をコレクション・モデルの選択した行にバインドします。

例29-4 表のselection属性

<af:table value="#{bindings.ProductVO1.collectionModel}" var="row"
.
.
.
          selectedRowKeys="#{bindings.ProductVO1.collectionModel.selectedRow}"
          selectionListener="#{bindings.ProductVO1.collectionModel.makeCurrent}"
          rowSelection="single">

このバインディングは、表の選択したキーをコレクション・モデルの選択した行にバインドします。selectionListener属性は、コレクション・モデルのmakeCurrentプロパティにバインドされます。このバインディングは、コレクションの選択した行をイテレータの現在行に設定します。


注意:

カスタム選択リスナーを作成した場合、コレクション・モデル(#{binding.Products.collectionModel.makeCurrent}など)のmakeCurrentプロパティへのメソッド・バインディングを作成し、任意のカスタム・ロジックの前にこのメソッド・バインディングをカスタム選択リスナーで起動する必要があります。


表は選択を自動的に処理できますが、オブジェクトの現在行をイテレータにプログラムで設定する必要がある場合があります。

getKey()メソッドをどのビュー行でコールしても、行を識別する1つ以上のキー属性をカプセル化するKeyオブジェクトを取得できます。findByKey()メソッドを使用して行セットのビュー行を検索するためにKeyオブジェクトを使用することもできます。実行時に、setCurrentRowWithKeyまたはsetCurrentRowWithKeyValueのいずれかの組込み操作がデータ・バインディング・レイヤーによって名前で起動されると、findByKey()メソッドを使用して、パラメータとして渡された値に基づいて行が検索された後、検索された行が現在の行として設定されます。

setCurrentRowWithKey操作およびsetCurrentRowWithKeyValue操作ではいずれもrowKeyという名前のパラメータが予想されますが、実行時にそのrowKeyパラメータに予想される値はそれぞれで異なります。

setCurrentRowWithKey操作

setCurrentRowWithKeyでは、rowKeyパラメータ値に、ビュー行キーのシリアライズされた文字列表現が想定されています。これは、次のような16進エンコード文字列です。

000200000002C20200000002C102000000010000010A5AB7DAD9

キーのシリアライズされた文字列表現により、ブラウザのURL文字列またはフォーム・パラメータで単一値として渡すことができる方法で、ビュー行のキーを構成する可能性のあるすべてのキー属性がエンコードされます。実行時に、有効なシリアライズされた文字列キーではないパラメータ値を不注意に渡すと、oracle.jbo.InvalidParamExceptionまたはjava.io.EOFExceptionなどの例外を結果として受信する場合があります。Webページでは、ADFコントロール・バインディングのrowKeyStrプロパティ(#{bindings.SomeAttrName.rowKeyStr}など)またはADF Faces表の行変数(#{row.rowKeyStr}など)を参照すると、行のシリアライズされた文字列キーの値にアクセスできます。

setCurrentRowWithKeyValue操作

setCurrentRowWithKeyValue操作では、rowKeyパラメータ値がビュー行のキーを表すリテラル値であると想定しています。たとえば、製品番号201を検索する場合、この値は単に201になります。


注意:

アプリケーション・モジュール・クラスにカスタム・コードを記述し、クライアントから渡されたシリアライズされた文字列キーに基づいて行を検索する必要がある場合は、oracle.jbo.clientパッケージにあるJboUtilクラスのgetRowFromKey()メソッドを次のように使用できます。

static public Row getRowFromKey(RowSetIterator rsi, String sKey)

第1パラメータは、行を検索するビュー・オブジェクト・インスタンスです。第2パラメータは、キーのシリアライズされた文字列書式です。


29.2.4 プログラムを使用した行データの取得に関する必知事項

CollectionModelでは行キー・パラメータを取るgetRowDataメソッドのバージョンがサポートされているため、現在の位置を変更することなく行データを取得できます。

たとえば、このコードを置き換えることができます。

CollectionModelInstance.setRowKey(RowKeyInstance);
JUCtrlHierNodeBinding rowData = (JUCtrlHierNodeBinding)
   CollectionModelInstance.getRowData();

次のコードで置き換えることができます。

JUCtrlHierNodeBinding rowData = (JUCtrlHierNodeBinding)
   CollectionModelInstance.getRowData(RowKeyInstance);

これは、setRowKeyメソッドの使用を回避できるため、ビュー・オブジェクトで範囲ページ移動を使用する際には特に役立ちます。(setRowKeyを使用する場合、そのメソッドで指定する行が現在の行範囲内にあることを確認するため、カスタム・コードを提供する必要がある場合もあります。)

29.3 編集可能な表の作成

ユーザーが表内の情報を編集し、その変更をデータソースにコミットできるようにする表を作成できます。組込みデータ制御操作を使用して、データを変更するためのコマンド・ボタンを作成し、このボタンを表のツールバーに配置できます。たとえば、Delete操作を使用して、ユーザーが現在のレンジからレコードを削除できるボタンを作成します。

重要なのは、コレクション固有の操作がADFキャッシュのオブジェクトに対してのみ実行されるという点です。ルート・データ・コントロール上でCommit操作を使用して、任意の変更をデータソースに実際にコミットする必要があります。データ・コントロールのRollback操作を使用して、キャッシュされたオブジェクトに対する任意の変更をロールバックします。ページが、バインド・タスク・フロー内のトランザクションの一部である場合、通常、タスク・フロー・リターン・アクティビティのトランザクションを解決するためにこの操作を使用します。詳細は、24.3項「タスク・フローのトランザクションの管理」を参照してください。


注意:

WebサービスやステートレスEJBセッションBeanに基づくデータ・コントロールなど、CommitおよびRollback操作が使用できないデータ・コントロールの場合、データ・ソースにデータを保存するカスタム・メソッドを提供する必要があります。JPA-ベースのデータ・コントロールの場合、mergeEntityまたはpersistEntityメソッドを使用して変更を保存できますが、これらのメソッドは単一行でのみ動作します。JPAベースのデータ・コントロールでの作業の詳細は、『Oracle ADFデータ・コントロールによるアプリケーションの開発』のEJBセッションBeanのコミット・モデルに関する項を参照してください。


編集可能なコンポーネントを使用してデータを表示することにした場合、ただちにすべての行を変更可能として表示する表か、ユーザーが行内をダブルクリックするまですべての行を読取り専用として表示する表という選択肢があります。図29-4は、すべての行に編集可能フィールドがある表を示しています。ページは、ページに追加されたコンポーネント(inputTextおよびinputDateコンポーネントなど)を使用してレンダリングされます。

図29-4 編集可能フィールドがある表

製品表の抜粋

図29-5は、同じ表ですが、データを編集または入力するにはユーザーが行をダブルクリック(または行がすでに選択されている場合はシングルクリック)する必要があるように構成されています。図29-4と同じ入力コンポーネントを使用してページは作成されていますが、outputTextコンポーネントを使用して選択されていない行のデータが表示されることに注意してください。これらのコンポーネントを実際にレンダリングしている行は、編集のために選択された行のみです。

図29-5 行の編集のためにクリックする表

製品表の抜粋

ADF Facesの表コンポーネントによる編集の処理方法の詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』の表、ツリーおよびツリー表のデータの編集に関する項を参照してください。

29.3.1 編集可能な表の作成方法

編集可能な表を作成するには、基本表の作成に類似した手順に従い、続いて操作にバインドされたコマンド・ボタンを追加します。ただし、表にツールバーを含めるには、表の作成に使用されたコレクションのアイテムとツールバーを関連付けるADF Facesコンポーネントを追加する必要があります。

始める前に:

編集可能なデータバインド表について理解しておくと役立ちます。詳細は、29.3項「編集可能な表の作成」を参照してください。

また、その他のADF機能について理解しておくと役立ちます。詳細は、29.1.2項「データバインド表の追加機能」を参照してください。

次のタスクを完了する必要があります。

  • 13.2項「アプリケーション・モジュールの作成と変更」で説明する手順に従って、データ・モデルに含めたいビュー・オブジェクトのインスタンスを含むアプリケーション・モジュールを作成します。または、別の種類のビジネス・サービスを使用している場合は、『Oracle ADFデータ・コントロールによるアプリケーションの開発』のデータ・コントロールを使用したビジネス・サービスの公開に関する項を参照してください。

  • 26.3項「Webページの作成」の説明に従って、JSFページを作成します。

編集可能な表を作成するには:

  1. 「データ・コントロール」パネルから、コレクションを選択します。

    たとえば、システム内の製品を編集できる簡単な表をSummit ADFタスク・フロー・サンプル・アプリケーションで作成するには、ProductVO1コレクションを選択します。

  2. コレクションをJSFページにドラッグし、ポップアップ・メニューから「表/リスト・ビュー」→「ADF表」を選択します。

    これにより、入力コンポーネントを使用して編集可能な表が作成されます。

  3. 次に表示される「表の作成」ダイアログを使用して、属性がどのように動作し、表の列としてどのように表示されるかを決定します。ユーザーが編集する行を選択できるようにするには、必ず「単一行」または「複数行」ラジオ・ボタンを選択してください。

    このダイアログを使用して表を構成する方法の詳細は、29.2.1項「基本表の作成方法」を参照してください。

  4. 「構造」ウィンドウで表を選択し、「プロパティ」ウィンドウの「動作」セクションを開いて、「EditingMode」属性を設定します。全行を編集可能にする場合は、editAllを選択します。ユーザーに1行をクリックさせてその行を編集可能にする場合は、clickToEditを選択します。

  5. 「構造」ウィンドウで、表コンポーネントを右クリックし、「囲む」を選択します。

  6. 「囲む」ダイアログでは、ドロップダウン・リストで「ADF Faces」が選択されていることを確認し、「パネル・コレクション」コンポーネントを選択して「OK」をクリックします。

    panelCollectionコンポーネントのツールバー・ファセットによりツールバーが保持され、そのツールバーによりデータの更新に使用されるコマンド・コンポーネントが保持されます。

  7. 「構造」ウィンドウで、panelCollection「f:facet - toolbar」ファセット・ノードを右クリックし、「f:facet - toolbarの中に挿入」「ツールバー」を選択します。

    これにより、ユーザーが表の表示方法を変更できるデフォルトのメニューと、表全体の連結を解除する「連結解除」リンクをすでに含むツールバーが作成され、ブラウザ・ウィンドウの大部分を占めるように表示されます。panelCollectionコンポーネントの詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』の表メニュー、ツールバーおよびステータス・バーの表示に関する項を参照してください。

  8. 「データ・コントロール」パネルから操作の実行対象となるオブジェクトのコレクションに関連付けられている操作を選択し、「構造」ウィンドウのtoolbarコンポーネントにドラッグして、ポップアップ・メニューから「作成」→「ADFボタン」を選択します。これにより、データバインドされたコマンド・コンポーネントがツールバー内に配置されます。

    たとえば、製品レコードを削除できるようにする場合は、ProductVO1コレクションに関連付けられているDelete操作をドラッグします。図29-6に、ProductVO1コレクションに関連付けられている操作を示します。

    図29-6 コレクションに関連付けられている操作

    「データ・コントロール」パネルのコレクション操作
  9. 変更をキャッシュに送信するボタンが必要な場合は、「構造」ウィンドウで「af:toolbar」コンポーネントを右クリックし、「ツールバーの中に挿入」「ボタン」の順に選択します。


    注意:

    表内の入力コンポーネントに対してautoSubmitプロパティをtrueに設定するなど、変更をキャッシュに送信する他の手段を使用できます。詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』の部分トリガーの使用に関する項を参照してください。


  10. ページが、バインド・タスク・フロー内のトランザクションの一部でない場合、ユーザーが変更をコミットまたはロールバックできるようにするためのボタンを作成する必要があります。「データ・コントロール」パネルから、ルートレベル・データ・コントロールに関連付けられたCommit操作とRollback操作をドラッグし、ボタンまたはリンクのいずれかとしてツールバーにドロップします。

    図29-7に、BackOfficeAppModuleDataControlデータ・コントロールのコミット操作とロール・バック操作を示します。

    図29-7 データ・コントロールのCommit操作とRollback操作

    「データ・コントロール」パネルのCommit操作とRollback操作

    ページが、バインド・タスク・フロー内のトランザクションの一部である場合、タスク・フロー・リターン・アクティビティを作成する際のトランザクションを解決する値としてCommitまたはRollbackを入力します。詳細は、24.3項「タスク・フローのトランザクションの管理」を参照してください。


ヒント:

データ・ストアに新規レコードを挿入できる表を作成するには、29.4項「入力表の作成」を参照してください。


29.3.2 編集可能な表の作成時の処理

編集可能な表の作成は、レコードの編集に使用するフォームの作成と類似しています。「データ・コントロール」パネルからドロップした操作に対してアクション・バインディングが作成されます。詳細は、28.4.2項「操作を使用したコマンド・コンポーネント作成時の処理」を参照してください。

29.4 入力表の作成

ユーザーが表に新しく空白行を挿入し、各列に値を追加することのできる表を作成できます(対応するエンティティ・オブジェクトまたはビュー・オブジェクトに設定されたデフォルト値は自動的に移入されます)。

29.4.1 入力表の作成方法

入力表を作成する際に、現在の行セット内の他の行のコンテキストにある新しい空白行をユーザーに表示する必要があります。この挿入を許可するには、CreateInsert操作を使用します。Create操作とは異なり、CreateInsert操作は、実際にはキャッシュのみではなく行セット内に新しい行を作成します。また、ユーザー・アクションに対応するよう表を構成する必要があります。ページ全体をリフレッシュするのではなく、他のコンポーネントとの対話に基づいて1つのコンポーネントをリフレッシュするようにADF Facesコンポーネントを設定できます。これは、部分ページ・レンダリングと呼ばれます。


注意:

CreateInsert操作は、WebサービスやJavaクラスに基づく操作など、アダプタベースのデータ・コントロールには利用できません。ただし、JPAベースのデータ・コントロールの場合、Create操作により、新規行がアプリケーション・モジュールに基づくデータ・コントロール用のCreateInsertなどの行セットに追加されます。詳細は、『Oracle ADFデータ・コントロールによるアプリケーションの開発』のデータ・コントロール組込み操作に関する項を参照してください。


始める前に:

ADF Facesの入力表について理解しておくと役立ちます。詳細は、29.4項「入力表の作成」を参照してください。

また、その他のADF機能について理解しておくと役立ちます。詳細は、29.1.2項「データバインド表の追加機能」を参照してください。

次のタスクを完了する必要があります。

  • 29.3項「編集可能な表の作成」で説明しているように、編集可能な表を作成します。

  • 表がバインド・タスク・フローの一部でない場合は、Commit操作とRollback操作にバインドされたボタンを含めます。

入力表を作成するには:

  1. 「データ・コントロール」パネルから、ドロップされたコレクションに関連付けられたCreateInsert操作をドラッグし、ツールバー・ボタンとしてツールバーにドロップします。CreateNewRowなどのわかりやすいものにIDを変更できます。これによって、部分トリガーとして選択する際に識別しやすくなります。


    注意:

    コレクションが別のコレクションの子である場合は(たとえば、Summit ADFサンプル・アプリケーションでは、OrdersForCustomerコレクションはCustomersコレクションの子)であり、CreateInsert操作を使用するかわりに、Create with Parameters操作を使用する必要があります。これは、子コレクションに対して作成するレコードが親コレクションに関連付けられるようにするためです。


  2. 構造ウィンドウで、表コンポーネントを選択します。「プロパティ」ウィンドウで、「動作」セクションを開きます。

  3. 「プロパティ」ウィンドウで、PartialTriggers属性上にマウスを置いて、「編集」を選択します。

  4. 「プロパティの編集」ダイアログで、panelCollectionコンポーネントのツールバー・ファセットを開き、CreateInsert コマンド・コンポーネントを含むツールバーを開きます。そのコンポーネントを選択し、「選択済」パネルに移動します。「OK」をクリックします。これにより、表のリフレッシュがトリガーされるコンポーネントが設定されました。

29.4.2 入力表の作成時の処理

CreateInsert操作を使用して入力表を作成すると、JDeveloperによって次の処理が行われます。

  • コレクションのイテレータ・バインディング、CreateInsert操作のアクション・バインディング、および表の属性バインディングの作成。CreateInsert操作は、行セットに新しい行を作成します。Commit操作およびRollback操作を使用してコマンド・ボタンまたはリンクを作成した場合、JDeveloperではこれらの操作のアクション・バインディングも作成されます。

  • ADF Faces tableコンポーネント、columnコンポーネント、inputTextコンポーネントおよび操作の場合はbuttonコンポーネントを使用した、JSFページへのコードの挿入。

例29-5に、ProductVO1コレクションから作成された入力表のページ定義ファイルを示します(属性の中には、コレクションをドロップしたときに、「表の作成」ダイアログで削除されたものがあります)。

例29-5 入力表のページ定義コード

<executables>
  <iterator Binds="ProductVO1" RangeSize="25"
            DataControl="BackOfficeAppModuleDataControl" id="ProductVO1Iterator"/>
</executables>
  <tree IterBinding="ProductVO1Iterator" id="ProductVO1">
    <nodeDefinition 
            DefName="oracle.summit.model.views.ProductVO"
            Name="ProductVO10">
      <AttrNames>
        <Item Value="Id"/>
        <Item Value="Name"/>
        <Item Value="ShortDesc"/>
        <Item Value="LongtextId"/>
        <Item Value="ImageId"/>
        <Item Value="SuggestedWhlslPrice"/>
        <Item Value="WhlslUnits"/>
      </AttrNames>
    </nodeDefinition>
  </tree>
  <action IterBinding="ProductVOIterator" id="CreateInsert"
          RequiresUpdateModel="true" Action="createInsertRow"/>
  <action id="Commit" RequiresUpdateModel="true" Action="commitTransaction"
          DataControl="BackOfficeAppModuleDataControl"/>
  <action id="Rollback" RequiresUpdateModel="false"
          Action="rollbackTransaction"
          DataControl="BackOfficeAppModuleDataControl"/>
</bindings>

例29-6に、CreateInsertコマンド・ツールバー・ボタンを、表をリフレッシュするためのトリガーとして使用し、部分ページ・レンダリングを提供するJSFページに追加されたコードを示します。

例29-6 表のコマンド・ボタンに設定された部分ページ・トリガー

<af:form>
  <af:panelCollection id="pc1">
    <f:facet name="menus"/>
    <f:facet name="toolbar">
      <af:toolbar id="tb1">
        <af:button actionListener="#{bindings.CreateInsert.execute}"
                                 text="CreateInsert"
                                 disabled="#{!bindings.CreateInsert.enabled}"
                                 id="CreateInsert"/>
        <af:button actionListener="#{bindings.Commit.execute}"
                                 text="Commit"
                                 disabled="false" id="b2"/>
        <af:button actionListener="#{bindings.Rollback.execute}"
                                 text="Rollback"
                                 disabled="#{!bindings.Rollback.enabled}"
                                 immediate="true" id="b3">
          <af:resetActionListener/>
        </af:button>
      </af:toolbar>
    </f:facet>
    <f:facet name="statusbar"/>
    <af:table value="#{bindings.ProductVO1.collectionModel}" var="row"
              rows="#{bindings.ProductVO1.rangeSize}"
              emptyText="#{bindings.ProductVO1.viewable ? \'No data to display.\' :
                                                      \'Access Denied.\'}"
              fetchSize="#{bindings.ProductVO1.rangeSize}"
              rowSelection="single" partialTriggers="CreateInsert" id="t1">
      <af:column sortProperty="Id" sortable="false"
                 headerText="#{bindings.ProductVO1.hints.Id.label}"
                 id="c1">
        <af:inputText value="#{row.ProductId}" simple="true"
                      required="#{bindings.ProductVO1.hints.Id.mandatory}"
                      columns="#{bindings.ProductVO1.hints.Id.displayWidth}"
                      maximuumLength="#{bindings.ProductVO1.hints.Id.precision}"
                     id="it1"/>
      </af:column>
.
.
.
    </af:table>
  </af:panelCollection>
</af:form>

29.4.3 実行時に行われる処理: CreateInsertおよび部分ページ更新の動作方法

CreateInsert操作にバインドされたボタンを起動すると、アクションが実行され、ページがレンダリングされることによりコレクションの新しいインスタンスが作成および挿入されます。ボタンは、表をリフレッシュするトリガーとして構成されているため、表の最上部に新しい空白行を表示して再描画されます。Commitアクションにバインドされたボタンをユーザーがクリックすると、行セット内に作成された新しい行がデータベースに挿入されます。部分ページ更新の詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』の「部分ページ・コンテンツの再レンダリング」の章を参照してください。

29.4.4 行の作成および列のソートに関する必知事項

表の列のソートが可能で、新規行を挿入する前にユーザーが列をソートした場合、新規行はソートされません。新規行を含めて列をソートするには、目的のソートとは逆の列ソートを行ってから再ソートする必要があります。これは、表で列がすでにソートされていると見なされるためで、最初から希望のソート順をクリックしても列には何の効果もあらわれません。

たとえば、ユーザーが列を昇順でソートし、その後行を新たに追加するとします。最初、その行は最上部に表示されます。もう一度昇順で列をソートするために最初から昇順をクリックすると、列がすでに昇順であると見なされ、表は再ソートされません。ユーザーは、降順でソートした後に昇順でソートする必要があります。

行を挿入すると、データが特定の列で特定の順に自動的にソートされるようにする場合、プログラムでコミット後にSortEventをキューに入れ、ソートを実行するハンドラを実装します。

ビュー・オブジェクト属性がカスタム・ドメイン・データ・タイプによって定義されている列でソートを許可する場合、表のソート・ボタン・クリック・イベントに対してcompareTo()メソッドを実装する必要があります。

public int compareTo(Object theObject)

現在のオブジェクトがtheObjectより小さい場合は0以下の値に対して0を戻します。また現在のオブジェクトがそれより大きい場合は、0より大きい値を戻します。属性のオブジェクト比較は文字列比較のように動作します。

29.4.5 CreateおよびCreateInsertに関する必知事項

CreateまたはCreateInsert操作を使用して新規行を宣言的に作成すると、次のコード行が実行されます。

// create a new row for the view object
Row newRow = yourViewObject.createRow();
// mark the row as being "initialized", but not yet new
newRow.setNewRowState(Row.STATUS_INITIALIZED);

ただし、CreateInsert操作を使用している場合は、行を行セットに挿入する追加のコード行も実行されます。

// insert the new row into the view object's default rowset
yourViewObject.insertRow(newRow);

行をエンティティベースのビュー・オブジェクトに作成すると、現在のアプリケーション・モジュールに関連付けられているTransactionオブジェクトによって、その処理が即時に記録されます。ビュー行の後に作成された新規エンティティ行は、Transactionの保留中の変更リストにすでに含まれています。作成された新規行は、初期化済状態であるとしてマーク付けされると、Transactionの保留中の変更リストから削除され、エンド・ユーザーによるデータ値の入力がまだ行われていない空白行とみなされます。初期化済という用語が適切である理由は、基礎となるエンティティ・オブジェクトによって定義されたすべてのデフォルト値を使用して初期化された新規行がエンド・ユーザーに表示されるためです。初期化済の行のどの属性にもユーザーがデータを入力していない場合は、その行が存在していないかのように処理されます。トランザクションのコミット時には、その行がTransactionの保留中の変更リストに含まれていないため、INSERT文はその行に対して試行されません。

初期化済の行に1つ以上の属性が設定されると同時に、初期化済の状態から新規状態(Row.STATUS_NEW)に自動的に遷移します。この時点で、基礎となるエンティティ行はTransactionの保留中の変更リストに登録され、トランザクションの次回コミット時に新規行が永続的に保存されます。


注意:

多数の初期化済の行を作成してもその行にデータを移入しない手順をエンド・ユーザーが実行した場合、低速メモリー・リークが発生することがあります。ただし、新規状態に遷移しない初期化済の行で使用されるメモリーは、Java仮想マシンのガベージ・コレクタによって最終的に解放されます。


29.4.6 JPAベースのデータ・コントロールでの複数行の保存に関する必知事項

EJBデータ・コントロールおよびJPAベースのBeanデータ・コントロールには、使用可能な組込みCreateInsert操作がありません。ただし、データ・コントロールのEagerPersistプロパティをtrueに設定して、これらのデータ・コントロールのCreate操作とCreateInsertの動作を置き換えることができます。このプロパティは、コンテナ管理トランザクションおよび明示的コミット・モデルを使用するステートフル・セッションBeanに基づくデータ・コントロールに対してデフォルトでtrueに設定されます。詳細は、『Oracle ADFデータ・コントロールによるアプリケーションの開発』のEJBセッションBeanのコミット・モデルに関する項を参照してください。

29.5 動的コンポーネントを使用した表の作成

ページ内で直接各コンポーネントに対してタグを提供する静的データバインド・フォームを作成するのではなく、動的コンポーネントを使用して、バインディング・メタデータ、列およびバインド・コンテンツを表示するために使用されるコンポーネントが実行時に決定される表を作成します。

図29-8は、CustomerVOビュー・オブジェクトで属性に対するUIヒントを設定し、動的表としてCustomersデータ・コントロール・コレクションをドロップすることによって作成された実行時の動的表を示しています。設定されたUIヒントにはLABELおよびDISPLAYHINTがあります(後者は、動的フォームに指定された属性を含めないようにHideに設定できます)。

図29-8 カテゴリ・ヒントに基づいた列グループを含む動的表

単一列と列のPersonInfoグループを含む表

動的コンポーネントの詳細は、28.9.1項「動的コンポーネントについて」を参照してください。

29.5.1 動的表の作成方法

動的表を作成するには、コレクションをADF表として「データ・コントロール」パネルからドロップして、フィールドが動的に生成されることを指定します。

始める前に:

動的コンポーネント機能および動的データバインド表について理解しておくと役立ちます。詳細は、28.9.1項「動的コンポーネントについて」および29.5項「動的コンポーネントを使用した表の作成」を参照してください。

また、その他のADF機能について理解しておくと役立ちます。詳細は、29.1.2項「データバインド表の追加機能」を参照してください。

次のタスクを完了する必要があります。

  • 13.2項「アプリケーション・モジュールの作成と変更」で説明する手順に従って、データ・モデルに含めたいビュー・オブジェクトのインスタンスを含むアプリケーション・モジュールを作成します。または、別の種類のビジネス・サービスを使用している場合は、『Oracle ADFデータ・コントロールによるアプリケーションの開発』のデータ・コントロールを使用したビジネス・サービスの公開に関する項を参照してください。

  • 26.3項「Webページの作成」の説明に従って、JSFページを作成します。

動的表を作成するには:

  1. 動的フォームを作成しているコレクションに対応するビュー・オブジェクトまたはデータ・コントロール構造にUIヒントを設定します。

    UIヒントにより、属性、ラベル、ツールヒント、フィールドを自動的に送信する必要があるかどうかなどを表示するために使用するUIコンポーネントのタイプなどが決定されます。UIヒントの作成手順は、5.13項「ビュー・オブジェクトのUIヒントの定義」を参照してください。

  2. 必要に応じて、各ビュー・オブジェクト属性のCategoryヒントに対して、カテゴリを指定するか、「新規カテゴリ」アイコンをクリックして、新規カテゴリを作成します。

    同じカテゴリを持つ属性は、そのビュー・オブジェクトに基づいて作成する動的表でまとめることができます。

  3. 必要に応じて、手順2で作成したカテゴリに対して、カテゴリのラベルおよびツールヒント用にUIヒントを設定します。これらはビュー・オブジェクトの概要エディタの「UIカテゴリ」タブで設定できます。

  4. 「データ・コントロール」パネルから、ビュー・オブジェクトを表すコレクションを選択します。

  5. コレクションをページにドラッグし、ポップアップ・メニューから「表/リスト・ビュー」「ADF表」を選択します。

  6. 「表の作成」ダイアログで、「実行時に列を動的に生成」チェック・ボックスを選択します。

  7. 手順2で属性のカテゴリを指定した場合は、これらのカテゴリに従って表の列をグループ化するためにチェック・ボックスにフォームの列の表示を編成するため、「列グループを含める」チェック・ボックスを選択します。

29.5.2 動的コンポーネント使用時の処理

コレクションをページに動的フォームとしてドロップする場合、次の処理が発生します。

  • ページ定義はvariableIteratorバインディング、イテレータへのiteratorバインディングおよびtree値バインディングで移入されます。詳細は、28.9.3.1項「動的フォームに対して作成されるバインディング」を参照してください。

  • JSFページにはtableタグおよび1つ以上のiteratorcolumnおよびdynamicComponentタグが移入されます。また、「列グループを含める」オプションが選択されている場合は、switcherおよびgroupタグが追加されます。

29.5.2.1 グループ化しないで動的表に対して作成されるタグ

JSFページで、JDeveloperはtableタグを挿入し、その内部で、コレクションの属性を反復処理するiteratorタグをネストします。そのiteratorタグ内で、dynamicComponentタグを含むcolumnタグがネストされます。また、dynamicComponentに、実行時に決定される各列に対して適切なコンポーネントが表示されます。

例29-7は、動的表としてCountriesデータ・コントロール・オブジェクトをドロップした(ただし、「列グループを含める」オプションを選択していない)場合に生成されるコードを示しています。

例29-7 動的表に対するJSFページ・コード

<af:table value="#{bindings.Countries.collectionModel}" var="row"
          rows="#{bindings.Countries.rangeSize}"
          emptyText="#{bindings.Countries.viewable ? 'No data to display.' :
                                                     'Access Denied.'}"
          rowBandingInterval="0" fetchSize="#{bindings.Countries.rangeSize}"
          id="t1">
    <af:iterator id="i1"
                 value="#{bindings.Countries.attributesModel.attributes}"
                 var="column">
        <af:column headerText="#{column.label}" id="c1">
            <af:dynamicComponent id="d2" attributeModel="#{column}"
                                 value="#{row.bindings[column.name].inputValue}"/>
        </af:column>
    </af:iterator>
</af:table>

iteratorタグのvalue属性では、コレクションのツリー・バインディングのattributesModel.attributesプロパティに評価するEL式を使用します。attributesModelプロパティは、コンポーネント・タイプ、ラベル、ツールヒント、レンダリングされる実際のコンポーネントの他のプロパティなど、データ・オブジェクトの属性およびそのメタデータを取得するために使用されます。attributesModelattributesプロパティは、表示可能属性およびそのメタデータのフラット(非階層的)リストが提供されていることを示します。

dynamicComponentタグのattributeModel属性は、EL式 #{column}にバインドされ、イテレータのvar属性で定義される変数を参照し、データ・コントロール・コレクションおよびその対応するメタデータの現在の属性へのポインタとして機能します。dynamicComponentvalue属性のEL式は、変数columnも参照します。

29.5.2.2 グループ化して動的表に対して作成されるタグ

「表の作成」ダイアログの「列グループを含める」チェック・ボックスを選択している場合は、生成されたJSFページに、29.5.2.1項「グループ化しないで動的表に対して作成されるタグ」で説明されているタグに加え、switchergroupタグが含まれます。

switcherタグは、columnタグ内で直接ネストされます。switcherタグ内には、GROUPおよびATTRIBUTEという名前のネストされたfacetタグがあります。GROUPファセットにはgroupタグが含まれ、その内部に、グループ名とiteratorタグを表示するoutputTextタグがあり、それにはdynamicComponentタグを含むcolumnタグが含まれます。ATTRIBUTEファセットにはdynamicComponentタグのみが含まれます。

高レベルのiteratorが反復する各属性の場合、切替え機能により、グループまたは列をレンダリングするかどうかが動的に決定されます。グループをレンダリングする場合、グループ内のイテレータはそのグループ内の列をレンダリングするために使用されます。

例29-8は、Countriesコレクションに基づいた動的フォームを作成し、列グループを含むように選択する場合に生成されるコードを示したものです。

例29-8 グループを使用した動的表に対するJSFページ・コード

<af:table value="#{bindings.Countries.collectionModel}" var="row"
          rows="#{bindings.Countries.rangeSize}"
          emptyText="#{bindings.Countries.viewable ? 'No data to display.' : 'Access Denied.'}"
          rowBandingInterval="0" fetchSize="#{bindings.Countries.rangeSize}"
          id="t1">
    <af:iterator id="i1"
              value="#{bindings.Countries.attributesModel.hierarchicalAttributes}"
                 var="column">
        <af:column headerText="#{column.label}" id="c1">
            <af:switcher id="sw1" facetName="#{column.descriptorType}"
                         defaultFacet="ATTRIBUTE">
                <f:facet name="GROUP">
                    <af:iterator id="gi1" value="#{column.descriptors}"
                                 var="nestedCol">
                        <af:column headerText="#{nestedCol.label}" id="c2">
                            <af:dynamicComponent id="gd1"
                                                 attributeModel="#{nestedCol}"
                              value="#{row.bindings[nestedCol.name].inputValue}"/>
                        </af:column>
                    </af:iterator>
                </f:facet>
                <f:facet name="ATTRIBUTE">
                    <af:dynamicComponent id="ad1" attributeModel="#{column}"
                                value="#{row.bindings[column.name].inputValue}"/>
                </f:facet>
            </af:switcher>
        </af:column>
    </af:iterator>
</af:table>

iteratorタグのvalue属性では、コレクションのツリー・バインディングのattributesModel.hierarchicalAttributesプロパティに評価されるEL式を使用します。attributesModelプロパティは、コンポーネント・タイプ、ラベル、ツールヒント、レンダリングされる実際のコンポーネントの他のプロパティなど、データ・オブジェクトの属性およびそのメタデータを取得するために使用されます。hierarchicalAttributesプロパティは、UIヒントの属性に対して設定されたカテゴリを含む、表示可能属性およびそのメタデータの階層リストが提供されることを示します。

dynamicComponentタグのattributeModel属性は、EL式 #{column}に設定され、イテレータのvar属性で定義される変数を参照し、データ・コントロール・コレクションおよびその対応するメタデータの現在の列(またはカテゴリ)へのポインタとして機能します。

29.5.3 実行時に行われる処理: 属性値の動的な決定方法

動的コンポーネントを含むページがレンダリングされると、設計時に「データ・コントロール」パネルから項目をドロップしたときと同様に、バインディングが作成されます。ただし、バインディングは実行時に作成されます。詳細は、28.9.4項「実行時に行われる処理: 属性値の動的な決定方法」を参照してください。

29.5.4 detailStampファセットを使用した動的表の作成方法

また、マスター・コンテンツを表示し、ユーザーが指定されたレコードのディテールを表示できるdetailStampファセットを含む動的表を作成できます。ディテール・コンテンツは、マスター・ビュー・オブジェクトでの動的コンポーネントのビュー・リンク・アクセッサへのバインディングから取得されます。図29-9に、このようなディテール・ファセットを含む動的表の一部を示します。表のdetailStampファセットの使用方法の詳細は、『Oracle ADF FacesによるWebユーザー・インタフェースの開発』の表への非表示機能の追加に関する項を参照してください。

図29-9 detailStampファセットが表示された動的表

3番目の行に表示されたdetailStampファセット

始める前に:

動的表について理解しておくと役立ちます。詳細は、29.5項「動的コンポーネントを使用した表の作成」を参照してください。

また、その他のADF機能について理解しておくと役立ちます。詳細は、29.1.2項「データバインド表の追加機能」を参照してください。

次のタスクを完了する必要があります。

detailStampファセットを使用して動的表を作成するには:

  1. JSFページのソース・エディタで、動的表のtableタグ内にfacetタグを挿入します。

  2. facetタグ内に、panelFormLayoutタグを挿入します。

  3. panelFormLayoutタグ内に、iteratorタグを挿入します。

  4. イテレータのvalue属性をデータ・オブジェクトのattributesModel.getLinkedViewAttributes(LinkedViewName)プロパティにバインドします。ここで、LinkedViewNameは、ディテール・コンテンツにアクセスするビュー・リンク・アクセッサの名前です。

  5. iteratorタグ内に、dynamicComponentタグを挿入します。

  6. dynamicComponentタグのattributeModel属性をiteratorタグのvar属性の値にバインドします。

  7. dynamicComponentタグのvalue属性を、選択した行のディテール・データを戻す式にバインドします。

例29-9は、ビュー・リンク・アクセッサを使用して取得されたデータを表示するためにdetailStampファセットを使用する動的表のJSFページ・コードを示したものです。

例29-9 状況依存のコンテンツを使用した動的表のためのタグ

<af:table value="#{bindings.EmpVO3.collectionModel}" var="row" id="t1" ...>
  <f:facet name="detailStamp">
    <af:panelForm id="pgl1" layout="vertical">
      <af:iterator id="iter3" var="detail"
           value="#{bindings.EmpVO3.attributesModel.getLinkedViewAttributes('DeptView')}">
        <af:dynamicComponent value="#{row['DeptView'].bindings[detail.name].inputValue}"/> attributeModel="#{detail}" id="dc1"/>
      </af:iterator>
    </af:panelForm>
  </f:facet>
  <af:iterator id="itr1" var="column"
      value="#{bindings.EmpVO3.attributesModel.attributes}">
    <af:column headerText="#{column.label}" id="dcc1">
      <af:dynamicComponent value="#{row.bindings[column.name].inputValue}" attributeModel="#{column}" id="dc1"/>
    </af:column>
  </af:iterator>
</af:table>

29.6 表に表示される属性の変更

「データ・コントロール」パネルを使用して表を作成したら、属性の削除、表示順序の変更、表示に使用されるコンポーネントの変更、コンポーネントの属性バインディングの変更ができます。新しい属性を追加したり、表を新規のデータ・コントロールに再バインドすることもできます。

29.6.1 表示される属性の変更方法

「データ・コントロール」パネルを使用して作成された表は、次のような変更ができます。

  • 行のラベルに対するバインディングの変更

  • 属性にバインドされているUIコンポーネントの変更

  • 属性を表す列の追加または削除

  • 表内の列の並替え

  • 選択とソート処理の有効化

始める前に:

データバインド表の変更について理解しておくと役立ちます。詳細は、29.6項「表に表示される属性の変更」を参照してください。

また、その他のADF機能について理解しておくと役立ちます。詳細は、29.1.2項「データバインド表の追加機能」を参照してください。

次のタスクを完了する必要があります。


29.2項「基本表の作成」の手順に従い、データバインドされた表を作成します。

表の属性を変更するには:

  1. 「構造」ウィンドウで、表コンポーネントを選択します。

  2. 「プロパティ」ウィンドウで「列」セクションを開き、列として表示される属性を変更、追加または削除します。列内でデータ表示に使用されるUIコンポーネントを変更することもできます。

  3. 「プロパティ」ウィンドウの他のセクションを開き、フィルタリングやソートなど、表の表示や動作を変更します。

29.6.2 表のバインディングの変更方法

バインディングを変更するかわりに、表がバインドされているオブジェクトを完全に変更することができます。

始める前に:

データバインド表の変更について理解しておくと役立ちます。詳細は、29.6項「表に表示される属性の変更」を参照してください。

また、その他のADF機能について理解しておくと役立ちます。詳細は、29.1.2項「データバインド表の追加機能」を参照してください。

次のタスクを完了する必要があります。

表をリバインドするには:

  1. 「構造」ウィンドウで表を右クリックし、「別のADFコントロールに再バインド」を選択します。

  2. 「ADFコントロールにバインド」ダイアログで、表のバインド先とする新しいコレクションを選択します。

    表のバインディングを変更すると、すべての列のバインディングも変更されます。29.6.1項「表示される属性の変更方法」の手順に従って、これらのバインディングを変更できます。


ヒント:

既存の表の最上部に異なるビュー・オブジェクトをドラッグして表を再バインドすることもできます。


29.6.3 バインディングまたは表示される属性の変更時に発生する処理

UIコンポーネントを移動または変更して単に属性の表示方法を変更すると、JSFページの対応するコードが変更されます。バインディング・エディタを使用してバインディングを追加または変更すると、JDeveloperによって、JSFページにコードが追加され、ページ定義ファイルに適切な要素が追加されます。