Home Page Home Page Articoli Riordinare le righe di una GridView con AJAX

Riordinare le righe di una GridView con AJAX

La GridView, un controllo molto potente e flessibile che però non può offrire tutto. Vediamo in questo articolo come estenderlo implementando meccanismi di reordering delle righe usando AJAX
Autore: Riccardo D'Aria Livello:

Introduzione


Spesso si sente la necessità di definire l'ordine sequenziale con cui, immagini, files, news o altro devono essere presentati all'utente di un sito web. Se si tratta di dati statici, e cioè dati inseriti manualmente nel markup HTML di una pagina web, il problema non sorge, in quanto in fase di creazione della pagina, si definisce l'ordine con cui i nostri dati devono comparire.

Il problema sorge nel caso di dati che sono stivati in un database, e che all'occorrenza vengono presentati nella pagina web, magari in funzione delle azioni dell'utente navigatore. In questo caso le possibilità di ordinare la presentazione dei dati sono quelle offerte dalla modalità di ordinamento dei dati derivante dalla clausola ORDER BY che utilizziamo nella query di selezione nel momento in cui andiamo a prelevare i dati dal nostro database. Qui troviamo uno schema chiuso che ci è dato da ordinamenti crescenti e decrescenti su ogni campo della tabella che contiene i nostri dati, ma nulla che possa permetterci di definire a nostro piacere un tipo di ordinamento che prescinda delle suddette preesistenti modalità di ordinamento crescente e decrescente.
La finalità è dunque quella di dare ai dati presenti in una tabella di un database un determinato tipo di ordinamento, e far si che gli stessi vengano presentati nella pagina web secondo l'ordine definito.
Questo strumento nasce dunque come supporto da utilizzare nei CMS di siti web, da mettere al servizio dell'amministratore del sito.

Tecnologie impiegate


Il sistema è stato progettato e realizzato su piattaforma ASP.NET 3.5 e con l'ausilio di un Update Panel. Quest'ultimo componente gioca un ruolo molto importante in quanto grazie ad esso, (alla chiamata asincrona che effettua) il modulo acquisisce una elevata velocità di esecuzione senza la quale il modulo avrebbe delle difficoltà di utilizzo stante il continuo call-back server-client ad ogni azione di spostamento di una riga in basso o in alto, stante la necessità di salvare, ad ogni spostamento di riga, il nuovo ordine dato alle righe (record).

Il progetto


Presupposto di base all'utilizzo del modulo è l'esistenza di un database al servizio del sito web.
Il modulo progettato e realizzato poggia su di un database MySql esistente su di un server web. Ma questo non è limitativo in quanto il sistema prescinde dal tipo di database utilizzato e può, con i dovuti aggiustamenti, essere utilizzato anche su altri DB.
Per poter implementare il modulo, è necessario l'ausilio AJAX che per gli utenti che utilizzano la versione 2.0 del Framework .NET, va installato a parte; per l'installazione di AJAX il seguente link offrirà ogni dettaglio tecnico necessario:
Microsoft ASP.NET AJAX 

Per chi invece utilizza la versione 3.5 e successive del Framework .NET, non c'è alcun bisogno di ulteriori installazioni dal momento che ASP.NET AJAX è già contenuto in queste versioni del Framework.NET.

La griglia dati completa


Di seguito si mostra, al fine di dare al lettore una prima idea di ciò che si sta andando a realizzare, uno screenshot del modulo completo. Così come è stato realizzato e posto on-line.



Sono evidenziati i pulsantini che permettono di spostare il singolo record/riga in basso o in alto e la colonna che indica il numero progressivo di ordinamento.
Inutile dire che il layout della griglia e dei pulsantini può essere gestito a piacimento secondo le proprie esigenze grafiche.

I controlli e gli oggetti necessari


Dopo essersi accertati che si dispone degli strumenti necessari si può procedere a costruire la pagina inserendo in essa i controlli

Per avviare la creazione della pagina destinata a contenere il modulo di riordinamento si eseguano i seguenti passi:

a) creare una pagina ASP.NET destinata a contenere la griglia dati che permetterà l'ordinamento.

Nella pagina ASP.NET si aggiungano i seguenti controlli:

1) un controllo ScriptManager;
2) un controllo UpdatePanel;
3) un controllo GridView;

All'interno della griglia:

4) i pulsanti per eseguire lo spostamento della riga in basso o in alto che saranno dei “buttonFiled” della gridView;
5) una colonna destinata a contenere il progressivo di ordinamento.

