11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Cela fait quelques jours que je souhaite approfondir le simple tri d'une liste avec JQuery. J'ai donc travaillé sur plusieurs points :

1. Trier des bloc (div) et non des listes
2. Organiser le tri sur deux colonnes
3. Sauvegarder les positions dans une base de données

J'ai fais beaucoup de recherches sur le sujet et j'ai trouvé beaucoup de réponses, mais je bloque encore sur un point et je n'ai trouvé aucun tutorial ou sujet sur un forum qui correspond à ce que je cherche.

Si j'arrive à enregistrer les positions au sein d'une liste (sur un colonne), je n'arrive pas à le faire sur deux colonnes (ça doit pas être compliqué pourtant).

J'espère qu'avec les bouts de code qui suivent vous allez comprendre ce que je veux dire et surtout pouvoir m'aider.

Voici la table qui permet de trier les DIVs

--
-- Contenu de la table `bloc`
--

INSERT INTO `bloc` (`id`, `nom`, `afficher`, `ordre`, `colonne`) VALUES
(1, 'Catégories', 1, 1, 2),
(2, 'Liens divers', 1, 2, 1),
(3, 'nouvelle', 1, 3, 1),
(4, 'Produits', 1, 0, 1);


Je ne met pas le code qui permet de générer les DIV mais juste le code html qui en ressort :

<div id="info">1-</div>
<div id="info2">2-</div>

<div class="colonne" id="colonne_g">
  	<div id="bloc_4"></div>
	<div id="bloc_2"></div>
	<div id="bloc_3"></div>
</div>
<div class="colonne" id="colonne_d">
  	<div id="bloc_1"></div>
</div>


Le code javascript en jquery qui permet de trier et qui devrait je pense faire appel à une page en ajax pour l'enregistrement:

$("#colonne_g").sortable({
                        connectWith: '#colonne_d',
                        update : function () {
                                var order = $('#colonne_g').sortable('serialize');
                                $("#info").load("ajax.php?"+order);
                                }
                });
				
$("#colonne_d").sortable({
                        connectWith: '#colonne_g',
                        update : function () {
                                var order = $('#colonne_d').sortable('serialize');
                                $("#info2").load("ajax.php?"+order);
                                }
                });


Voila ce que j'ai trouvé, et ça marche, et j'ai mis ça dans le page ajax.php pour vérifier que ça marche (et ça marche):


echo 'ok';




J'ai vraiment cherché, et je n'ai pas trouvé de réponse satisfaisante, je pense que pour quelqu'un qui s'y connait c'est vraiment facile.

Merci beaucoup
Modifié par Ardnas (06 Feb 2012 - 19:48)
Je me permet un petit up ... presque 100 vues et pas de réponse, j'ai peut être mal expliqué ?
Apparemment quand le contenu d'une colonne est modifié, le script lance une requête HTTP asyncrhone (Ajax pour les intimes) en GET sur ajax.php?BIDULE où BIDULE est une chaine de caractères qui correspond à $('#colonne_g').sortable('serialize'); ou $('#colonne_d').sortable('serialize'); (suivant le cas de figure).

Donc, dans les trucs à vérifier:
1. Est-ce que les requêtes HTTP se font bien? (Tester la Web Console de Firefox, l'onglet réseau de Firebug, celui de Web Inspector, ou autre outil qui va bien.)
2. Lorsqu'on change le contenu en déplaçant un contenu d'une colonne à l'autre, est-ce que ça déclenche une ou deux requêtes?
3. Est-ce que le script PHP a besoin de recevoir les infos pour tous les enregistrements, ou est-ce qu'il se débrouille avec des infos de mise à jour pour une seule colonne à la fois?
4. Quel est le format retourné par $(element).sortable('serialize');? Si ça s'avère pertinent (selon les résultats des tests 1-3 ci-dessus), est-ce que tu peux appeler la méthode sortable('serialize') sur une liste d'éléments plutôt que sur un seul élément? Si non, est-ce que ça retourne une chaine de caractères qui peut être concaténée facilement à une chaine du même format?
Bonsoir et merci de ta réponse.

Je vais essayer de répondre point par point et j'espère avoir tout compris, je n'ai certainement pas ton niveau mais ça va le faire !

Ok pour le principe, quand le contenu d'une colonne est modifié, le script se lance bien, sur une colonne, l'autre ou même les deux un après l'autre si je met un élément de gauche vers la droite (ou inversement).

1. Voila le contenu de la console lors que je bouge la colonne de gauche :

GET http://localhost/design/ajax.php?bloc[]=3&bloc[]=4 200 OK 10ms

Celle de droite :

GET http://localhost/design/ajax.php?bloc[]=1&bloc[]=2 200 OK 3ms

Et de gauche à droite par exemple :

GET http://localhost/design/ajax.php?bloc[]=3 200 OK 3ms
GET http://localhost/design/ajax.php?bloc[]=1&bloc[]=4&bloc[]=2 200 OK 14ms

Je pense que tout se passe donc bien, en effet c'est ça que je veux ! à la limite je pourrais changer et mettre bloc_g[] et bloc_d[] ça je pense être capable de le faire pour différencier les deux.


2. Comme je l'ai montré plus haut, ça enclenche une requête si on travaille sur une colonne, et deux si on déplace un div entre deux colonnes (je pense que c'est bon)

