Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Il componente DataGrid

Un componente particolarmente utile quando si tratta di mostrare dati tabellari. Nell'articolo vediamo il suo funzionamento e alcuni usi specifici
Un componente particolarmente utile quando si tratta di mostrare dati tabellari. Nell'articolo vediamo il suo funzionamento e alcuni usi specifici
Link copiato negli appunti

Flex e Flash mettono a disposizione un componente particolarmente utile quando si tratta di mostrare dati tabellari, ovvero il componente DataGrid. Tale componente permette di mostrare una serie di dati ed eventualmente ordinarli in base ad una determinata colonna, inoltre è anche possibile offrire all'utente la possibilità di modificare i dati contenuti nelle varie celle della tabella.

In questo articolo vedremo come creare un'istanza del componente DataGrid, come popolarla sfruttando un DataProvider e come agire sulla tabella per modificarne l'aspetto e alcune opzioni, tutto questo utilizzando Actionscript 3 e Flash CS3.

Creare un'istanza del componente DataGrid

Per prima cosa avviamo Flash CS3 e scegliamo di creare un nuovo file Actionscript 3; apriamo quindi il pannello Componenti (Finestra -> Componenti oppure Ctrl+F7), dalla categoria User Interface selezioniamo il componente DataGrid e trasciniamolo sullo stage.

Figura 1. Il componente DataGrid all'interno del pannello Componenti
Screenshot del pannello componenti

Il componente sullo stage apparirà come un quadrato bianco, in modo piuttosto scarno.

Figura 2. Il componente DataGrid posto sullo stage
Screenshot dello stage

Se proviamo a portarci sul pannello Parametri noteremo come, a differenza della maggior parte degli altri componenti, il DataGrid non preveda le voci data e label da popolare manualmente; questo perché il DataGrid può prevedere un diverso numero di righe e colonne e i nomi dei campi sono personalizzabili, quindi imposteremo il contenuto della tabella tramite Actionscript.

Concludiamo le operazioni sullo stage dando al componente il nome istanza tabella.

È anche possibile creare un'istanza del componente tramite Actionscript, tramite il codice:

Listato 1. Crea un'istanza del componente

import fl.controls.DataGrid;
var tabella:DataGrid = new DataGrid();
addChild(tabella)

È però necessario che il componente sia presente almeno nella libreria del filmato Flash, altrimenti non verrà creato.

Popolare il componente DataGrid

Apriamo il pannello Azioni (Finestra -> Azioni oppure F9) e inseriamo il codice:

Listato 2. Popola il componente DataGrid

import fl.data.DataProvider;
// creiamo un oggetto DataProvider
var dati:DataProvider = new DataProvider();
// lo popoliamo con i campi "Nome" e "Cognome" e i rispettivi valori
dati.addItem({Nome:"Mario", Cognome:"Bianchi"});
dati.addItem({Nome:"Franco", Cognome:"Rossi"});
dati.addItem({Nome:"Giuseppe", Cognome:"Verdi"});
// diciamo al componente di usare il dataProvider "dati" come fonte di dati
tabella.dataProvider = dati;

Per prima cosa importiamo la classe fl.data.DataProvider, necessaria per impostare un DataProvider tramite Actionscript, quindi creiamo un nuovo oggetto di nome dati che popoliamo poi con alcuni dati: notiamo come Nome e Cognome saranno identificati dal DataGrid come nomi delle colonne, mentre i dati saranno presentati su diverse righe, come possiamo vedere in figura.

Figura 3. Il componente DataGrid con i dati ricavati dal DataProvider
Screenshot del filmato

Possiamo notare come Cognome e Nome siano in ordine inverso rispetto a quanto indicato nel DataProvider: per essere sicuri che l'ordine delle colonne sia quello da noi desiderato possiamo sfruttare il comando addColumn del DataGrid, che come si può intuire aggiunge una colonna alla tabella e si rivela molto utile per mettere i campi nell'ordine desiderato e non avere risultati indesiderati, infatti ad esempio il codice:

Listato 3. Ordina le colonne

import fl.data.DataProvider;
var dati:DataProvider = new DataProvider();

dati.addItem({Anni:51,Nome:"Mario",Cognome:"Bianchi"});
dati.addItem({Anni:34,Nome:"Franco",Cognome:"Rossi"});
dati.addItem({Anni:27,Nome:"Giuseppe",Cognome:"Verdi"});