Di seguito una serie di immagini a supporto per questa Operazione.

b) Selezionare il controllo ScriptManager e trascinarlo sulla Pagina avendo cura di inserirlo nel tag <form> della pagina.



c) Selezionare il controllo UpdatePanel e trascinarlo nella pagina, posizionandolo al di sotto del Controllo Script Manager.



d) Selezionare il controllo GridView e collocarlo all'interno dell'UpdatePanel;



e) Aggiungere Pulsanti all'interno della griglia. Questi dovranno essere dei ButtonField. Il markup dei pulsanti, una volta collocati nella griglia, sarà pressappoco il seguente:

Codice XML n°1
<asp:ButtonField ButtonType="Button" CommandName="SU" Text="SU" >
<ControlStyle Font-Size="7pt"></ControlStyle>
<ItemStyle Width="10px" />
</asp:ButtonField>

<asp:ButtonField ButtonType="Button" CommandName="GIU" Text="GIU" >
<ControlStyle Font-Size="7pt"></ControlStyle>
<ItemStyle Width="10px" />
</asp:ButtonField>


Come si può notare, per entrambi i pulsanti è stato definito l'attributo CommandName. Questo valore viene utilizzato nell'evento RowCommand della griglia per intercettare il tipo di operazione da eseguire, e cioè se si tratta di uno spostamento verso l'alto o verso il basso, all'interno della griglia.

f) La colonna ordine della griglia.

La colonna che ospita il progressivo dell'ordinamento svolge due funzioni:

1) Indica all'utente la posizione ordinale dell'item 3° posto, 4°, 12° posto etc. in modo che l'utente possa avere sempre una visione dei progressivi di ordinamento;
2) Questo valore viene prelevato dal codice server-side, ed utilizzato per rieseguire l'ordinamento ad ogni spostamento verso il basso o verso l'alto. Senza di questo, il sistema non saprebbe quale è la posizione corrente del record da spostare. E quindi non sarebbe in grado di riordinare correttamente gli Items.

Una volta creata la pagina, e collocati in essa i controlli necessari possiamo passare alla compilazione del codice lato server che provvederà a popolare la griglia, a spostare le righe in alto o in basso e a salvare i dati ogni qualvolta una riga viene spostata. E' inoltre necessario aggiungere alla tabella del database che contiene i dati a cui intendiamo dare il “Nostro” ordinamento, un campo numerico che contenga il progressivo di ordinamento. Questo campo oltre a contenere il numero di ordinamento, verrà utilizzato dalla query di selezione di lettura dei dati, come campo su cui impostare la clausola ORDER BY in sede di renderizzazione dei dati a video.

Il Campo Ordinale


Affinché il modulo possa svolgere la sua funzione è necessario aggiungere alla tabella dei dati del Database un campo numerico destinato a contenere il numero ordinale dell'ordinamento che di volta in volta l'utente assegna ai dati.
Quindi aggiungiamo alla nostra tabella il campo di tipo intero che chiameremo "ordinale"

N.B. è necessario anche impostare nella tabella il campo id come numeratore progressivo univoco (il classico id che ogni record che si rispetti deve possedere). Anche questo dato deve essere riportato nella GridView.

Per completezza si riporta il codice html della griglia destinata ad ospitare i dati:

Codice XML n°2
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
CssClass="Gridview1" PageSize="8" Font-Size="12px">
<Columns>

<asp:BoundField DataField="id" HeaderText="ID" >
<ItemStyle Width="5px" />
</asp:BoundField>
<asp:BoundField DataField="ordinale" HeaderText="Ordine" >
<ItemStyle Width="20px" />
</asp:BoundField>

<asp:BoundField DataField="nome" HeaderText="Nome" >
<ItemStyle Width="50px" />
</asp:BoundField>

<asp:ButtonField ButtonType="Button" CommandName="SU" Text="SU" >
<ControlStyle Font-Size="7pt"></ControlStyle>
<ItemStyle Width="10px" />
</asp:ButtonField>

<asp:ButtonField ButtonType="Button" CommandName="GIU" Text="GIU" >
<ControlStyle Font-Size="7pt"></ControlStyle>
<ItemStyle Width="10px" />
</asp:ButtonField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>


Si noti che la griglia è chiusa nell'UpdatePanel

Il codice lato server


