Skip to main content

Utilizzare controller di elenco standard

Obiettivi di apprendimento

Al completamento di questa unità, sarai in grado di:

  • Spiegare cos'è un controller di elenco standard di Visualforce e come si differenzia da un controller (record) standard.
  • Indicare tre azioni fornite dal controller di elenco standard che sono diverse da quelle di un controller standard.
  • Visualizzare un elenco di record utilizzando un controller di elenco standard su una pagina Visualforce.
  • Definire la paginazione e poterla aggiungere a una pagina Visualforce.
Nota

Nota

Stai seguendo la formazione in italiano? Inizia la sfida in un Trailhead Playground in italiano e utilizza le traduzioni fornite tra parentesi per la navigazione. Per quanto riguarda i valori da inserire, copia e incolla solo quelli in lingua inglese, perché la convalida della sfida è basata sul fatto che i dati siano in inglese. Se non superi la sfida nella tua organizzazione italiana, ti consigliamo di (1) selezionare Stati Uniti per le impostazioni internazionali, (2) selezionare Inglese per la lingua seguendo le istruzioni riportate qui e, successivamente, (3) fare nuovamente clic sul pulsante "Controlla la sfida".

Visita il badge Trailhead nella tua lingua per informazioni dettagliate su come usufruire dell'esperienza Trailhead in altre lingue.

Introduzione al controller di elenco standard

Il controller di lista standard consente di creare pagine Visualforce che possono visualizzare o agire su un insieme di record.

La visualizzazione di un elenco di record è un comportamento fondamentale di quasi tutte le app web. Con Visualforce è estremamente facile visualizzare un elenco di record dello stesso tipo, utilizzando solo il markup e nessun codice back-end. Il segreto, come sempre, è il controller standard, in questo caso il controller di elenco standard.

Il controller di elenco standard offre molti comportamenti efficaci e automatici, ad esempio eseguire query per trovare i record di un oggetto specifico e rendere disponibili i record in una variabile raccolta, nonché filtrare ed effettuare la paginazione dei risultati. L'aggiunta del controller di elenco standard a una pagina è molto simile all'aggiunta del controller (record) standard, ma mira a operare con più record contemporaneamente, anziché con un record alla volta.

Visualizzare un elenco di record

Per visualizzare un elenco di record, si usa il controller di elenco standard e un componente di iterazione, ad esempio <apex:pageBlockTable>.

Il controller (record) standard consente di caricare facilmente un singolo record in una variabile utilizzabile in una pagina Visualforce. Il funzionamento del controller di elenco standard è simile, ma anziché caricare un singolo record, carica un elenco, o una raccolta, di record nella variabile.

Poiché si ha a che fare con una raccolta, anziché con un singolo record, è necessario utilizzare un componente di iterazione per visualizzarli. Un componente di iterazione lavora con una raccolta di elementi simili, anziché su un singolo valore. Un componente di iterazione esegue un loop sulla sua raccolta e per ciascun record genera un output basato su un modello da te fornito nel markup del componente. A parole sembra complicato, ma si capisce subito leggendo il markup.

Il markup per l'utilizzo del controller di elenco standard è quasi identico a quello per l'utilizzo del controller standard, "un record alla volta". Per rendere la cosa palese, nell'esempio riportato di seguito le differenze principali sono evidenziate in grassetto.

  1. Apri la Developer Console e fai clic su File | New | Visualforce Page (File | Nuovo | Pagina Visualforce) per creare una nuova pagina Visualforce. Inserisci ContactList come nome della pagina.
  2. Nell'editor, sostituisci qualsiasi markup con il seguente.
    <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. Fai clic su Preview (Anteprima) per aprire un'anteprima della pagina che potrai guardare mentre apporti le modifiche. Si apre una nuova finestra in cui sono visualizzati gli elementi standard dell'intestazione e della barra laterale della pagina di Salesforce e un elenco dei referenti. Un elenco di referenti dal controller di elenco standard

L'utilizzo di un controller di elenco standard è molto simile a quello di un controller standard. Per prima cosa imposta l'attributo standardController sul componente <apex:page> , poi imposta l'attributo recordSetVar sullo stesso componente. L'attributo standardController imposta l'oggetto con cui lavorare, proprio come avviene con il controller standard. L'attributo recordSetVar imposta il nome della variabile da creare con la raccolta di record, in questo caso {!contacts }. Per convenzione, questa variabile viene solitamente chiamata con il plurale del nome oggetto.