tabella.dataProvider = dati;

ordina le colonne in maniera decisamente poco intuitiva, come vediamo in figura.

Figura 4. Ordine non intuitivo delle colonne
Screenshot del filmato

Sfruttando invece il comando addColumn, come nel codice seguente, ordineremo le colonne come desideriamo. Questo si rivela particolarmente utile ovviamente nel caso di tabelle con molti campi.

Listato 5. Ordina le colonne con addColumn

import fl.data.DataProvider;
var dati:DataProvider = new DataProvider();

dati.addItem({Anni:51,Nome:"Mario",Cognome:"Bianchi"});
dati.addItem({Anni:34,Nome:"Franco",Cognome:"Rossi"});
dati.addItem({Anni:27,Nome:"Giuseppe",Cognome:"Verdi"});

tabella.addColumn("Cognome")
tabella.addColumn("Nome")
tabella.addColumn("Anni")

tabella.dataProvider = dati;

Figura 5. Ordine personalizzato delle colonne
Screenshot del filmato

Il DataProvider può essere popolato in diversi modi: oltre alla compilazione diretta che abbiamo appena visto potremmo usare come fonte di dati un array, in questo modo:

Listato 6. Usa come fonte di dati un array

import fl.data.DataProvider;
// creiamo un array
var array_dati:Array = new Array()
// popoliamo l'array con diversi dati
array_dati.push({Anni:51,Nome:"Mario",Cognome:"Bianchi"});
array_dati.push({Anni:34,Nome:"Franco",Cognome:"Rossi"});
array_dati.push({Anni:27,Nome:"Giuseppe",Cognome:"Verdi"});
// creiamo un DataProvider basato sulla struttura dell'array
var dati:DataProvider = new DataProvider(array_dati);

Oppure ricavando i dati da una struttura XML, così:

Listato 7. Usa come fonte di dati una struttura XML

import fl.data.DataProvider;
var xml_dati:XML = <items>
<item Anni="51" Nome="Mario" Cognome="Bianchi" />
<item Anni="34" Nome="Franco" Cognome = "Rossi" />
<item Anni="27" Nome="Giuseppe" Cognome="Verdi" />
</items>

var dati:DataProvider = new DataProvider(xml_dati);

Sempre basandosi su una struttura XML, potremmo caricare i dati da un file esterno:

Listato 8. Usando una struttura XML carica i dati da file esterno

import fl.data.DataProvider;
var dati:DataProvider
// Carichiamo un file XML esterno
var file:String = "dati.xml";
var req:URLRequest = new URLRequest(file);
var uLdr:URLLoader = new URLLoader();
uLdr.addEventListener(Event.COMPLETE, analizza);
uLdr.load(req);
// quando è stato caricato lo analizziamo
function analizza(event:Event):void {
  var ldr:URLLoader = event.currentTarget as URLLoader;
  var dati_xml:XML = new XML(ldr.data);
  // inseriamo i dati nel DataProvider
  dati = new DataProvider(dati_xml);
  // associamo il DataProvider alla tabella
  tabella.dataProvider = dati;
}

Vi sono quindi svariate modalità per popolare un DataProvider e di conseguenza per popolare un componente DataGrid: l'importante è che alla fine il DataProvider contenga tutte le colonne e i dati che desideriamo mostrare all'utente.

Ridimensionare il componente DataGrid

Per ridimensionare un DataGrid possiamo agire sia impostando separatamente altezza e larghezza (usando le proprietà height e width) oppure tramite il comando setSize(larghezza,altezza). Quindi aggiungere al nostro codice o le righe:

tabella.width = 300
tabella.height = 100

oppure il comando

tabella.setSize(300,100)

Darà in entrambi i casi il risultato:

Figura 6. La tabella ridimensionata
Screenshot del filmato

C'è un piccolo effetto indesiderato: se il ridimensionamento in larghezza non dà problemi, in altezza ci troviamo con una sorta di "buco", poichè le righe occupano meno spazio di quello impostato per la tabella.

C'è però un comando in grado di risolvere tutto, ovvero la proprietà rowCount.