Il codice lato server riguarda soltanto, la gestione del salvataggio dei dati della tabella ad ogni operazione di spostamento che eseguiamo tramite i pulsanti di ordinamento. Il codice lato server occorre per eseguire il corretto riordinamento degli items e la renderizzazione a video dei dati riordinati.
In pratica ad ogni spostamento eseguito, Su o Giù, il sistema provvede ad eseguire il calcolo della giusta posizione del singolo Item e ricarica i dati in tabella. Quest'ultima operazione risulta quasi immediata, dal momento che l'UpdatePanel fa si che ci sia il postback dei dati della sola griglia e non di tutta la pagina, pertanto l'operazione è, compatibilmente, con la velocità della connessione ad Internet, estremamente veloce.
Occorre a questo punto, fare una precisazione circa il termine riordinamento che si sta utilizzando in questo articolo. Il riordinamento dei dati è solo un concetto figurativo, che si esprime e si manifesta solo al momento della renderizzazione a video dei dati. Fisicamente i dati non vengono riordinati, ma ad essi viene solo associato il corretto numero ordinale. Solo in fase di lettura dei dati, ordinati (ORDER BY) per il campo ordinale, che si esprime e manifesta il concetto di ordinamento dei dati, che appaiono secondo l'ordine definito.
Il codice lato server va impostato dunque nell'evento RowCommand della griglia.
Ad ogni pressione dei pulsanti SU/GIU, viene scatenato l'evento RowCommand della GridView. In esso non dobbiamo far altro che intercettare il tipo di pulsante premuto (tramite la proprietà commandName dl ButtonField) ed in base ad esso eseguire una semplice rinumerazione del campo ordinale del record/item da spostare e del record successivo o precedente ad esso a seconda del fatto che si è scelto di spostare Su o Giù.

Una volta intercettato il tipo di spostamento, è necessario prelevare:

1) il valore dell'ordinale del record da spostare;
2) l'id del record da spostare;
3) l'id del record precedente se lo spostamento è Su;
4) l'id del record successivo se lo spostamento è Giù.

Una volta prelevati questi dati, occorre solo eseguire una query di update sulla tabella in questione modificando i valori del campo ordinale del record da spostare e del suo precedente o successivo.
Dunque si è capito che l'intervento è su due soli record di dati per volta, quello che si vuole spostare ed il suo precedente o successivo secondo l'ordinamento esistente all'atto dello spostamento.

In particolare, se si tratta di uno spostamento Su:

1) si decrementa di una unità il valore dell'ordinale del record da spostare;
2) si incrementa di una unità il valore dell'ordinale del record precedente;

Se si tratta di uno spostamento Giù:

1) si incrementa di una unità il valore dell'ordinale del record da spostare;
2) si decrementa di una unità il valore dell'ordinale del record successivo;

In sostanza non si fa altro che invertire tra loro i valori degli ordinali dei due record facendo attenzione a prendere il precedente o il successivo a seconda che si vada giù o Su.
Il codice che segue mostra quanto appena detto.

Codice .NET n°3
Protected Sub GridView1_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GridView1.RowCommand
Dim idrecordCorrente As Integer = 0
Dim idrecordPrecedente As Integer = 0
Dim idrecordSuccessivo As Integer = 0
Dim ordinale As Integer = 0
Dim indexCorrente As Integer = 0
Dim indexPrecedente As Integer = 0
Dim indexSuccessivo As Integer = 0
Dim strSQL as string = “”

Dim selectedRow As GridViewRow = GridView1.Rows(Convert.ToInt32(e.CommandArgument))

indexCorrente = Convert.ToInt32(e.CommandArgument)
Select Case e.CommandName.ToString

Case "SU"
‘Verifico che non sia la prima riga della griglia, se lo è presento messaggio con alert javaScript
If indexCorrente > 0 Then
‘Prelevo il valore dell'ordinale del record spostato e gli id del record spostato ‘(recordCorrente) e ‘del recordPrecedente
ordinale = CInt(GridView1.Rows(indexCorrente).Cells(1).Text)
idrecordCorrente = CInt(GridView1.Rows(indexCorrente).Cells(0).Text)
idrecordPrecedente = CInt(GridView1.Rows(indexCorrente - 1).Cells(0).Text)

‘Assemblo la stringa sql per eseguire l'update sul record corrente
strSQL = "UPDATE tabella set ordinale=" & ordinale - 1 & " where id = " & idrecordCorrente
‘qui il codice per eseguire l'update del record . . . . . . . . .

‘Assemblo la stringa sql per eseguire l'update sul record Precedente
strSQL = "UPDATE inprimopiano set ordinale=" & ordinale & " where id = " & idrecordPrecedente
‘qui il codice per eseguire l'update del record . . . . . . . . .

