In AngularJS, i filtri sono componenti con il compito di formattare o comunque applicare una elaborazione al risultato di una espressione. Il loro utilizzo all'interno di una view è abbastanza semplice ed è basato sull'uso dell'operatore pipe
(|), come nel seguente esempio:
<p>{{"Hello Angular" | uppercase }}</p>
In questo caso la stringa "Hello Angular" viene elaborata dal filtro uppercase
che trasforma in maiuscolo tutti i suoi caratteri e ci permette di ottenere il seguente risultato:
<p>HELLO ANGULAR</p>
Combinare filtri in AngularJS
Possiamo combinare più filtri mettendoli in sequenza. Ad esempio, la seguente espressione trasforma la stringa "Hello Angular" prima in maiuscolo e poi in minuscolo:
<p>{{"Hello Angular" | uppercase | lowercase }}</p>
Una espressione con più filtri viene elaborata dal primo filtro, il risultato diventa l'input del secondo filtro e così via fino all'ultimo filtro della sequenza. Nel nostro caso il risultato finale sarà:
<p>hello angular</p>
Filtri con parametri
I filtri prevedono la possibilità di passare dei parametri per definire modalità di formattazione o comunque per modificare l'elaborazione predefinita. Ad esempio, la seguente espressione estrae i primi 5 caratteri di una stringa:
<p>{{"Hello Angular" | limitTo:5 }}</p>
Il filtro limitTo
prevede un parametro specificato dopo i due punti. Il risultato ottenuto sarà:
<p>Hello</p>
Nel caso di più parametri, questi saranno specificati uno dopo l'altro separati dai due punti, come nel seguente schema:
{{espressione | filtro:par1:par2:par3 }}
Filtri predefiniti in AngularJS
Angular mette a disposizione alcuni filtri predefiniti, elencati di seguito, che ci consentono di gestire le più comuni problematiche di formattazione ed elaborazione:
Filtro | Descrizione |
---|---|
lowercase | Trasforma una stringa in caratteri minuscoli |
uppercase | Trasforma una stringa in caratteri maiuscoli |
number | Formatta un numero |
currency | Formatta un numero come valuta |
date | Formatta una data |
orderBy | Ordina gli elementi di un array |
limitTo | Estrae i primi n elementi di un insieme (stringa, array) |
filter | Estrae gli elementi di un array che soddisfano un determinato criterio |
Abbiamo già visto il funzionamento di lowercase
e uppercase
, vediamo brevemente come utilizzare gli altri filtri predefiniti.
number
Il filtro number
formatta un numero inserendo il separatore di migliaia e gestendo i decimali. Il comportamento predefinito prevede che, in presenza di decimali, il numero venga arrotondato alle tre cifre. Quindi dal seguente esempio:
<p>{{3.14159 | number}}</p>
otterremo il seguente risultato:
<p>3.142</p>
Per personalizzare il risultato, possiamo definire il numero di cifre decimali da restituire passandolo come parametro del filtro. I seguenti sono esempi di applicazione:
<p>{{3.14159 | number:2}}</p>
<p>{{3.14159 | number:0}}</p>
che danno come risultato:
<p>3.14</p>
<p>3</p>
Occorre tener presente che la formattazione predefinita delle migliaia prevede come simbolo la virgola. Infatti, la seguente espressione
<p>{{1450,32 | number}}</p>
produce come risultato il valore che segue:
<p>1,450.32</p>
È possibile personalizzare la formattazione sfruttando la localizzazione, come vedremo in seguito.
currency
Il filtro currency
ci consente di formattare un numero come valuta. Il suo comportamento predefinito consiste nel formattare il numero arrotondandolo a due decimali e premettendo ad esso il simbolo del dollaro. Ad esempio, la seguente espressione:
<p>{{1200.451 | currency}}</p>
produce il seguente risultato:
<p>$1,200.45</p>
Possiamo personalizzare il risultato passando due parametri al filtro: il primo parametro rappresenta il simbolo della valuta che vogliamo applicare, il secondo rappresenta il numero di decimali da visualizzare. Considerando la seguente espressione
<p>{{1200.451 | currency:"€":0}}</p>
otteniamo il seguente risultato:
<p>€1,200</p>
date
Il filtro date
ci permette di formattare una data in maniera abbastanza flessibile. Consideriamo il seguente esempio:
$scope.dataOra = Date.now();
...
<p>{{dataOra | date}}</p>
L'applicazione del filtro date
ci consente di ottenere la data formattata come mostrato di seguito:
Apr 12, 2015
Notiamo come in realtà otteniamo soltanto la data. Possiamo personalizzare il formato restituito passando un parametro. I seguenti esempi ci indicano i risultati ottenuti in base al parametro passato:
Esempio | Risultato |
---|---|
{{dataOra | date:"fullDate"}} |
Sunday, April 12, 2015 |
{{dataOra | date:"longDate"}} |
April 12, 2015 |
{{dataOra | date:"medium"}} |
Apr 12, 2015 8:40:46 AM |
{{dataOra | date:"short"}} |
4/12/15 8:40 AM |
{{dataOra | date:"shortTime"}} |
8:40 AM |
Oltre ai formati predefiniti, possiamo costruirci un nostro formato come mostrato dai seguenti esempi:
Esempio | Risultato |
---|---|
{{dataOra|date:"dd-MM-yyyy"}} |
12-04-2015 |
{{dataOra|date:"yyyy-MM-dd HH:mm:ss Z"}} |
2015-04-12 08:40:04 +0200 |
{{dataOra|date:"EEEE dd/MM/yyyy"}} |
Sunday 12/04/2015 |
{{dataOra|date:"'Il giorno ' dd/MM/yyyy"}} |
Il giorno 12/04/15 |
Maggiori dettagli sui simboli che si possono utilizzare nella costruzione dei formati personalizzati si trovano sulla documentazione ufficiale di AngularJS.
orderBy
Oltre che alla formattazione, un filtro può avere lo scopo di applicare una trasformazione al risultato di un'espressione. E' questo ad esempio il caso del filtro orderBy
, il quale ordina gli elementi contenuti in un elenco. Il seguente esempio mostra l'applicazione del filtro ad un array di numeri:
<p>{{[5,3,6,1] | orderBy}}</p>
Il risultato ottenuto è un array con i numeri in ordine crescente:
<p>[1,3,5,6]</p>
Il filtro può essere applicato anche ad elenchi di oggetti. Immaginiamo infatti di aver definito il seguente array nel controller:
$scope.elencoCitta = [
{nome: "Roma", regione: "Lazio"},
{nome: "Latina", regione: "Lazio"},
{nome: "Milano", regione: "Lombardia"},
{nome: "Napoli", regione: "Campania"},
{nome: "Como", regione: "Lombardia"},
{nome: "Palermo", regione: "Sicilia"},
{nome: "Caserta", regione: "Campania"},
{nome: "Avellino", regione: "Campania"},
{nome: "Trapani", regione: "Sicilia"},
{nome: "Agrigento", regione: "Sicilia"}
];
Possiamo visualizzare l'elenco delle città in ordine alfabetico come mostrato di seguito:
<ul>
<li ng-repeat="citta in elencoCitta | orderBy:'nome'">{{citta.nome}}</li>
</ul>
Come possiamo vedere, al filtro orderBy
è stato passato il nome della proprietà in base alla quale ordinare l'elenco. L'ordinamento predefinito è quello crescente, ma possiamo ordinare gli elementi in ordine decrescente con due modalità: facendo precedere il segno meno al nome della proprietà o indicando un secondo parametro di tipo booleano il cui valore true
indica l'ordinamento decrescente. In pratica, le seguenti impostazioni avranno il medesimo effetto, cioè restituiscono l'elenco delle città in ordine descrescente sul nome:
<ul>
<li ng-repeat="citta in elencoCitta | orderBy:'-nome'">{{citta.nome}}</li>
</ul>
<ul>
<li ng-repeat="citta in elencoCitta | orderBy:'nome':true">{{citta.nome}}</li>
</ul>
limitTo
Come abbiamo già avuto modo di vedere, il filtro limitTo
estrae un sottoinsieme degli elementi da un elenco in base al parametro passato. Ad esempio, se nella lista delle città vogliamo vedere soltanto le prime tre, possiamo scrivere il seguente codice:
<ul>
<li ng-repeat="citta in elencoCitta | limitTo:3">{{citta.nome}}</li>
</ul>
Il filtro estrae gli elementi della lista partendo dal primo. Allo stato attuale non è previsto un modo per estrarre gli elementi a partire da un elemento indicato dall'utente.
filter
Il filtro filter
ha lo scopo di filtrare gli elementi di un elenco in base ad una condizione. Se, ad esempio, indichiamo la seguente espressione:
<ul>
<li ng-repeat="citta in elencoCitta | filter:{regione: 'Sicilia'}">
{{citta.nome}}</li>
</ul>
otterremo l'elenco delle città della Sicilia. Evidenziamo il fatto che il valore specificato nel criterio per filtrare i dati viene sempre interpretato come "contiene" e non come "uguale a". Il seguente esempio, infatti, seleziona le città la cui regione contiene una lettera L, ottenendo quindi le città del Lazio, della Lombardia e della Sicilia:
<ul>
<li ng-repeat="citta in elencoCitta | filter:{regione: 'L'}">
{{citta.nome}}</li>
</ul>
Combinare sequenze di criteri
Possiamo combinare insieme più criteri specificandoli in sequenza, come nel seguente esempio:
<ul>
<li ng-repeat="citta in elencoCitta | filter:{regione: 'L', nome: 'R'}">
{{citta.nome}}</li>
</ul>
Nell'esempio stiamo chiedendo l'elenco delle città la cui regione contiene una L ed il nome contiene una R
. facendo riferimento al nostro elenco di città, il risultato sarà costituito da Roma, Palermo, Trapani ed Agrigento.
Una sequenza di criteri viene sempre combinata in AND. Allo stato attuale non è prevista la combinanzione dei criteri in OR.
Sfruttando il two-way binding
, possiamo costruire un filtro interattivo su un elenco di città in modo estremamente semplice, come mostrato dal seguente codice:
Filtra per nome: <input type="text" ng-model="filtro">
<ul>
<li ng-repeat="citta in elencoCitta | filter:{nome:filtro}">{{citta.nome}}</li>
</ul>
Abbiamo definito una casella di testo tramite la quale l'utente può specificare il proprio filtro di selezione. La casella di testo è legata alla variabile filtro
, che viene utilizzata per filtrare l'elenco dei dati visualizzati. Il risultato grafico ottenuto è il seguente:
L'elenco delle città verrà filtrato dinamicamente non appena l'utente inizia a digitare nella casella di testo.
Se al filtro filter
non passiamo un oggetto con le proprietà che indicano il criterio di filtro, ma direttamente un valore, quel valore verrà ricercato in tutte le proprietà degli elementi dell'elenco.
Consideriamo il seguente esempio:
<ul>
<li ng-repeat="citta in elencoCitta | filter:'R'">
{{citta.nome}}</li>
</ul>
Esso visualizza l'elenco delle città che hanno una R
nel nome o nel nome della regione.