<apex:pageBlockTable> è un componente di iterazione che genera una tabella di dati, con tanto di stile della piattaforma. Ecco cosa accade nel markup della tabella.

  • L'attributo value di <apex:pageBlockTable> è impostato sulla variabile caricata dal controller di elenco standard, {!contacts }. Si tratta dell'elenco dei record con cui opererà <apex:pageBlockTable>.
  • <apex:pageBlockTable> assegna singolarmente ciascun record dell'elenco alla variabile indicata nell'attributo var di <apex:pageBlockTable>. Nel nostro caso, il nome della variabile è ct.
  • Per ciascun record, <apex:pageBlockTable> costruisce una nuova riga nella tabella, utilizzando la riga definita dall'insieme di componenti <apex:column> presenti all'interno del corpo di <apex:pageBlockTable>. I componenti <apex:column>, a loro volta, utilizzano la variabile ct che rappresenta il record corrente, per estrarre i valori dei campi di quel record.
  • Al di fuori del loop, <apex:pageBlockTable> utilizza i campi associati ai componenti <apex:column> per creare intestazioni di colonna, cercando l'etichetta di ciascun campo.

Sono molte cose da assimilare e i componenti dell'iterazione sono difficili da comprendere al primo impatto. La cosa migliore che puoi fare in questo momento è provare a crearne di tuoi. Scegli i campi che desideri vengano visualizzati nella tabella. Cerca i diversi attributi per <apex:pageBlockTable> e <apex:column> e fai esperimenti finché non ti senti a tuo agio. Puoi anche provare a utilizzare alcuni degli altri componenti dell'iterazione, ad esempio <apex:dataList> o persino <apex:repeat>.

Aggiungere il filtro della visualizzazione elenco

Per ottenere un elenco dei filtri della visualizzazione elenco disponibili per un oggetto si usa {!listViewOptions }. Per impostare il filtro della visualizzazione elenco da utilizzare per i risultati di un controller di elenco standard, si usa {!filterId }.

Il controller di elenco standard offre una serie di funzioni utilizzabili per modificare la visualizzazione elenco. Una delle più efficaci è quella dei filtri della visualizzazione elenco. I filtri della visualizzazione elenco si creano in modo dichiarativo, facendo clic anziché usando il codice, e il controller di elenco standard permette di utilizzare qualsiasi filtro della visualizzazione elenco definito nella pagina.

  1. Inserisci l'intero componente <apex:pageBlock> in un tag <apex:form>. Per modificare il filtro della visualizzazione elenco per un controller di elenco standard, occorre rimandare il nuovo valore al server. Il modo standard di eseguire questo invio è quello di utilizzare un modulo creato con il componente <apex:form>.
  2. Nel tag <apex:pageBlock>, aggiungi il seguente attributo.
id="contacts_list"

Questo attribuisce all'<apex:pageBlock> un "nome" utilizzabile per un simpatico effetto Ajax, che spiegheremo tra poco.

  1. Dopo il tag <apex:pageBlock> di apertura e sopra il componente <apex:pageBlockTable>, aggiungi il seguente markup.
    Filter:
    <apex:selectList value="{! filterId }" size="1">
        <apex:selectOptions value="{! listViewOptions }"/>
        <apex:actionSupport event="onchange" reRender="contacts_list"/>
    </apex:selectList>
    Il codice completo della pagina dovrebbe presentarsi così.
    <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>
    Un nuovo controllo del filtro viene visualizzato sopra l'elenco. Elenco referenti con filtro visualizzazioni elenco
  2. Seleziona un filtro diverso dal menu. Cosa succede all'elenco dei referenti?

Quando effettui una nuova selezione dal menu di filtraggio appena creato, noterai due cose. La prima è che l'elenco dei record cambia quando si sceglie un nuovo filtro. (Potrebbe essere necessario provare un paio di opzioni diverse: alcune visualizzazioni elenco presentano gli stessi record quando si utilizzano i dati di esempio in un'organizzazione DE standard.)