‘Qui il codice, per rieseguire la lettura dei dati e ripopolare la griglia dati .. .
Else
‘Gestione del massaggio di errore con alert javaScript del caso in cui si stia tentando di ‘spostare il primo item verso l'alto
Dim x As String = "<script language='JavaScript'> alert('Primo rocord, impossibile andare SU') </script>"
ScriptManager.RegisterStartupScript(Me, Me.GetType(), "x", x, False)
End If

Case "GIU"
‘Verifico che non sia l'ultima riga della griglia, se lo è presento messaggio con alert javaScript
If indexCorrente < GridView1.Rows.Count - 1 Then

‘Prelevo il valore dell'ordinale del record spostato e gli id del record spostato ‘(recordCorrente) e ‘del recordSuccessivo
ordinale = CInt(GridView1.Rows(indexCorrente).Cells(1).Text)
idrecordCorrente = CInt(GridView1.Rows(indexCorrente).Cells(0).Text)
idrecordSuccessivo = CInt(GridView1.Rows(indexCorrente + 1).Cells(0).Text)

‘Assemblo la stringa sql per eseguire l'update sul record corrente
strSQL = "UPDATE inprimopiano set ordinale=" & ordinale + 1 & " where id = " & idrecordCorrente
‘Assemblo la stringa sql per eseguire l'update sul record corrente
strSQL = "UPDATE inprimopiano set ordinale=" & ordinale & " where id = " & idrecordSuccessivo

‘Qui il codice, per rieseguire la lettura dei dati e ripopolare la griglia dati .. .
Else
Dim x As String = "<script language='JavaScript'> alert('Ultimo rocord, impossibile andare GIU') </script>"
ScriptManager.RegisterStartupScript(Me, Me.GetType(), "x", x, False)
End If

End Select
End Sub


L'omissione del codice relativo ai comandi di update, e di lettura dei dati è stata voluta e ritenuta necessaria al fine di rendere più agevole e snella la comprensione del codice e della logica che ad esso sottende.

Conclusioni


Il modulo è stato sviluppato sulla base di una concreta esigenza sorta ad un utilizzatore di un CMS per la gestione di gallerie di immagini. A tal fine la sua esigenza era quella di poter dare alle immagini presentate sul suo sito web un ordine sequenziale basato sulle sue specifiche esigenze. Nessuno vieta di applicarlo anche in altri scenari per esempio per ordinare un elenco di pagine, oppure la priorità nel caso di un elenco di prodotti su un sito di ecommerce.

Spunti di sviluppo


a) Il sistema potrebbe essere integrato con una funzione Javascript che provveda essa stessa a spostare lato client, le righe della griglia. Così impostato non sarebbe più necessario il ripopolamento della griglia ad ogni operazione di spostamento. Ad ogni operazione di spostamento corrisponderebbe solo l'azione di update dei record interessati mediante, come già visto, l'incremento/decremento del valore del campo ordinale.

b) Abbiamo visto in questo articolo come implementare funzioni di ordinamento dentro una GridView tramite ASP.NET AJAX e VB.NET. Questo è un metodo ma ce ne sono altri che potrebbero migliorare ulteriormente l'usabilità per l'utente, ad esempio ordinare le righe tramite Drag & Drop. Un controllo già pronto che ci consente ciò è il ReoderList contenuto nell'AJAX Control Toolkit, è possibile vedere una demo funzionate a questo indirizzo (AJAX Control Toolkit ReorderList Demo ). C'è da notare che qui abbiamo di fronte una list formata da elementi <li> e non le righe di una GridView che è composta da <tr>.

c) Se non vogliamo proprio avere a che fare con il server e quindi con dei roundtrip continui e a volte anche pesanti generati dallo stack AJAX di Microsoft possiamo anche optare per soluzioni jQuery come il plugin Sortable del pacchetto jQuery UI di cui potete vedere una demo qui (jQuery UI Sortable Plugin ). Naturalmente qui dovrete voi farvi carico della serializzazione delle modifiche e quindi sarà necessario costruire Javascript aggiuntivo che faccia delle chiamate sul server via HTTP/POST o altro per apportare la modifica nel database.

Ringraziamenti


- dotNetHell.it  per la pubblicazione del presente articolo;
- David De Giacomi  per il supporto nella stesura dell'articolo;
- Multi Planet 2002 per il continuo stimolo e sostegno nella ricerca di nuove soluzioni da mettere al servizio dei fruitori di Internet;
Voto medio articolo: Numero Voti: 0
Riccardo D'Aria