3. Sur ce point tu sauras sans doute mieux que moi. Tout ce que souhaite c'est que grâce aux infos j'arrive à faire une UPDATE sur ma base de données en modifier l'ordre de DIV mais aussi leur position (gauche ou droite).

4. J'ai un peu du mal à te comprendre (je manque de connaissances), mais le format retourné doit être une chaîne du genre bloc[]=1 etc...
Je n'utilise pas de liste, mon html est du genre :

<div id="colonne_g">
<div id="bloc_1"></div>
etc..
etc..
</div>
Et pareil pour la colonne de droite

J'espère vraiment avoir répondu à toutes tes questions et je reste à ta disposition, encore merci de m'aider car je sèche sur le coup ...
Si tu sais quel format ton script PHP attend, tu dois pouvoir t'en sortir.
Le problème que je vois c'est qu'avec une requête ayant pour query string ?bloc[]=1&bloc[]=4&bloc[]=2 on se retrouve avec 3 fois le même nom de variable (bloc[]) et trois valeurs différentes. Il me semble que le script ne lira que la dernière valeur. Ou bien s'il reçoit les trois (je ne sais plus comment ça se comporte exactement en GET avec PHP), je ne suis pas sûr qu'il sache s'en dépatouiller pour autant.

S'il s'agit juste d'enregistrer dans quelle colonne se trouve un bloc, il suffit d'envoyer l'identifiant du bloc et l'identifiant de la colonne (ça fait déjà une info de plus que dans les exemples que tu montres, si je comprends bien).
S'il s'agit d'enregistrer la position et l'ordre de tous les blocs dans les colonnes, il faudra envoyer pour les deux colonnes l'identifiant du bloc, celui de la colonne et celui de la position. Par exemple:
?bloc_1=1,2&bloc_2=2,0&bloc_3=1,0&bloc_4=1,1

Enfin bref il y a pas mal de manières de faire, mais ça va demander des bases solides en PHP et au moins de bonnes notions de JavaScript.
fvsch a écrit :
Si tu sais quel format ton script PHP attend, tu dois pouvoir t'en sortir.
Le problème que je vois c'est qu'avec une requête ayant pour query string ?bloc[]=1&bloc[]=4&bloc[]=2 on se retrouve avec 3 fois le même nom de variable (bloc[]) et trois valeurs différentes. Il me semble que le script ne lira que la dernière valeur. Ou bien s'il reçoit les trois (je ne sais plus comment ça se comporte exactement en GET avec PHP), je ne suis pas sûr qu'il sache s'en dépatouiller pour autant.

bloc[] est un tableau indexer par valeur incrémenter (vu qu'aucune valeur de clef n'est précisé).
Php fera quelque chose comme $_GET['bloc'] = array(1,4,2);

Après comme dit fvsch, il faudra rajouter des infos supplémentaires pour connaitre le type de requête effectué :
modification de colonne ou/et d'ordre.
Oui les infos suffisent pour une colonne normalement, en fait comme dis jo_link_noir, l'ordre est celui juste celui du tableau.

J'ai des liens de tuto qui expliquent l'enregistrement des données pour UNE colonne, mais je sais pas si je peux les donner ici, par contre le gros soucis c'est de gérer les deux colonnes en même temps !

En gros ce qu'il me faut c'est, en envoyant ce genre de données :