La seconda, meno evidente, è che l'elenco si aggiorna senza ricaricare l'intera pagina. Questo effetto "Ajax" si deve all'attributo reRender="contacts_list" del componente <apex:actionSupport>. L'effetto combinato del componente e del reRender si traduce nell'aggiornamento della sola parte di pagina indicata nell'attributo reRender. Avendo aggiunto id="contacts_list" a <apex:pageBlock>, al completamento dell'azione viene aggiornato solo <apex:pageBlock>, evitando la necessità di ricaricare l'intera pagina.

Il ciclo di vita completo delle nuove funzioni di questa pagina avviene più o meno in questo modo.

  • Quando la pagina viene caricata, <apex:selectList> crea un menu che contiene i filtri disponibili, recuperando l'elenco tramite l'espressione {!listViewOptions }. listViewOptions è una proprietà fornita dal controller di elenco standard.
  • La scelta di una nuova opzione dal menu provoca l'innesco dell'evento onchange da parte del componente <apex:actionSupport>.
  • Quando onchange viene innescato, la pagina reinvia la nuova visualizzazione elenco selezionata, inviando il nuovo elemento alla proprietà filterId, impostata in <apex:selectList>.
  • Quando la proprietà viene aggiornata, la pagina riceve una nuova risposta dal server, con una nuova raccolta di record corrispondenti nella variabile referenti.
  • Ma poiché <apex:actionSupport> specifica che deve essere rieseguito il rendering di solo una parte della pagina, la pagina viene aggiornata utilizzando Ajax (JavaScript asincrono) anziché ricaricando l'intera pagina.

Il risultato netto è un comportamento complesso e avanzato con l'aggiunta di poche righe di markup.

Aggiungere la paginazione all'elenco

Utilizza le funzioni di paginazione del controller di elenchi standard per consentire agli utenti di consultare lunghi elenchi di record una "pagina" alla volta.

Le funzioni che hai sviluppato finora sono molto interessanti e funzionano egregiamente con il breve elenco di record forniti come dati di esempio in un'organizzazione della Developer Edition. Ma cosa succede quando ci si misura con un'organizzazione reale, costituita da centinaia, migliaia o addirittura milioni di record? Visualizzarli tutti in un'unica pagina non è certo l'ideale!

Di fatto, per impostazione predefinita il controller di elenco standard visualizza solo i primi 20 record che corrispondono ai criteri del filtro, se presenti. Come si fa a permettere alle persone di accedere a un numero di record maggiore rispetto ai primi 20 o magari a un numero di record per pagina maggiore di 20?

La risposta è la paginazione. Si tratta di un elemento standard dell'interfaccia utente di un'app web che consente di spostarsi avanti e indietro in un lungo elenco di record, una "pagina" alla volta, di solito utilizzando i link Next (Avanti) e Previous (Indietro). Puoi aggiungerlo alla pagina utilizzando il controller di elenco standard, in aggiunta ad altre comode funzioni come un indicatore di avanzamento e un menu per modificare il numero di record per pagina.

  1. Aggiungi il seguente markup al di sotto all'elenco dei referenti </apex:pageBlockTable>.
<!-- 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 markup crea una tabella HTML che conterrà i tre controlli di paginazione che aggiungerai.

Nota

Nelle pagine reali potresti utilizzare un markup maggiormente semantico con stili separati. Tuttavia, per il momento utilizzeremo codice HTML semplice, più conciso e meno ingombrante.

  1. Sostituisci la riga di commento <!-- Page X of Y --> (Pagina X di Y) con il seguente markup.
Page: <apex:outputText value=" {!PageNumber} of {! CEILING(ResultSize / PageSize) }"/>

In questo modo viene aggiunto all'elenco un indicatore di avanzamento, che indica la pagina visualizzata dall'utente e il numero di pagine rimanenti. Se stai provando a farlo in un'organizzazione DE, probabilmente indicherà "Pagina 1 di 1".

  1. Sostituisci le righe di commento <!-- Previous page --> (Pagina precedente) e <!-- Next page --> (Pagina successiva) con il seguente 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) }"/>
    Questo markup crea collegamenti Indietro e Avanti nella pagina. Il markup contempla due possibilità: quando ci sono più record da visualizzare in una determinata direzione, il link è attivo; quando non ci sono più pagine in una determinata direzione, il link viene disabilitato.
  2. Sostituisci la riga di commento <!-- Records per page --> (Record per pagina) con il seguente 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>
    Questo markup fornisce un menu per modificare il numero di record per pagina. Qui ci siamo limitati ad aggiungere un'opzione per visualizzare un minor numero di record in una pagina. Prova a selezionare "5" dall'elenco e vedi cosa succede all'elenco e agli altri controlli.