Riccardo D'Aria

Mi laureo in economia e commercio nel 96, comincio a scrivere macro per excel per conto del CED dell'azienda di ricerche di mercato in cui ero ricercatore. Dalle macro passo ai primi programmini in vb 6, poi al web con pagine dinamiche ASP, per poi continuare con la piattaforma microsoft. Attualmente libero professioni... Profilo completo

Articoli collegati

Membership, Role e Profile Provider personalizzati
Chi deve gestire in modo consistente autenticazione, gestione dei ruoli e profilazione degli utenti di un sito Internet non può non conoscere i Providers (MembershipProvider, RoleProvider e ProfileProvider) offerti da ASP.NET. Vediamo che cosa sono, a cosa servono e come si costruiscono.
Autore: Marco Rossi | Difficoltà: | Commenti: 13
Da AJAX ad Atlas nuove tecnologie per un Web di nuova generazione
Nell'ultimo periodo si è parlato molto di Atlas l'ultima tecnologia Microsoft per rendere le pagine web dinamiche, interattive e molto più attraenti, in modo da essere sempre più somiglianti a vere e proprie applicazioni Windows. Cominciamo a conoscere questa tecnologia per sapere cosa potremo fare nelle applicazioni ASP.NET di prossima generazione.
Autore: Matteo Raumer | Difficoltà: | Commenti: 6
La classe Profile di ASP.NET 2.0
In un'applicazione ASP.NET è cosa comune avere la necessità di gestire alcune proprietà che caratterizzino ogni utente, sempre disponibili tra le varie pagine. L'approccio con la versione 1.1 del Framework si basava sull'uso dell'oggetto Session. Con la versione 2.0 il Framework ci mette a disposizione la classe Profile.
Autore: Matteo Raumer | Difficoltà: | Commenti: 3 | Voto:
Le WebParts in ASP.NET 2.0
Scopriamo le WebParts, i nuovi Web Controls di ASP.NET 2.0 che consentono di personalizzare sia i contenuti che l'interfaccia grafica delle nostre applicazioni Web, tecnologia giù utilizzata ampiamente nel prodotto Sharepoint Portal Server 2003.
Autore: Marco Caruso | Difficoltà: | Commenti: 6 | Voto:
Scopriamo l'oggetto Gridview di ASP.NET 2.0
Nonostante la Datagrid di ASP.NET 1.x offrisse già molta flessibilità, con il Framework 2.0 è stato introdotto un nuovo oggetto, la Gridview, erede della DataGrid che, migliorata e potenziata, faciliterà di molto la vita agli sviluppatori Web.
Autore: Giovanni Ferron | Difficoltà: | Commenti: 1 | Voto:
Configurazioni Web con ASP.NET 2.0
Vediamo come cambia e come viene semplificata la configurazione in ASP.NET 2.0 attraverso i nuovi controlli di login, il tool d'amministrazione e l'amministrazione attraverso Internet Information Server (IIS)
Autore: Marco Caruso | Difficoltà: | Commenti: 4
Più facile con il .NET Framework 2.0 :-)
Da quando ho cominciato a "smanettare" per arrivare poi a "lavorare" con il framework 1.x, mi sono trovato subito a mio agio con gli elementi che il .NET metteva a disposizione, ma per alcune cose già sapevo che avrei dovuto lavorare. Con la versione 2.0 del Framework alcune di queste sono state già inserite semplificandomi ulteriormente la vita...
Autore: Matteo Raumer | Difficoltà: | Commenti: 1
ASP.NET Themes e Skins con Visual Studio .NET 2005
Una delle novità introdotte in Whidbey è la possibilità di applicare dei Temi (Themes) alle nostre applicazioni o pagine Web e addirittura applicare delle Skins singolarmente ai controlli delle Web Forms in modo estremamente flessibile e rapido.
Autore: David De Giacomi | Difficoltà: | Commenti: 3 | Voto:
Anteprima su Visual Studio .NET 2005
Visual Studio .NET Whidbey, ossia la prossima versione di Visual Studio .NET basato sul Framework 2.0 è ancora in cantiere ma grazie all'Alpha rilasciata agli sviluppatori in occasione della PDC 2003 possiamo vedere quali novità ci aspettano. Eccone alcune!
Autore: David De Giacomi | Difficoltà: | Commenti: 2
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5