Skip to main content
Bring your team and maximize your impact at Dreamforce. Register three or more to unlock $999 passes.

標準リストコントローラーの使用

学習の目的

この単元を完了すると、次のことができるようになります。

  • Visualforce 標準リストコントローラーとは何か、標準 (レコード) コントローラーとの違いは何かを説明する。
  • 標準リストコントローラーで提供される、標準コントローラーとは異なるアクションを 3 つ挙げる。
  • Visualforce ページで標準リストコントローラーを使用して、レコードのリストを表示する。
  • ページネーションを定義して Visualforce ページに追加する。

標準リストコントローラーの概要

標準リストコントローラーを使用すると、レコードセットの表示や操作が行える Visualforce ページを作成できます。

レコードのリストの表示は、ほぼすべての Web アプリケーションの基本動作です。Visualforce では、バックエンドコードなしでマークアップのみを使用して、同じタイプのレコードのリストを非常に簡単に表示できます。この秘密の鍵は標準コントローラーにあり、この場合は標準<>リスト>コントローラーが使用されます。

標準リストコントローラーには、特定のオブジェクトレコードのクエリ、コレクション変数でのレコードの使用、結果の絞り込みやページネーションなど、多数の強力な自動動作があります。ページへの標準リストコントローラーの追加は標準 (レコード) コントローラーの追加と非常に似ていますが、一度に 1 レコードを操作する代わりに、一度に多数のレコードを操作することを目的としています。

メモ

メモ

日本語で受講されている方へ
Challenge は日本語の Trailhead Playground で開始し、かっこ内の翻訳を参照しながら進めていってください。Challenge での評価は英語データを対象に行われるため、英語の値のみをコピーして貼り付けるようにしてください。日本語の組織で Challenge が不合格だった場合は、(1) この手順に従って [Locale (地域)] を [United States (米国)] に切り替え、(2) [Language (言語)] を [English (英語)] に切り替えてから、(3) [Check Challenge (Challenge を確認)] ボタンをクリックしてみることをお勧めします。

翻訳版 Trailhead を活用する方法の詳細は、自分の言語の Trailhead バッジを参照してください。

レコードのリストを表示する

<>> などの標準リストコントローラーと反復コンポーネントを使用して、レコードのリストを表示します。

標準 (レコード) コントローラーにより、Visualforce ページで使用できる変数に 1 つのレコードを簡単に読み込むことができます。標準<>リスト>コントローラーも同様ですが、1 つのレコードの代わりに、レコードのリストまたはコレクションを変数に読み込みます。

個々のレコードではなくコレクションを操作するため、反復コンポーネントを使用してレコードを表示する必要があります。反復コンポーネントは、1 つの値ではなく類似した項目のコレクションと連動します。反復コンポーネントはそのコレクションをループし、各レコードに対して、コンポーネントマークアップの一部として提供するテンプレートに基づいて出力を生成します。これは複雑に思えるかもしれませんが、マークアップを読めばすぐに理解できます。

標準リストコントローラーを使用するためのマークアップは、一度に 1 レコードの標準コントローラーを使用するためのマークアップとほぼ同じです。

  1. 新しい Visualforce ページを作成するには、開発者コンソールを開き、<>[File (ファイル)]> | <>[New (新規)]> | <>[Visualforce Page (Visualforce ページ)]> をクリックします。ページ名に <><>ContactList>> と入力します。
  2. エディターで、任意のマークアップを次のように置き換えます。
    <apex:page standardController="Contact" recordSetVar="contacts">
        <apex:pageBlock title="Contacts List">
            <!-- Contacts List -->
            <apex:pageBlockTable value="{! contacts }" var="ct">
                <apex:column value="{! ct.FirstName }"/>
                <apex:column value="{! ct.LastName }"/>
                <apex:column value="{! ct.Email }"/>
                <apex:column value="{! ct.Account.Name }"/>
            </apex:pageBlockTable>
        </apex:pageBlock>
    </apex:page>
  3. <>[Preview (プレビュー)]> をクリックして、変更処理中に確認できるページのプレビューを開きます。標準の Salesforce ページヘッダー、サイドバー要素、取引先責任者のリストが表示された新規ウィンドウが開きます。A list of contacts from the standard list controller

