Bonsoir,
Comme vous pouvez voir sue ce lien :

http://team-rushkiller.fr/partage/2014/

Le tout fonctionne mais une fois le lien déposé a une autre place il perd son style et les liens ne sont plus cliquable, je suis un peut embêter
voici le code jquery j'ai oublié un truc mai je ne vois pas quoi.

Si vous arrivez a dépatouillez le code je vous paye une glace lol.

Voila merci a vous !

<script type="text/javascript">
// ajoute la propriété pour le drop et le transfert de données
$.event.props.push('dataTransfer');
$(document).ready(function() {
    var i, $this, $log = $('#picto');
    $('#nav-left li').on({
        // on commence le drag
        dragstart: function(e) {
            $this = $(this);
            i = $(this).index();
            $(this).css('opacity', '0.5');
            // on garde le texte en mémoire
            e.dataTransfer.setData('text/html', $(this).text());
        },
        // on passe sur un élément draggable
        dragenter: function(e) {
            // on augmente la taille pour montrer le draggable
            $(this).animate({
                width: '122px'
            }, 'fast');
            e.preventDefault();
        },
        // on quitte un élément draggable
        dragleave: function() {
            // on remet la taille par défaut
            $(this).animate({
                width: '122px'
            }, 'fast');
        },
        // déclenché tant qu on a pas lâché l élément
        dragover: function(e) {
            e.preventDefault();
        },
        // on lâche l élément
        drop: function(e) {
            // si l élément sur lequel on drop n'est pas l'élément de départ
            if (i !== $(this).index()) {
                // on récupère le texte initial
                var data = e.dataTransfer.getData('text/html');
                // on log
                $log.html(data + ' > ' + $(this).text()).fadeIn('slow').delay(1000).fadeOut();
                // on met le nouveau texte à la place de l ancien et inversement
                $this.text($(this).text());
                $(this).text(data);
            }
            // on remet la taille par défaut
            $(this).animate({
                width: '122px'
            }, 'fast');
        },
        // le drop est terminé, fin du drag
        dragend: function() {
            $(this).css('opacity', '5');
        },
        // au clic sur un élément
        //click: function() {
        // alert($(this).text());
        //}
    });
});
</script>

15 réponses


Lotfi Berrahal
Réponse acceptée

As tu essayé le .html() ? au lieu du .text()

Bonsoir,

Visiblement tu ne gardes pas tout ton text à l'intérieur de ton li en mémoire.
Il met bien le mot mais pas la balise <a> donc regarde de ce côté là.
Tu devrais pouvoir récupérer tout le html en faisant quelque chose comme :

e.dataTransfer.setData('text/html', $(this).html());

ton style s'applique sur

#nav-left ul li a

