Tutoriel: Drag and drop jQuery / AJAX
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 DEMO - Té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 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!







5 décembre 2011
ce drag and drop est exactement ce qu’il me faut, sauf qu’il ne fonctionne pas avec explorer. avez-vous une astuce, ou un lien vers un autre code qui fait la même chose (modif de la base de donnée) et compatible explorer ?
merci d’avance,
petite fée
6 décembre 2011
Alors effectivement il y a un petit problème, mais seulement avec IE9 (sur les versions précédentes ça fonctionne à priori). Il semblerait que ce soit le drag-and-drop qui ne fonctionne pas, sûrement une petite erreur de ma part lors de la reprise du code de Guillaume Voisin, puisque son tuto est sensé fonctionner sous IE9.
Je travaille sur mac, du coup je regarderais tout ça dès que j’ai accès à un PC !
6 décembre 2011
Bonjour Sébastien, et merci de ta réponse.
je découvre le jquery, et il me semble évident que je dois apprendre et intégrer maintenant ce fonctionnement dans la construction de mes sites.
je tatonne donc, et je suis prise par le temps.
je suis allée voir le tuto d’origine de Guillaume voisin, mais sa démo de drag and drop ne fonctionne pas non plus avec mon explorer 9… firefox est ok par contre.
le problème ne vient donc pas de toi.
peut-être as-tu une idée, ou quelqu’un en visite sur ce forum, pour régler ce problème ?
soit par une correction du code (je ne maitrise pas encore assez cette technique pour le faire) ou en m’indiquant une autre source drag and drop compatible explorer 9 ?
d’avance merci,
Petite fée
6 décembre 2011
Re-bonjour
Problème corrigé, il suffisait de mettre à jour les librairies jQuery et le tour est joué!
Ce tuto drag and drop fonctionne donc pour, Ã priori, tous les navigateurs (Firefox, Chrome, Safari, Opera, IE9, IE8, IE7)
6 décembre 2011
Merci beaucoup,
pour ta rapidité d’intervention et aussi ton travail.
pas facile de trouver des tutos et des sources qui fonctionnent simplement, et surtout, EN FRANCAIS !!
chapeau m’sieur
)
15 décembre 2011
excellent! mais il me semble que l’exemple live n’est pas tout à fait iso avec le code dans la page ou dans l’archive.
perso, en partant de l’archive, la sauvegarde du nouvel ordre en base est OK, mais suite à un refresh de la page, l’ordre n’est pas rétabli
15 décembre 2011
Je viens de mettre l’archive à jour, maintenant ça doit fonctionner.
15 décembre 2011
Bonjour deadfish,
tu as bien vérifié que dans la base l’odre est bien le bon ?
parce que :
soit l’ordre est bon sur ta vérif sur la page mais pas dans la base ce qui pourrait venir d’un problème de ta requête (update…)
soit la base est bien mise à jour quand tu regardes dedans, et c’est le refresh qui n’est pas bon, peut-être parce que ton navigateur te réaffiche ta page d’après une archive conservée en cache.
vérifies les données dans ta base après avoir fait ton glissé-déposé, mais AVANT de rafraichir la page.
encore une idée : ta requête d’affichage se fait avant ou après la requête update ?
il est possible qu’en raffraichissant ta page celle-ci conserve les anciens emplacement (et donc le précédent array), et que ta requête d’update se re-lance et remodifie la base (c’est pourquoi je te propose de vérifier les données de ta base avant de rafraichir la page)
@ +
Elizabeth
23 décembre 2011
Bonjour,
j’essaye de faire fonctionner votre script sans trop de succès malheureusement. J’ai aucun action d’enregistrement qui ce fait dans MYSQL.
if( $_POST['action'] == « updateListeOrder ») devrait être if( $_GET['action'] == « updateListeOrder »)
Merci de votre aide
Christophe
2 janvier 2012
bonjour,
même problème pour moi,
le message « positions mise à jour » n’apparait pas comme il le fait dans la démo,
et la base de donnée n’est pas modifiée…
christophe, as-tu trouvé la solution ?
6 janvier 2012
Alors il y a trois points où il faut faire attention en reprenant le code source du tuto:
1) dans le fichier index, bien remplacer « nom » dans $res['nom'] par le nom de votre élément dans la table
2) dans jquery.shoppingList.js, vérifier que l’url passé en paramètre de la fonction $.post est correct, c’est ce qui permet la mise à jour.
3) vérifier que les paramètres d’accès à la DB sont corrects dans le fichier db.php
Si ça ne fonctionne toujours pas, vous pouvez encore essayer de mettre à jour vos fichiers jquery.min.s et jquery-ui.custom.min.js, mais à priori c’est sensé fonctionner avec ceux de l’archive…
8 janvier 2012
Dans jquery.shoppingList.js, enlever le premier « / » Ã la ligne 47 (Modification de l’URL)
Remplacer /inc/updateListe.php
Par inc/updateListe.php
La mise à jour devrais se faire.
2 février 2012
Merci pour le tuto,
le jquery fonctionne bien, mais pas la mise à jour, lorsque je drag un élément, j’ai le message « no datables selected », pourtant, j’ai bien sélectionné ma base de données et vérifié les chemins…
Une idée ?
2 février 2012
Bonjour Sophie,
j’ai eu le même problème,
ajoute simplement un appel à ta base juste avant ta requête :
mysql_select_db($database_client, $client);
…et ensuite ta requete …$query = « SELECT * FROM etc.
2 février 2012
Merci petite fée,
en fait le pb ne vient pas du sélect (je suis bien connectée à la base, ma page écho bien le contenu dans la page index), le problème vient de la mise à jour, donc de l’update (la connexion ne semble pas se faire…)
2 février 2012
j’ai trouvé, j’ai ajouté mysql_select_db avant l’update … il n’y était effectivement pas et bien que familière de ce genre de requête, je l’ai happé!
Merci !
2 février 2012
c’est une erreur que je fais tout le temps…
)
et je suis familière aussi !
du coup c’est ce que je regarde en premier quand ça ne fonctionne pas