Utilisation de contrôleurs de liste standard
Objectifs de formation
Une fois cette unité terminée, vous pourrez :
- Présenter un contrôleur de liste standard Visualforce et ce qui le différencie d’un contrôleur standard (enregistrement)
- Citer trois actions fournies par le contrôleur de liste standard qui sont différentes de celles d'un contrôleur standard
- Afficher une liste d’enregistrements en utilisant un contrôleur de liste standard dans une page Visualforce
- Définir une pagination et l’ajouter à une page Visualforce
Présentation du contrôleur de liste standard
Le contrôleur de liste standard permet de créer des pages Visualforce qui peuvent s’afficher ou agir en fonction d’un ensemble d’enregistrements.
L'affichage d'une liste d'enregistrements est un comportement fondamental dans la grande majorité des applications Web. Visualforce facilite considérablement l’affichage d’une liste d’enregistrements de même type, en utilisant uniquement un balisage, sans code back-end. Le secret, comme toujours, est le contrôleur standard, dans le cas présent le contrôleur list standard.
Le contrôleur list standard fournit de nombreux comportements puissants et automatiques, notamment l'interrogation des enregistrements d'un objet spécifique et la disponibilité des enregistrements dans une variable de collection, ainsi que le filtrage et la pagination des résultats. L'ajout d'un contrôleur list standard à une page est semblable à l'ajout d'un contrôleur (record) standard, mais avec pour objectif d'utiliser de nombreux enregistrements en même temps, pas un seul à la fois.
Affichage d'une liste d'enregistrements
Utilisez le contrôleur de liste standard et un composant d’itération, tel que <apex:pageBlockTable>
, pour afficher une liste d’enregistrements.
Le contrôleur standard (enregistrement) aide à charger un enregistrement unique dans une variable que vous pouvez utiliser dans une page Visualforce. Le contrôleur standard liste est similaire, mais au lieu d’un enregistrement unique, il charge une liste ou un ensemble d’enregistrements dans la variable.
Comme vous travaillez avec une collection d’enregistrements au lieu d’un enregistrement individuel, vous devez utiliser un composant d’itération pour les afficher. Un composant d'itération fonctionne avec une collection d'éléments similaires au lieu d'une valeur unique. Un composant d'itération crée une boucle sur sa collection et génère pour chaque enregistrement une sortie basée sur le modèle que vous fournissez dans le balisage du composant. Cela semble complexe, mais vous comprendrez rapidement en lisant le balisage.
Le balisage qui utilise le contrôleur de liste standard est presque identique au contrôleur standard (un enregistrement à la fois). Les principales différences sont mises en évidence en caractères en gras dans l'exemple ci-dessous.
- Ouvrez la Developer Console, puis cliquez sur File (Fichier) | New (Nouveau) | Visualforce Page (Page Visualforce) pour créer une page Visualforce. Saisissez le nom ContactList pour la page.
- Dans l'éditeur, remplacez le balisage par :
<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>
- Cliquez sur Preview (Aperçu) pour prévisualiser la page à mesure que vous la modifiez. Une nouvelle fenêtre doit s’ouvrir, comprenant l’en-tête de page et les éléments du menu latéral standard de Salesforce, ainsi que la liste de vos contacts.
L'utilisation d'un contrôleur de liste standard est très similaire à celle d'un contrôleur standard. Vous définissez d’abord l’attribut standardController
sur le composant <apex:page>
, puis l’attribut recordSetVar
sur le même composant. L'attribut standardController
définit l'objet à utiliser, comme avec le contrôleur standard. L’attribut recordSetVar définit le nom de la variable à créer avec la collection d’enregistrements, dans le cas présent {!contacts }
. Par convention, cette variable porte généralement le pluriel du nom de l'objet.
<apex:pageBlockTable>
est un composant d’itération qui génère un tableau de données dans le style de la plate-forme. Le balisage du tableau se présente comme suit :
- L’attribut value de
<apex:pageBlockTable>
est défini sur la variable chargée par le contrôleur de liste standard,{!contacts }
. Il correspond à la liste des enregistrements que<apex:pageBlockTable>
doit utiliser.
-
<apex:pageBlockTable>
attribue chaque enregistrement de cette liste à la variable nommée dans l’attribut var de<apex:pageBlockTable>
, au rythme d’un enregistrement à la fois. Dans le cas présent, la variable est nomméect
.
- Pour chaque enregistrement,
<apex:pageBlockTable>
crée une ligne dans le tableau en utilisant la ligne définie par l’ensemble de composants<apex:column>
du corps de<apex:pageBlockTable>
. À leur tour, les composants<apex:column>
utilisent la variablect
qui représente l’enregistrement actuel afin d’extraire les valeurs de champ correspondant à ce dernier.
- Hors de la boucle,
<apex:pageBlockTable>
utilise les champs des composants<apex:column>
pour créer des en-têtes de colonne en recherchant l’étiquette de chaque champ.
Cela représente de nombreux éléments à connaître et les composants d'itération sont difficiles à comprendre. La meilleure solution est d'essayer de créer votre propre composant. Sélectionnez les champs que vous souhaitez afficher dans le tableau. Recherchez les différents attributs de <apex:pageBlockTable>
et de <apex:column>
, puis testez-les jusqu’à ce que vous vous soyez familiarisé avec eux. Vous pouvez également utiliser d’autres composants d’itération, tels que <apex:dataList>
ou <apex:repeat>
.
Ajout d'un filtrage de vue de liste à la liste
Utilisez {!listViewOptions }
pour obtenir la liste des filtres de vue de liste disponibles pour un objet. Utilisez {!filterId }
pour définir le filtre de vue de liste à utiliser pour les résultats d’un contrôleur de liste standard.
Le contrôleur de liste standard fournit plusieurs fonctionnalités qui permettent de modifier l'affichage de la liste. Les filtres de vue de liste sont l'une des plus puissantes fonctionnalités. Vous créez des filtres de vue de liste par déclaration, à l'aide de clics au lieu d'un code, et le contrôleur de liste standard permet d'utiliser n'importe quel filtre de vue de liste défini sur la page.
- Placez l’intégralité de
<apex:pageBlock>
dans une balise<apex:form>
. Pour remplacer le filtre de vue de liste d'un contrôleur de liste standard, soumettez la nouvelle valeur au serveur. La méthode de soumission standard consiste à utiliser un formulaire créé avec le composant<apex:form>
.
- Dans la balise
<apex:pageBlock>
, ajoutez l’attribut ci-dessous.
id="contacts_list"
Il fournit un « nom » à <apex:pageBlock>
que nous pouvons utiliser pour créer un effet Ajax intéressant, que nous présenterons plus loin.
- Après la balise ouvrante
<apex:pageBlock>
et au-dessus de<apex:pageBlockTable>
, ajoutez le balisage ci-dessous.Le code complet de votre page doit se présenter comme suit :Filter: <apex:selectList value="{! filterId }" size="1"> <apex:selectOptions value="{! listViewOptions }"/> <apex:actionSupport event="onchange" reRender="contacts_list"/> </apex:selectList>
Un nouveau contrôle de filtre apparaît au-dessus de la liste.<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>
- Sélectionnez un autre filtre dans le menu. Que devient la liste de contacts ?
Lorsque vous sélectionnez dans le menu Filtrer que vous venez de créer, notez deux éléments. La liste des enregistrements change lorsque vous sélectionnez un nouveau filtre (vous pouvez essayer plusieurs options différentes, certaines vues de listes présentent les mêmes enregistrements lors de l'utilisation des exemples de données dans une organisation DE standard).
Plus subtil, la liste est mise à jour sans recharger la page entière. On doit cet effet « Ajax » à l’attribut reRender="contacts_list"
présent dans le composant <apex:actionSupport>
. L’effet combiné du composant et de reRender fait en sorte que seule la partie de page nommée dans l’attribut reRender soit mise à jour. Vous avez ajouté id="contacts_list"
à <apex:pageBlock>
. Par conséquent, une fois l’action terminée, seul <apex:pageBlock>
est mis à jour, sans que la page entière ait à être rechargée.
Le cycle de vie complet des nouvelles fonctionnalités de cette page fonctionne comme suit :
- Au chargement de la page,
<apex:selectList>
génère le menu des filtres disponibles en récupérant la liste avec l’expression{!listViewOptions }
.listViewOptions
est une propriété fournie par le contrôleur de liste standard.
- Lorsque vous sélectionnez une nouvelle option dans le menu, l’événement
onchange
est activé par le composant<apex:actionSupport>
.
- Lorsque
onchange
est activé, la page soumet la nouvelle vue de liste sélectionnée en soumettant le nouvel élément à la propriétéfilterId
, définie dans<apex:selectList>
.
- Lorsque la propriété est mise à jour, la page reçoit une nouvelle réponse du serveur, avec un nouvel ensemble d’enregistrements correspondants dans la variable contacts.
- Toutefois, comme
<apex:actionSupport>
spécifie que seulement une partie de la page doit être réaffichée, la page est mise à jour à l’aide d’Ajax (JavaScript asynchrone) au lieu d’être entièrement réactualisée.
En ajoutant quelques lignes de balisage seulement, vous obtenez un comportement complexe et sophistiqué.
Ajout d'une pagination à la liste
Utilisez les fonctionnalités de pagination du contrôleur de liste standard pour permettre aux utilisateurs de parcourir les longues listes d'enregistrements dans des « pages » individuelles.
Les fonctionnalités que vous avez développées jusqu'ici sont très intéressantes et fonctionnent très bien dans une organisation Developer Edition avec les quelques enregistrements fournis dans l'exemple de données. Que se passe-t-il dans une véritable organisation comptant des centaines ou des milliers (voire des millions) d'enregistrements ? Il est impossible de consulter tous les enregistrements sur une seule page !
Par défaut, contrôleur de liste standard affiche les 20 premiers enregistrements correspondant à vos critères de filtrage, le cas échéant. Comment accéder à davantage d'enregistrements ou afficher plus de 20 enregistrements par page ?
La réponse est la pagination. Il s'agit d'un élément d'interface utilisateur d'une application Web standard, qui permet parcourir une longue liste d'enregistrements, page par page, généralement à l'aide des liens Suivant et Précédent. Vous pouvez l'ajouter à votre page en utilisant le contrôleur de liste standard, ainsi que des outils pratiques tels qu'un indicateur de progression et un menu pour changer le nombre d'enregistrements par page.
- Sous la liste de contacts
<apex:pageBlockTable>
, ajoutez le balisage ci-dessous.
<!-- 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>
Il crée un tableau HTML contenant les trois contrôles de pagination que nous allons ajouter.
- Remplacez la ligne de commentaire
<!-- Page X of Y -->
(Page X sur Y) par le balisage ci-dessous.
Page: <apex:outputText value=" {!PageNumber} of {! CEILING(ResultSize / PageSize) }"/>
Il ajoute un indicateur de progression à la liste, qui indique la page que l'utilisateur visualise et le nombre total de pages. Si vous essayez ce balisage dans une organisation DE, il risque d'indiquer « Page 1 sur 1 ».
- Remplacez les lignes de commentaire
<!-- Previous page -->
(Page précédente) et<!-- Next page -->
(Page suivante) par le balisage ci-dessous.Ce balisage fournit les liens Précédent et Suivant de la page. Le balisage couvre deux possibilités : lorsqu'il y a davantage d'enregistrement à afficher à un certain endroit, le lien est activé ; lorsqu'il n'y a aucun enregistrement à afficher à un certain endroit, le lien est désactivé.<!-- 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) }"/>
- Remplacez la ligne de commentaire
<!-- Records per page -->
(Enregistrements par page) par le balisage ci-dessous.Ce balisage fournit un menu qui permet de changer le nombre d'enregistrements par page. Dans le cas présent, nous avons seulement ajouté une option qui permet de réduire le nombre d'enregistrements affichés dans une page. Sélectionnez « 5 » dans la liste, puis examinez la liste et les autres contrôles.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>
Une page de liste inclut plusieurs fonctionnalités fournies par le contrôleur de liste standard.
Dans l'indicateur de progression, trois propriétés sont utilisées pour indiquer le nombre total de pages : PageNumber
, ResultSize
et PageSize
. Les deux dernières propriétés sont utilisées dans une formule d'expression, qui arrondit le nombre à l'entier le plus proche. Cela empêche l'indicateur d'afficher une information inappropriée, par exemple « Page 2 sur 1,6 ».
Dans les contrôles de pagination, les composants <apex:commmandLink>
référencent deux méthodes d’action fournies par le contrôleur de liste standard, Previous
et Next
. Le résultat est un lien qui exécute l'action Previous
ou Next
.
Mais quel est donc cet attribut rendered contenant des expressions telles que {!HasPrevious }
? Avec cet attribut, Visualforce autorise l’affichage de composants sous certaines conditions, c’est-à-dire en fonction du résultat d’une expression booléenne. Dans le cas présent, le balisage de page référence des propriétés booléennes fournies par le contrôleur de liste standard, HasPrevious
et HasNext
, qui indiquent s'il existe d'autres enregistrements dans une direction donnée. En utilisant l’expression dans l’attribut rendered, vous pouvez afficher ou masquer les résultats de ce composant sur la page. Le lien Précédent est grisé au chargement initial de la page, puis s'active lorsque vous passez à la page suivante en cliquant sur le lien Suivant.
Le menu de sélection du nombre d’enregistrements par page utilise <apex:selectList>
, que vous avez employé plus tôt. Cependant, au lieu d’appeler une méthode de contrôleur pour obtenir les valeurs du menu, nous utilisons ici simplement des éléments <apex:selectOption>
pour les valeurs voulues. De même, la balise <apex:actionSupport>
indique au menu de déclencher son action à chaque fois que la valeur sélectionnée change, et elle utilise reRender="contacts_list"
pour mettre à jour uniquement <apex:pageBlock>
. Toutefois, ici, c’est la balise <apex:selectList>
qui définit la propriété PageSize
du contrôleur de liste standard.
En savoir plus...
Le contrôleur de liste standard offre d'autres fonctionnalités fréquemment utilisées dans les applications Web, qui sont beaucoup plus nombreuses que celles présentées ici.
Par exemple, en plus des actions Previous
et Next
, qui ouvrent la page précédente ou suivante, les actions First
et Last
permettent d'accéder au début ou à la fin d'une liste d'enregistrement.
À l'arrière-plan de votre balisage, le contrôleur de liste standard repose sur la classe Apex StandardSetController
. Pour en savoir plus sur cette classe et ses fonctionnalités, reportez-vous au Guide du développeur de code Apex.
Les exemples que nous avons créés ici présentent un petit problème de tri. Il est souvent souhaitable de définir un ordre de tri par défaut pour une liste, et d'activer le tri par en-tête de colonne qui permet de réorganiser une liste sur-le-champ. Le problème est que vous ne pouvez pas affecter l’ordre de tri en utilisant seulement Visualforce. La quantité de balisage Visualforce et de code Apex supplémentaires requis pour prendre en charge le tri et le clic sur les en-têtes de colonnes n’est pas très important, mais nécessite un code personnalisé. Reportez-vous aux ressources supplémentaires.
Ressources
-
Visualforce Developer Guide: Standard Controllers
-
Visualforce Developer Guide: Standard List Controllers
-
Guide du développeur Visualforce Create a Custom List View in Salesforce Classic
-
Guide du développeur Visualforce : composant apex:outputLink
-
Guide du développeur Visualforce : composant apex:repeat
-
Guide du développeur Apex : classe StandardController
-
Guide du développeur Apex : classe StandardSetController
-
Blog des développeurs Salesforce : Twitter Bootstrap and Visualforce in Minutes