L’apparition du drag and drop sur la toile ne date pas d’hier, et cela peut s’avérer très utile dans un back office, par exemple pour gérer l’ordre des éléments d’un menu ou d’une galerie d’images.

Mais pour que ce soit vraiment puissant, il faut bien évidemment que les modifications soient enregistrées en base de données, et en temps réel!

Guillaume Voisin a présenté un tutoriel très clair sur la façon de mettre en place un système de drag and drop dans son article Drag and Drop jQuery. C’est pourquoi, à partir de cette base, je me limiterai à la partie sauvegarde en live en base de données.

Voir la DEMOTélécharger l’archive

Base de données

Avant de se lancer dans le code, il faut avant tout avoir une table en base de données avec au minimum l’architecture suivante:

Structure de la table en base de données

Structure de la liste HTML

On va pouvoir reprendre la liste HTML du tutoriel de Guillaume Voisin à un petit détail près: il faut préciser pour chaque ligne l’identifiant en base de données de l’élément affiché.

<ul>
	<li id="Element_1">Milk</li>
	<li id="Element_2">Red wine</li>
	<li id="Element_3">Sugar</li>
	<li id="Element_4">Ice Cream</li>
</ul>

Mise en place du drag and drop

Comme dit précédemment, le tutoriel de Drag and Drop jQuery de Guillaume Voisin explique en détail comment mettre en place une liste qu’on peut facilement réordonner à l’aide du drag and drop.

On va donc partir de cet exemple en se limitant à la partie « tri drag and drop » de la liste, pour ajouter le code nécessaire à la mémorisation en base de données.

Vous devrez donc avoir dans le fichier appelé jquery.shoppingList.js le code suivant:

$(obj).sortable({
	axis: "y", // Le sortable ne s'applique que sur l'axe vertical
	containment: ".shoppingList", // Le drag ne peut sortir de l'élément qui contient la liste
	handle: ".item", // Le drag ne peut se faire que sur l'élément .item (le texte)
	distance: 10, // Le drag ne commence qu'à partir de 10px de distance de l'élément
	// Évènement appelé lorsque l'élément est relâché
	stop: function(event, ui){
		// Pour chaque item de liste
		$(obj).find("li").each(function(){
			// On actualise sa position
			index = parseInt($(this).index()+1);
			// On la met à jour dans la page
			$(this).find(".count").text(index);
		});
	}
});


C’est dans ce code que nous allons pouvoir intégrer un appel à la mise à jour de l’ordre des éléments de la liste.

Appel de la mise à jour

On va maintenant demander à notre code jQuery d’appeler une page, qu’on appellera updateListe.php, contenant un script php qui va mettre à jour la position des éléments en base de donnée.

Il suffit donc d’ajouter dans le code précédent le code suivant:

update: function()
{
	// On prépare la variable contenant les paramètres
	var order = $(this).sortable("serialize")+'&action=updateListeOrder';
	// $(this).sortable("serialize") sera le paramètre "element", un tableau contenant les différents "id"
	// action sera le paramètre qui permet éventuellement par la suite de gérer d'autres scripts de mise à jour

	// Ensuite on appelle notre page updateListe.php en lui passant en paramètre la variable order
	$.post("/updateListe.php", order, function(theResponse){});
} 

Il est possible de récupérer une réponse du script pour afficher un message à l’utilisateur. Notre script jQuery final (pour la partie concernant le tri) aura donc cette allure:

$(obj).sortable({
	axis: "y", // Le sortable ne s'applique que sur l'axe vertical
	containment: ".shoppingList", // Le drag ne peut sortir de l'élément qui contient la liste
	handle: ".item", // Le drag ne peut se faire que sur l'élément .item (le texte)
	distance: 10, // Le drag ne commence qu'à partir de 10px de distance de l'élément
	// Évènement appelé lorsque l'élément est relâché
	stop: function(event, ui){
		// Pour chaque item de liste
		$(obj).find("li").each(function(){
			// On actualise sa position
			index = parseInt($(this).index()+1);
			// On la met à jour dans la page
			$(this).find(".count").text(index);
		});
	},
	update: function()
	{
		// On prépare la variable contenant les paramètres
		var order = $(this).sortable("serialize")+'&action=updateListeOrder';
		// $(this).sortable("serialize") sera le paramètre "element", un tableau contenant les différents "id"
		// action sera le paramètre qui permet éventuellement par la suite de gérer d'autres scripts de mise à jour

		// Ensuite on appelle notre page updateListe.php en lui passant en paramètre la variable order
		$.post("/updateListe.php", order, function(theResponse)
		{
			// On affiche dans l'élément portant la classe "reponse" le résultat du script de mise à jour
			$(".reponse").html(theResponse).fadeIn("fast");
			setTimeout(function()
			{
				$(".reponse").fadeOut("slow");
			}, 2000);
		});
	}
});

Script de mise à jour de la base de données

Il ne reste maintenant plus qu’à lancer le script de mise à jour de la base de données.

On va donc créer notre fichier updateListe.php, à qui on va passer en paramètre l’action à effectuer ainsi que le tableau des identifiants de chaque élément.

Le fichier va contenir le script suivant:

// On se connecte à notre base de données
$host = "myDBServer";
$user = "myDBUser";
$db = "myDBName";
$pass = "myDBPassword";

mysql_connect($host, $user, $pass) or die(mysql_error());
mysql_select_db($db) or die(mysql_error());

// On analyse la variable POST action (qui permet éventuellement de gérer plusieurs scripts de mise à jour)
if( $_POST['action'] == "updateListeOrder")
{
	// On récupère le tableau des ID de chaque élément
	$elements = $_POST['element']

	// On indique le premier indice de position souhaité
	$position = 1;

	// Et on met à jour la base de données
	foreach($elements as $id)
	{
		$sql = 'UPDATE rubriques SET position = '.$position.' WHERE id='.$id;
		mysql_query($sql) or die(mysql_error());
		$position++;
	}
}

Conclusion

Vous avez maintenant tout ce qu’il faut pour que votre drag and drop mémorise en temps réel la position de vos éléments en base de données.

A partir de là, vous pouvez faire évoluer ce script pour que toutes les actions du tutoriel de Guillaume Voisin soient aussi mémorisées dans la table de vos éléments!