MICHELEPISANI.IT

jQuery UI: guida all'uso delle interazioni

Ordinare liste, griglie e tabelle con il 'Drag and Drop'

Ordinare le liste grazie a jQuery UI Sortable

February 12
07:222015

jQuery UI ci mette a disposizione il metodo sortable() al fine di riordinare gli elementi di una lista, di una tabella o di una griglia utilizzando il mouse. In pratica, questo metodo, attiva un gruppo di elementi del DOM permettendone l'interscambio di posizione tramite "drag and drop", Fig. 1.

jQuery UI Sortable - esempio visivo di ordinamento elementi

Fig. 1 - jQuery UI Sortable - esempio visivo di ordinamento elementi

Lo scopo di questo articolo è quello di spiegare nei minimi termini, fornendo codice funzionante, i passaggi da effettuare per ottenere un risultato applicabile in contesti più complessi (subendo poi le opportune personalizzazioni del caso).

Per prima cosa la nostra pagina dovrà inludere le librerie jQuery e jQuery UI tra i tag script nell'head (quelle elencate di seguito assicurano il corretto funzionamento del codice, altre invece, a causa di modifiche successive apportate dai creatori di jQuery come ad esempio dalle verisoni di jQuery Ui >= 1.9.0, potrebbero non garantirne il funzionamento):

https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js
http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js

La struttura HTML dovrà presentarsi come un contenitore generale con id univoco che ospita gli elementi che subiranno l'attivazione dell'ordinamento. Nel caso specifico ho utilizzato una tabella per ordinarne le righe "tr" con contenitore "tbody" identificato da id="lista_ordinata".
L'aggiunta di un identificatore univoco per ciascun elemento (ad esempio "oggettoItem_1") agevolerà il successivo lavoro di gestione della lista ordinata.

<table>
    <tr>
        <td>colonna 1</td>
        <td>colonna 2</td>
        <td>colonna 3</td>
    </tr>
    <tbody id="lista_ordinata">
        <tr id="oggettoItem_1">
            <td class="drag" nowrap="nowrap"><b>DRAG & DROP</b></td>
            <td nowrap="nowrap">Michele</td>
            <td nowrap="nowrap">Giocatore di basket</td>
        </tr>
        <tr id="oggettoItem_2">
            <td class="drag" nowrap="nowrap"><b>DRAG & DROP</b></td>
            <td nowrap="nowrap">Marco</td>
            <td nowrap="nowrap">Giocatore di calcio</td>
        </tr>
        <tr id="oggettoItem_3">
            <td class="drag" nowrap="nowrap"><b>DRAG & DROP</b></td>
            <td nowrap="nowrap">Roberto</td>
            <td nowrap="nowrap">Giocatore di bocce</td>
        </tr>           
    </tbody>
</table>
<div id="risultato"></div>

Un minimo di CSS giusto per garantire un migliore impatto visivo (la grafica è minimale e non corisponde all'immagine esemplificativa di cui sopra):

table {border-collapse:collapse;}
tr {padding:10px;}
td {padding:5px;border:solid 1px #ddd;}
#risultato {padding:10px;color:#00AA00;}
.drag:hover {cursor:move}

Dopodichè si passa al cuore dell'attivazione. Il codice seguente è dovutamente commentato, basterebbe l'assegnazione del metodo sortable all'id del contenitore della lista, tuttavia ho inserito alcune impostazioni e funzionalità avanzate tra cui "handle" per definire la parte dell'elemento adibita al trascinamento, "helper" a cui ho assegnato una funzione per mantenere costante la larghezza della riga della tabella durante il trascinamento evitandone il ridimensionamento, e "update" per eseguire ad ogni spostamento una chiamata AJAX passando come parametro i dati in un array secondo l'ordine desiderato.
Nel codice di esempio la lista ordinata viene inviata alla pagina "pagina_destinazione.asp" che eseguirà le opportune operazioni e restituirà un risultato che verrà mostrato all'interno del contenitore con id="risultato".


// Quando la pagina è caricata definisce l'ordine attuale e gli elementi da riordinare
$(document).ready(function () {
  $("#lista_ordinata").sortable({ //definisco il contenitore di elementi da riordinare
    handle: '.drag', //definisco con la classe .drag quali sono gli elementi trascinabili

    helper: function (e, tr) { //mantiene la larghezza del tr durante il trascinamento
      var $originals = tr.children();
      var $helper = tr.clone();
      $helper.children().each(function (index) {
        $(this).width($originals.eq(index).width())
      });
      return $helper;
    },

    update: function () { //aggiorno l'ordine ed eseguo una callback
      var ordina = $('#lista_ordinata').sortable('serialize');
      $("#risultato").load("pagina_destinazione.asp?" + ordina); //oggettoItem[]

    }      
  });
});

Per intendersi, se nella lista dei 3 elementi (come nell'esempio della tabella HTML) ordinati inizialmente come oggettoItem_1, oggettoItem_2, oggettoItem_3 spostassi il terzo elemento tra i primi due, il valore della variabile "ordina" risulterà essere un array di questo tipo:

oggettoItem[]=1&oggettoItem[]=3&oggettoItem[]=2

La pagina "pagina_destinazione.asp" recuperà i dati dall'array:

<%
oggettoItem = request("oggettoItem[]")
response.Write oggettoItem
%>

In questo caso nel contenitore "risultato" apparirà:

1, 3, 2

Nell'esempio ho utilizzato l'ASP, avrei potuto utilizzare anche il PHP, tuttavia il concetto che è necessario capire è che nella pagina chiamata posso elaborare lato server, in background, i dati relativi al nuovo ordinamento ed effettuare ad esempio un update nel database prima di restituire un qualsiasi risultato che sarà visualizzato a video come callback di successo.

Potete vedere il codice in funzione, senza la chiamata AJAX dovutamente commentata, nell'esempio che ho creato su JSFiddle e che potete testare direttamente nel codice seguente all'interno del tab "Result":


Per un approfondimento sulle opzioni, metodi ed eventi utilizzabili rimando alla documentazione ufficiale del widget sortable sul sito di jQueryUI.


Tags

Autore

Michele Pisani

Michele Pisani

Ho uno spiccato orientamento al problem-solving, se è troppo facile non mi diverto :)
Credo nella volontà e nel cambiamento perchè hanno fatto della mia passione il mio pane quotidiano.
Se devo descrivermi con una sola parola direi... "Concretezza", la mia stretta di mano è una garanzia.

0 Commenti

Non ci sono commenti

Nessuno ha ancora commentato questo articolo, fallo tu per primo!

Scrivi un Commento

Scrivi un Commento

Il tuo indirizzo email non sarà pubblicato.
I campi contrassegnati da un * sono obbligatori

Articoli e Argomenti correlati

Il Canale YouTube in ITALIANO

1 VIDEO GRATIS ogni 2 settimane! ISCRIVITI!

Entra a far parte della community su Facebook

Categorie popolari

Iscriviti alla mia newsletter

La tua e-mail con me sarà al sicuro.
Non fornirò mai le tue informazioni a nessuno!

Ultimi commenti

Michele Pisani

Hai verificato se succede per tutte le pagine da un certo periodo di tempo in poi o solo su alcune?

Tecnowiz

Sono amministratore di un blog pure io... Intanto ti faccio i complimenti per questo articolo. …

Michele Pisani

Ciao Antonio, grazie per la fiducia :) In caso di più fogli è necessario inserire il codice del …

Antonio

Ciao Michele, ho acquistato il tuo libro che unitamente ai tuoi video sta diventando il mio corso …