Tale proprietà permette di impostare il numero di righe che il DataGrid deve mostrare e si occupa automaticamente di stabilire quanto sia lo spazio necessario; poichè il rowCount agisce solo sull'altezza sarà comunque necessario impostare la larghezza tramite la proprietà width. Ecco un esempio:

Listato 9. Inposta il numero di righe da mostrare

import fl.data.DataProvider;
var dati:DataProvider = new DataProvider();
dati.addItem({Anni:51,Nome:"Mario",Cognome:"Bianchi"});
dati.addItem({Anni:34,Nome:"Franco",Cognome:"Rossi"});
dati.addItem({Anni:27,Nome:"Giuseppe",Cognome:"Verdi"});
tabella.addColumn("Cognome")
tabella.addColumn("Nome")
tabella.addColumn("Anni")
tabella.dataProvider = dati;
tabella.width = 300
tabella.rowCount = 3

Figura 7.La tabella ridimensionata usando la proprietà rowCount
Screenshot del filmato

Nota: la proprietà rowCount stabilisce quante righe rendere visibili, quindi nel caso in cui il numero di righe fosse maggiore a quello impostato nel rowCount verrà mostrata una barra di scorrimento verticale.

È interessante notare come la proprietà rowCount si basi sul numero di righe indipendentemente dalla loro dimensione, infatti, qualora avessimo delle righe più alte dell'impostazione usando rowCount saremo sempre sicuri di mostrarle integralmente. Proviamo ad esempio il codice riportato di seguito, dove tramite la proprietà rowHeight sono state impostate righe alte ognuna 80 pixel.

Listato 10. Imposta le righe in altezza

import fl.data.DataProvider;
var dati:DataProvider = new DataProvider();
dati.addItem({Anni:51,Nome:"Mario",Cognome:"Bianchi"});
dati.addItem({Anni:34,Nome:"Franco",Cognome:"Rossi"});
dati.addItem({Anni:27,Nome:"Giuseppe",Cognome:"Verdi"});
dati.addItem({Anni:21,Nome:"Davide",Cognome:"Beltrame"});
dati.addItem({Anni:45,Nome:"Valeria",Cognome:"Rossi"});
dati.addItem({Anni:71,Nome:"Virgilia",Cognome:"Corsinovi"});
tabella.addColumn("Cognome")
tabella.addColumn("Nome")
tabella.addColumn("Anni")
tabella.dataProvider = dati;
tabella.width = 300
tabella.rowHeight = 80
tabella.rowCount = 3

Il risultato sarà il seguente:

Figura 9. La proprietà rowCount è efficace anche con righe con altezze diverse da quella di default
Screenshot del filmato

Un altro possibile utilizzo della proprietà rowCount è quello di mostrare sempre tutti i dati della tabella: per questo possiamo abbinare le proprietà rowCount e length, quest'ultima infatti restituisce il numero di righe che compongono la tabella.

Con il seguente codice la tabella avrà sempre un'altezza tale da mostrare tutte le righe impostate dal DataProvider.

Listato 11. Imposta l'altezza della tabella in base ai dati

import fl.data.DataProvider;
var dati:DataProvider = new DataProvider();
dati.addItem({Anni:51,Nome:"Mario",Cognome:"Bianchi"});
dati.addItem({Anni:34,Nome:"Franco",Cognome:"Rossi"});
dati.addItem({Anni:27,Nome:"Giuseppe",Cognome:"Verdi"});
dati.addItem({Anni:21,Nome:"Davide",Cognome:"Beltrame"});
dati.addItem({Anni:45,Nome:"Valeria",Cognome:"Rossi"});
dati.addItem({Anni:71,Nome:"Virgilia",Cognome:"Corsinovi"});
tabella.addColumn("Cognome")
tabella.addColumn("Nome")
tabella.addColumn("Anni")
tabella.dataProvider = dati;
tabella.width = 300
tabella.rowCount = tabella.length

Figura 10. La proprietà rowCount usata per mostrare sempre l'intera tabella
Screenshot del filmato

Finora abbiamo preso in considerazione la possibilità di uno scrolling verticale, ma potrebbero esserci casi in cui la tabella abbia molte colonne e sia quindi necessario uno scrolling orizzontale per garantire una buona consultazione dei dati: il componente DataGrid mette a disposizione la proprietà horizontalScrollPolicy, da utilizzare come nel codice seguente:

Listato 12. Imposta lo scrolling orizzontale