標準リストコントローラーの使用方法は、標準コントローラーの使用方法によく似ています。最初に <>> コンポーネントの <>standardController> 属性を設定し、次に同じコンポーネントの <>recordSetVar> 属性を設定します。<>standardController> 属性では、標準コントローラーと同様に、作業するオブジェクトを設定します。recordSetVar では、レコードのコレクションで作成される変数の名前 (ここでは <>{! contacts }>) を設定します。命名規則に従って、通常この変数には複数形のオブジェクト名が付けられます。

<>> は、プラットフォームのスタイル設定が適用されたデータテーブルを生成する反復コンポーネントです。テーブルマークアップでの処理を次に示します。

  • <><>>> の value 属性は、標準リストコントローラー <><>{! contacts }>> で読み込まれた変数に設定されます。これは <><>>> で操作するレコードのリストです。
  • そのリストの各レコードに対して 1 レコードずつ、<><>>> はレコードを <><>>> の var 属性で指定された変数に割り当てます。この場合、変数には <><>ct>> が指定されます。
  • 各レコードに対して、<><>>> は <><>>> 本体内の一連の <><>>> コンポーネントで定義された行を使用して、テーブルに新しい行を作成します。<><>>> コンポーネントは、現在のレコードを表す <><>ct>> 変数を使用して、そのレコードの項目値を順に取得します。
  • ループの外側で、<><>>> は <><>>> コンポーネントの項目を使用して、各項目の表示ラベルを調べることで列ヘッダーを作成します。

これは非常に複雑で、最初は反復コンポーネントを理解することは難しいかもしれません。この時点でできることは、自分自身で作成してみることです。テーブルに表示する項目を選択します。<>> と <>> の別の属性を調べて、慣れるまで試してみてください。また、<>> や <>> など、その他いくつかの反復コンポーネントも使用してみてください。

リストにリストビューの検索条件を追加する

<>{! listViewOptions }> を使用して、オブジェクトで使用可能なリストビュー検索条件のリストを取得します。<>{! filterId }> を使用して、標準リストコントローラーの結果に使用するリストビュー検索条件を設定します。

標準リストコントローラーには、リストの表示を変更できる多数の機能があります。最も強力な機能の 1 つに、リストビュー検索条件があります。リストビュー検索条件は、コードを使用せずにクリックで宣言的に作成します。標準リストコントローラーでは、ページで定義済みのリストビュー検索条件を使用できます。

  1. <><>>> 全体を <><>>> タグでラップします。標準リストコントローラーのリストビュー検索条件を変更するには、新しい値をサーバーに送信する必要があります。この送信を実行する一般的な方法は、<><>>> コンポーネントで作成されたフォームを使用することです。
  2. <><>>> タグで、次の属性を追加します。
id="contacts_list"

Ajax 効果 (これについては後ほど説明します) に使用できる「名前」が <>> に付けられます。

  1. <><>>> 開始タグの後、<><>>> の上に、次のマークアップを追加します。
    Filter:
    <apex:selectList value="{! filterId }" size="1">
        <apex:selectOptions value="{! listViewOptions }"/>
        <apex:actionSupport event="onchange" reRender="contacts_list"/>
    </apex:selectList>
    ページの完全なコードは次のようになります。
    <apex:page standardController="Contact" recordSetVar="contacts">
        <apex:form>
            <apex:pageBlock title="Contacts List" id="contacts_list">
                Filter:
                <apex:selectList value="{! filterId }" size="1">
                    <apex:selectOptions value="{! listViewOptions }"/>
                    <apex:actionSupport event="onchange" reRender="contacts_list"/>
                </apex:selectList>
                <!-- Contacts List -->
                <apex:pageBlockTable value="{! contacts }" var="ct">
                    <apex:column value="{! ct.FirstName }"/>
                    <apex:column value="{! ct.LastName }"/>
                    <apex:column value="{! ct.Email }"/>
                    <apex:column value="{! ct.Account.Name }"/>
                </apex:pageBlockTable>
            </apex:pageBlock>
        </apex:form>
    </apex:page>
    A new filter control appears above the list. Contacts list with list views filter
  2. メニューから異なる検索条件を選択します。取引先責任者リストはどのように変化するでしょうか。

ここで作成した [検索条件] メニューから新しいオプションを選択すると、2 つの変化があります。まず、新しい検索条件を選択したときにレコードのリストが変更されます。(いくつかの異なるオプションの選択が必要な場合があります。標準の DE 組織のサンプルデータを使用している場合、複数のリストビューで同じレコードが表示されます)。