GET http://localhost/design/ajax.php?bloc[]=3 200 OK 3ms
GET http://localhost/design/ajax.php?bloc[]=1&bloc[]=4&bloc[]=2 200 OK 14ms

Comment découper ça (ça doit pas être dur si c'est sous la forme d'un tableau) pour faire l'update de ma table ?

A la limite si ça peut aider on pourrait faire je pense :
GET http://localhost/design/ajax.php?bloc[]=3 200 OK 3ms
GET http://localhost/design/ajax.php?bloc2[]=1&bloc2[]=4&bloc2[]=2 200 OK 14ms

donc je dois récupérer "bloc" ou "bloc2' pour reconnaitre la colonne, le chiffre indiqué qui est en fait l'ID du bloc, et enfin la position dans le tableau qui est la position du DIV dans la colonne.

Est ce possible ?
Peut-être plus simplement:
GET //localhost/design/ajax.php?col=1&bloc[]=3
GET //localhost/design/ajax.php?col=2&bloc2[]=1&bloc2[]=4&bloc2[]=2

Tu peux même l'écrire en dur dans ton code JavaScript, vu l'extrait que tu as donné.
Côté PHP il faut bien sûr modifier le script pour qu'il prenne en compte $_GET['col'].
Exactement ce que j'ai fait Smiley smile

$("#info").load("ajax.php?col=1&"+order);


et

$("#info").load("ajax.php?col=2&"+order);


Du coup je retrouve bien dans mon fichier ajax.php toutes les données nécessaires, il me reste plus qu'à les traiter pour les entrer dans la base de données, je pense y arriver tout seul, je posterai le résultat si j'y arrive mais en attendant si vous avez idée je suis preneur !
Bon bah merci pour les réponses j'ai trouvé comme un grand, grâce à vos pistes tout de mêmes, donc à la suite de ce qui avait été dit je met juste un truc du genre dans le fichier ajax.php :


$col = $_GET['col'];

foreach ($_GET['bloc'] as $position => $id) {

    $req = "	UPDATE bloc
				SET ordre=$position,
				colonne=$col
				WHERE id=$id
			";
    $rep = mysql_query($req);
	
}


C'est moche mais ça marche ensuite je ferais ça plus proprement, il me reste plus qu'à trouver une solution pour le "bug" qui empêche de poser un div si le colonne est vide, mais ça c'est connu je trouverai sur google Smiley smile

merci
Je suis une bille en PHP mais il me semble que ton script est une faille béante de sécurité qui se prête à de l'injection SQL vite fait bien fait. Tu voudras peut-être faire quelques recherches sur le sujet.

Moi je vérifierais si les valeurs récupérées pour $col et $_GET['bloc'] sont bien des chaines représentant des nombres entiers (avec éventuellement un plafond).
fvsch a écrit :
Moi je vérifierais si les valeurs récupérées pour $col et $_GET['bloc'] sont bien des chaines représentant des nombres entiers (avec éventuellement un plafond).


Oui tu peux faire une vérification sur le format (meilleur solution) ou faire un cast de la valeur sur le type integer pour éviter les injection (un peu plus à l'arrache mais suffisant dans la plupart des cas simples).

$col = intval($_GET['col']);

Sinon il a aussi les filtres de validations et de nettoyage de PHP 5 qui fonctionnent bien pour ce genre de choses.

http://php.net/manual/fr/book.filter.php
Modifié par jb_gfx (08 Feb 2012 - 22:42)
Bonjour,

je me permet de remonter ce post car même si la question n'est pas la même elle porte sur le même script donc ça sera plus simple pour répondre.

J'ai un petit soucis de compatibilité avec IE (il me semble) et je n'ai pas le bon comportement entre FF et IE (comme de par hasard ...)

Je suis parti du principe que c'était encore IE qui avait un soucis (et ça m'arrange vu que ça marche parfaitement avec FF)

Donc avec FF je travaille très bien sur les deux colonnes ! l'enregistrement dans la BDD se fait impec et j'ai bien mon placehover comme je l'ai demandé dans mon CSS

Avec IE lorsque je déplace un élément j'ai l’impression qu'il se duplique ... en plus de ça j'ai parfois un élément qui se déplace mais sans background ou dans la mauvaise position ! bref ça bug Smiley smile

Une idée d'où ça pourrait venir ? Mis à part que IE c'est le mallllllllll