import fl.data.DataProvider;
// importiamo la classe fl.controls.scrollPolicy
import fl.controls.ScrollPolicy;
var dati:DataProvider = new DataProvider();
dati.addItem({Anni:51,Nome:"Mario",Cognome:"Bianchi"});
dati.addItem({Anni:34,Nome:"Franco",Cognome:"Rossi"});
dati.addItem({Anni:27,Nome:"Giuseppe",Cognome:"Verdi"});
dati.addItem({Anni:21,Nome:"Davide",Cognome:"Beltrame"});
dati.addItem({Anni:45,Nome:"Valeria",Cognome:"Rossi"});
dati.addItem({Anni:71,Nome:"Virgilia",Cognome:"Corsinovi"});
tabella.addColumn("Cognome")
tabella.addColumn("Nome")
tabella.addColumn("Anni")
tabella.dataProvider = dati;
// impostiamo una larghezza tale da non contenere tutte le colonne
tabella.width = 100
// attiviamo lo scrolling orizzontale
tabella.horizontalScrollPolicy = ScrollPolicy.ON
tabella.rowCount = tabella.length

Il risultato sarà:

Figura 11. Uso dello scrolling orizzontale del DataGrid
Screenshot del filmato

Impostare l'ordinabilità delle colonne

Il DataGrid, come impostazione predefinita, offre all'utente la possibilità di ordinare i dati in base ad ogni colonna raffigurata nella tabella, sia in ordine crescente che in ordine decrescente; la colonna ordinata e il relativo senso vengono evidenziati tramite una apposita freccetta in alto a destra nell'intestazione della colonna stessa.

Figura 12. La colonna "Anni" ordinata in ordine decrescente
Screenshot del filmato

È possibile impedire l'ordinamento di tutte le colonne oppure operare in maniera più selettiva e quindi lasciarne alcune ordinabili e altre no. Per agire sull'intera tabella è sufficiente la proprietà sortableColumns, che accetta come valori true (le colonne saranno ordinabili) e false (le colonne non saranno ordinabili), mentre per agire su una singola colonna è necessario usare il comando getColumnAt(numero), dove numero è un valore che parte da 0 e relativo alle colonne.

Nella nostra tabella di esempio potremmo rendere ordinabili i dati solo per la colonna "Anni", andando a disabilitare l'ordinamento per le prime due, ovvero le colonne 0 (Cognome) e 1 (Anni), in questo modo:

tabella.getColumnAt(0).sortable = false
tabella.getColumnAt(1).sortable = false

Un'altra opzione importante e impostabile per ogni colonna è il criterio di ordinamento della stessa: il problema più comune, ad esempio, è il fatto che dei valori numerici vengano ordinati come stringhe, generando di conseguenza degli errori. Prendiamo ad esempio il seguente codice:

Listato 13. Ordina la colonna degli anni in modo crescente

import fl.data.DataProvider;
var dati:DataProvider = new DataProvider();
dati.addItem({Anni:51,Nome:"Mario",Cognome:"Bianchi"});
dati.addItem({Anni:34,Nome:"Franco",Cognome:"Rossi"});
dati.addItem({Anni:27,Nome:"Giuseppe",Cognome:"Verdi"});
dati.addItem({Anni:201,Nome:"Davide",Cognome:"Beltrame"});
dati.addItem({Anni:45,Nome:"Valeria",Cognome:"Rossi"});
dati.addItem({Anni:101,Nome:"Virgilia",Cognome:"Corsinovi"});
tabella.addColumn("Cognome")
tabella.addColumn("Nome")
tabella.addColumn("Anni")
tabella.dataProvider = dati;
tabella.width = 300
tabella.rowCount = tabella.length

Ordinando la colonna degli anni in maniera crescente, ci aspetteremmo che i valori partano da 27...ma se proviamo a farlo ecco cosa succede:

Figura 13. La colonna "Anni" viene ordinata in modo errato
Screenshot del filmato

Questo avviene perchè l'ordinamento di default è di tipo testuale, di conseguenza "1" viene ordinato prima di "2" indipendentemente dalla lunghezza della stringa. Per evitare questo genere di errori va utilizzata l'opzione sortOptions, che permette di impostare secondo quale criterio ordinare ogni colonna; nel nostro caso basterà aggiungere al codice la riga