次に、あまり目立ちませんが、<>ページ全体は再読み込みされることなく>、リストが更新されます。この「Ajax」効果は、<>> コンポーネントの <>reRender="contacts_list"> 属性で適用されます。コンポーネントと reRender の複合効果によって、reRender 属性で指定されたページの一部のみが更新されます。<>> に <>id="contacts_list"> を追加しているため、アクションの完了時に、ページ全体が再読み込みされることなく <>> のみが更新されます。

このページでのこの新機能の完全なライフサイクルは、次のようになります。

  • ページが読み込まれると、<><>{! listViewOptions }>> 式からリストを取得することで、使用可能な検索条件のメニューが <><>>> で作成されます。<><>listViewOptions>> は、標準リストコントローラーで提供されるプロパティです。
  • メニューから新しいオプションを選択すると、<><>>> コンポーネントによって <><>onchange>> イベントが起動されます。
  • <><>onchange>> が起動すると、<><>filterId>> プロパティに新しい項目を送信することで、新しく選択されたリストビューがページから戻され、<><>>> に設定されます。
  • プロパティが更新されると、contacts 変数の新しい該当レコードのコレクションを含む、サーバーからの新しい応答をページが受信します。
  • ただし、<><>>> ではページの一部のみの表示が指定されているため、ページ全体が再読み込みされる代わりに、Ajax (非同期 JavaScript) を使用してページが更新されます。

正味の効果は、複雑で高度な動作をほんの数行のマークアップの追加で実現できることにあります。

ページネーションをリストに追加する

標準リストコントローラーのページネーション機能を使用すると、ユーザーは長いリストのレコードを 1 「ページ」ずつ表示できます。

これまで開発してきた機能は、Developer Edition 組織のサンプルデータとして提供されている短いリストのレコードでは快適に動作します。ただし、数百や数千、または数百万件のレコードがある実際の組織ではどうでしょうか。すべてのレコードを 1 ページに表示した場合は、うまく機能しません。

実際、デフォルトでは、標準リストコントローラーは検索条件に一致する最初の 20 件 (存在する場合) のレコードのみを表示します。この 20 件以外のレコードにユーザーがアクセスできるようにしたり、1 ページに 20 件を超えるレコードを表示したりするにはどうすればよいでしょうか。

答えはページネーションにあります。ページネーションは標準の Web アプリケーションユーザーインターフェースです。長いリストのレコードを 1 「ページ」ずつ、通常は <>[Next (次へ)]> と <>[前へ]> リンクを使用して前後に移動できます。標準リストコントローラーや進行状況インジケーター、メニューなどのツールを使用してページにページネーションを追加し、ページあたりのレコード数を変更できます。

  1. 取引先責任者リスト <><>>> の下に、次のマークアップを追加します。
<!-- Pagination -->
<table style="width: 100%">
    <tr>
        <td>
            <!-- Page X of Y -->
        </td>
        <td align="center">
            <!-- Previous page -->
            <!-- Next page -->
        </td>
        <td align="right">
            <!-- Records per page -->
        </td>
    </tr>
</table>

追加する 3 つのページネーションコントロールを含めることができる HTML テーブルが作成されます。

Note

実際のページでは、個別のスタイル設定によりセマンティックなマークアップが使用される場合もありますが、ここでは簡潔で追加ステップの不要なプレーン HTML を使用します。

  1. <><>>> コメント行を次のマークアップで置き換えます。
Page: <apex:outputText value=" {!PageNumber} of {! CEILING(ResultSize / PageSize) }"/>