Or après le déplacement tu perds ta balise <a>, et tout ce qu'il contient (y compris le span de l'icone, donc).
Résous ce problème et tu verras que tes styles reviennent (fait l'expérience avec l'inspecteur d'ajouter un élément <a> autour du texte qui est dans le li que tu a déplacé: le style ré-apparait)

Arf, Lotfi a été plus rapide :(

lol j'ai pas forcément donné la bonne solution :p tu peux toujours gagner la glace ! :)

neecride
Auteur

Merci de vos réponse !

@Vallyan

C'est bien le <a> est le <span> que je perd au repositionnement

Voici mes liste :

<ul>
    <li draggable="true"><a href=""><span class="icon-home-1"></span> Home</a></li>
    <li draggable="true"><a href=""><span class="icon-chat-1"></span> Forum</a></li>
    <li draggable="true"><a href=""><span class="icon-equalizer"></span> Actualite</a></li>
    <li draggable="true"><a href=""><span class="icon-download"></span> medias</a></li>
    <li draggable="true"><a href=""><span class="icon-wrench-3"></span> Tutos</a></li>
    <li draggable="true"><a href=""><span class="icon-star"></span> Teams</a></li>
    <li draggable="true"><a href=""><span class="icon-gamepad"></span> Jeux</a></li>
    <li draggable="true"><a href=""><span class="icon-squares"></span> Articles</a></li>
</ul>

J'ai testé de ne déclaré que le li dans le css "nav-left li" comme sur cette autre lien ça marche bien mai je perd quand même le <a> et le <span> hors le <li> le <a> est le <span> doivent suivre le drag&drop faut ajouté autre chose au script mai je mi perd dans toutes les fonction qu'il y a sur jquery.

Comme le disait lotfi, je pense que c'est parce que tu utilises $selecteur.text() au lieu de $selecteur.html() (regarde lignes 16, 49 et 50, par exemple, de ton code en haut de la page).
.text() va virer toutes tes balises (donc le <a> et le <span>, alors que html() va les garder, et le remettra correctement au moment ou tu echange les contenus.

Change ca a tous les endroits ou tu l'utilises avant de changer ton css ou autre ...

Cette fois c'est toi Vallyan le plus rapide lol mais ça me rassure j'ai cru mon post était invisible O_o

^^ Je suis toujours en lice pour la glace !

@neecride: Dans l'ensemble je trouve que tu te compliques pas mal la vie avec tes e.dataTransfer.setData().
Le code suivant marche parfaitement si je le tape en console sur ton site:

var startIndex, currentIndex, startHtml, currentHtml;
$('#nav-left li').on({
    dragstart: function(e) {
        startIndex = $(this).index();
        startHtml = $(this).html();
    },
    dragenter: function(e) {
        currentIndex = $(this).index();
        currentHtml = $(this).html();
    },
    drop: function(e) {
        $( '#nav-left li:eq(' + startIndex + ')' ).html( currentHtml );
        $( '#nav-left li:eq(' + currentIndex + ')' ).html( startHtml);
    },
});

Il ne te reste a ajouter tes fioritures de transparence :P ...

Tant que j'y suis:

  • Je comprends pas bien pourquoi tu mets des e.preventDefault() dans des fonctions vides (pourquoi mettre ses fonctions si c'est juste pour faire un preventDefault() ??)
  • Tu as une 'opacity: 5' ligne 60 de ton code en haut de cette page, ce qui n'est pas possible
  • Et enfin je trouve que l' échange entre les deux li est, en réalité, pas intuitive du tout. En général pour des actions de drag n' drop l'élément draggé est inséré , de telle facon que le li en seconde position est maintenant en première position, celui qui etait en troisieme est maintenant en seconde, etc. (autrement dit les li au-dessus du site d'insertion sont décalés vers le haut).

Enfin bref ... bonne chance pour la suite ^^

neecride
Auteur

@Lofti : j'ai bien fait ce que tu ma indiquer est cela fonctionne hier j'avais oublié une ligne ça pouvez pas marcher.

@ Vallyan : ton code ne fonctionne pas chez moi quoi qu'il en soi j'ai déjà mis le site teste en ligne reste plus qu'a enregistré le tout quand un user fait un déplacement, Vous me conseilliez quoi comme méthode.

En tous cas merci a vous !

cookie ... ou bdd

GG lotfi, la glace est a toi :(

LOL non pas à moi disons que la solution que tu lui donnes pas la suite est plus propre cela dit il fait bien trop froid pour une glace aussi je te la donne volontiers ! :)

neecride
Auteur

@Vallyan : on peut faire ça avec une base de donnée ? les cookie on ne m'en dit que du mal.

Ben le cookies sont plus ou moins pratiques ... dans ton cas c'est ce que j'utiliserai.

Pour la bdd, il te faut faire un ajax a chaque drop pour envoyer la configuration actuelle du menu au serveur afin qu'il la sauvegarde, mais cela suppose que tu peux identifier te sutlisateurs de facon non-equivoque (couple login / mdp, donc, ce qui n'a pas l'air d'etre le cas de ton site). Alternativement tu peux utiliser leur IP, mais c'est moins propre et si plusieurs utilisateurs partagent la meme IP ils vont se foirer leurs config les uns les autres. C'est pour ca que j'utiliserai un cookie, a updater a chaque drop.

Et donc en plus de cela, au chargement de la page tu dois faire une requête pour récupérer la configuration de l'utilisateur depuis la bdd ou le cookie.

Quant a ce que tu dois envoyer en ajax (ou sauvegarder dans un cookie), tu peux y aller comme un bourrin et envoyer tout l'html du <ul>. Le problème c'est que si tu décides de changer ton html pour une raison X, les mecs qui ont sauvegardé leur config avant que tu changes le html (les classes, par exemple, ou les liens, ou autre ...) vont avoir un problème. Alternativement (c'est mieux), tu peux juste sauvegarder l'ordre des onglets dans un objet JS et envoyer le JSON au server. Coté PHP au chargement de la page, il faudra récupérer le JSON et l'intégrer proprement a ta vue, ce qui fait que si tu décide de changer ton html ce sera toujours possible.

neecride
Auteur

Waoww sa va être chaud a mettre en place si le cookie est plus pratique je vais me pencher la dessus.

Merci !