tabella.getColumnAt(2).sortOptions = Array.NUMERIC

Per far sì che gli anni seguano un ordinamento di tipo numerico e non di tipo testuale.

Rendere modificabili i dati

Secondo analogo principio, anche per quanto riguarda la possibilità di modificare i dati è possibile agire sull'intera tabella (DataGrid.editable) o su ogni singola colonna (DataGridColumn.editable), ne consegue che con il comando tabella.editable = true andremo a rendere modificabili tutti i dati; mentre, per rendere modificabile solo la colonna "Anni", utilizziamo il codice:

tabella.editable = true
tabella.getColumnAt(0).editable = false
tabella.getColumnAt(1).editable = false
tabella.getColumnAt(2).editable = true

Notiamo come sia necessario impostare la tabella come modificabile, perchè in caso contrario l'impostazione tabella.editable = false andrebbe e "sovrascrivere" l'editabilità delle singole colonne e nessuna di esse risulterebbe modificabile anche qualora l'avessimo impostata singolarmente come tale.

Ricavare la selezione di un dato

Aspetto importante del DataGrid è la possibilità di ricavare quale dato sia stato selezionato dall'utente: per ogni dato potremo accedere alle proprietà impostate come colonne (nel nostro esempio Nome, Cognome e Anni). Il procedimento è molto semplice: è sufficiente sfruttare l'evento CHANGE, associandolo ad una funzione che si occuperà di reperire i dati dell'elemento selezionato.

Listato 14. Ricava il dato selezionato dall'utente

tabella.addEventListener(Event.CHANGE ,cerca)
function cerca(evt:Event){
  trace(evt.target.selectedItem.Nome)
  trace(evt.target.selectedItem.Cognome)
  trace(evt.target.selectedItem.Anni)
}

Teniamo presente che possiamo utilizzare anche dei dati "nascosti", per esempio è possibile inserire un campo nel DataProvider ma poi non mostrarlo nel DataGrid; ad esempio con il seguente codice creiamo per ogni elemento un campo id che verrà ricavato solo al momento della selezione mentre non sarà visibile nella tabella poichè non è stata creata la colonna "id" con il comando addColumn.

Listato 15. Imposta per ogni elemento un dato id che non verrà visualizzato

import fl.data.DataProvider;
var dati:DataProvider = new DataProvider();
dati.addItem({Anni:51,Nome:"Mario",Cognome:"Bianchi",id:1});
dati.addItem({Anni:34,Nome:"Franco",Cognome:"Rossi",id:2});
dati.addItem({Anni:27,Nome:"Giuseppe",Cognome:"Verdi",id:3});
dati.addItem({Anni:201,Nome:"Davide",Cognome:"Beltrame",id:4});
dati.addItem({Anni:45,Nome:"Valeria",Cognome:"Rossi",id:5});
dati.addItem({Anni:101,Nome:"Virgilia",Cognome:"Corsinovi",id:6});
tabella.addColumn("Cognome")
tabella.addColumn("Nome")
tabella.addColumn("Anni")
tabella.dataProvider = dati;
tabella.width = 300
tabella.rowCount = tabella.length

tabella.addEventListener(Event.CHANGE ,cerca)

function cerca(evt:Event){
  trace(evt.target.selectedItem.id)
}

Conclusione

Abbiamo visto alcune delle peculiarità del componente DataGrid, in particolare la versatilità offerta a livello di fonte di dati e le numerose possibilità di ridimensionamento e scrolling sia orizzontale che verticale, inoltre è stato trattato il procedimento per applicare particolari proprietà solamente ad una colonna piuttosto che all'intera tabella.

Le nozioni viste in questo articolo a livello di Actionscript 3 sono valide sia per il componente DataGrid offerto da Flash CS3 che per quello offerto da Flex. Flex 3 offre un componente addirittura più avanzato, chiamato appunto Advanced DataGrid e di cui si è accennato nell'articolo sulle novità di Flex 3; al momento non vi sono informazioni sull'eventuale integrazione di questo componente in Flash, tuttavia già con il normale DataGrid è possibile catalogare e rappresentare i dati in maniera semplice ed efficiente e si rivela quindi più che sufficiente per la maggior parte delle situazioni che richiedano l'uso di tabelle di dati.

Ti consigliamo anche