ユーザーが表示しているページと残りのページ数を示す、進行状況インジケーターがリストに追加されます。DE 組織で試行している場合は、「Page 1 of 1」 (1/1 ページ) と表示されます。

  1. Replace the <!-- Previous page --> and <!-- Next page -->comment lines with the following markup.
    <!-- Previous page -->
    <!-- active -->
    <apex:commandLink action="{! Previous }" value="« Previous"
         rendered="{! HasPrevious }"/>
    <!-- inactive (no earlier pages) -->
    <apex:outputText style="color: #ccc;" value="« Previous"
         rendered="{! NOT(HasPrevious) }"/>
    <!-- Next page -->
    <!-- active -->
    <apex:commandLink action="{! Next }" value="Next »"
         rendered="{! HasNext }"/>
    <!-- inactive (no more pages) -->
    <apex:outputText style="color: #ccc;" value="Next »"
         rendered="{! NOT(HasNext) }"/>
    This markup provides Previous and Next links on the page. The markup covers two possibilities: when there are more records to view in a given direction, then the link is active; and when there aren’t more pages in a given direction, the link is disabled.
  2. Replace the <!-- Records per page -->comment line with the following markup.
    Records per page:
    <apex:selectList value="{! PageSize }" size="1">
        <apex:selectOption itemValue="5" itemLabel="5"/>
        <apex:selectOption itemValue="20" itemLabel="20"/>
        <apex:actionSupport event="onchange" reRender="contacts_list"/>
    </apex:selectList>
    This markup provides a menu for changing the number of records per page. Here we’ve only added an option to display fewer records on a page. Select “5” from the list, and see what happens to the list, and the other controls.

標準リストコントローラーで提供される多数の機能が含まれたリストページが表示されます。

<img alt="Contacts list with pagination controls" class="image" src="images/kix.d9v8yz1afesw.jpg" width="672.0"/>

進行状況インジケーターでは、何ページあるかを示すために <>PageNumber>、<>ResultSize>、<>PageSize> の 3 つのプロパティが使用されています。最後の 2 つは、最も近い整数に四捨五入する数式で使用されます。これにより、インジケーターに「Page 2 of 1.6」 (2/1.6 ページ) などの不適切な値が表示されることを防ぎます。

ページネーションコントロールの <>> コンポーネントは、標準リストコントローラー <>Previous> と <>Next> で提供される 2 つのアクションメソッドを参照します。その結果、<>Previous> または <>Next> アクションを実行するリンクが表示されます。

では、<>{! HasPrevious }> などの式が含まれる rendered 属性は何を意味するのでしょうか。Visualforce はこの属性によって、コンポーネントを条件付きで (Boolean 式の結果に応じて) 表示できるようにします。ここでは、ページマークアップは標準リストコントローラー <>HasPrevious> と <>HasNext> で提供される Boolean プロパティを参照しています。これらのコントローラーは、指定方向にさらにレコードがあるかどうかを示します。rendered 属性でこの式を使用することで、そのコンポーネントの結果をページに表示または非表示にすることができます。これにより、ページを最初に読み込んだときは <>[前へ]> リンクがグレー表示になり、<>[Next (次へ)]> リンクをクリックして先に進むと有効になります。

ページあたりのレコード数選択メニューでは、以前に使用した <>> を使用しますが、メニューの値を取得するコントローラーメソッドをコールする代わりに、目的の値の <>> 要素を使用します。ここでも、<>> タグは選択値が変更された場合にメニューのアクションを実行し、<>reRender="contacts_list"> を使用して <>> のみを更新します。ここで異なる点は、<>> で標準リストコントローラーの <>PageSize> プロパティを設定していることです。

もうひとこと...

標準リストコントローラーには Web アプリケーションで一般的な多数の機能があり、ここで紹介している機能はほんの一部にすぎません。

たとえば、1 ページごとに前後に移動する <>Previous> アクションと <>Next> アクションに加えて、レコードのリストの先頭または最後に移動する <>First> アクションや <>Last> アクションもあります。

マークアップで操作する標準リストコントローラーは、<>StandardSetController> Apex クラスに基づいています。このクラスの詳細とすべての機能については、<>『Apex リファレンスガイド』>を参照してください。

ここで作成した例では、並び替えの問題があります。通常はリストのデフォルトの並び替え順を設定し、並び替え順をその場で変更できる列ヘッダーを含めることが望まれます。実際には、Visualforce 単独で並び替え順を変更することはできません。並び替えとクリック可能な列ヘッダーをサポートするために必要な追加の Visualforce マークアップと Apex コードの量はそれほど多くありませんが、カスタムコードが必要になります。その開始点については、その他のリソースを参照してください。

リソース

Salesforce ヘルプで Trailhead のフィードバックを共有してください。

Trailhead についての感想をお聞かせください。[Salesforce ヘルプ] サイトから新しいフィードバックフォームにいつでもアクセスできるようになりました。

詳細はこちら フィードバックの共有に進む