Il risultato è una pagina di elenco che presenta parecchie funzioni fornite dal controller di elenco standard.

Elenco referenti con controlli di paginazione

L'indicatore di avanzamento utilizza tre proprietà per indicare il numero di pagine presenti: PageNumber, ResultSize e PageSize. Le ultime due vengono utilizzate in un'espressione formula, che arrotonda il numero all'intero più vicino. In questo modo si impedisce all'indicatore di riportare informazioni senza senso, ad esempio "Pagina 2 di 1.6".

Nei controlli di paginazione, i componenti <apex:commmandLink> fanno riferimento a due metodi di azione forniti dal controller di elenco standard, Previous (Indietro) e Next (Avanti). Il risultato è un link che esegue l'azione Previous o Next.

Ma in che cosa consiste l'attributo visualizzato con espressioni come {!HasPrevious }? Si tratta di un metodo utilizzato da Visualforce per visualizzare i componenti in modo condizionato, cioè in base al risultato di un'espressione booleana. In questo caso il markup della pagina fa riferimento alle proprietà booleane fornite dal controller di elenco standard, HasPrevious e HasNext, che permettono di sapere se ci sono altri record in una determinata direzione o meno. Utilizzando l'espressione nell'attributo visualizzato, è possibile mostrare o nascondere i risultati di quel componente sulla pagina. In questo modo il link Previous (Indietro) viene disattivato al primo caricamento della pagina, ma diventa attivo se si avanza facendo clic sul link Next (Avanti).

Il menu di selezione dei record per pagina utilizza <apex:selectList>, già impiegato in precedenza. Tuttavia, anziché chiamare un metodo controller per ottenere i valori del menu, utilizziamo semplicemente gli elementi <apex:selectOption> per i valori desiderati. Ancora una volta, il tag <apex:actionSupport> fa sì che il menu attivi la sua azione ogni volta che il valore selezionato cambia e, ancora una volta, utilizza reRender="contacts_list" per aggiornare solamente <apex:pageBlock>. La novità è che <apex:selectList> imposta la proprietà PageSize del controller di elenco standard.

Ulteriori informazioni...

Il controller di elenco standard offre molte funzioni comuni alle app web, molte più di quelle che sono state trattate in questa sede.

Ad esempio, oltre alle azioni Previous (Indietro) e Next (Avanti), che consentono di spostarsi avanti e indietro una pagina alla volta, esistono anche le azioni First (Primo) e Last (Ultimo) che consentono di andare all'inizio o alla fine dell'elenco dei record.

Dietro alle quinte del markup, il controller di elenco standard si basa sulla classe Apex StandardSetController. Per saperne di più sull'argomento e su tutte le funzioni offerte, consulta la Guida per gli sviluppatori di Apex Code di Lightning Platform.

Nella stanza degli esempi che abbiamo creato si cela un piccolo elefante, il cui nome è "ordinamento". Spesso è auspicabile disporre sia di un ordinamento predefinito per un elenco sia di intestazioni di colonna che influenzino l'ordinamento e che ti consentano di cambiare l'ordine all'istante. Il fatto è che non è possibile modificare l'ordinamento solo utilizzando Visualforce. Benché la quantità di markup Visualforce e di Apex Code aggiuntivi necessari per supportare l'ordinamento e le intestazioni di colonna selezionabili non sia enorme, richiede comunque del codice personalizzato. Per alcuni spunti, consulta le risorse aggiuntive.

Risorse

Condividi il tuo feedback su Trailhead dalla Guida di Salesforce.

Conoscere la tua esperienza su Trailhead è importante per noi. Ora puoi accedere al modulo per l'invio di feedback in qualsiasi momento dal sito della Guida di Salesforce.

Scopri di più Continua a condividere il tuo feedback