web-dev-qa-db-fra.com

jQuery draggable + droppable: comment accrocher un élément déposé à un élément déposé

J'ai mon écran divisé en deux DIVs. DIV gauche J'ai quelques DIVs de 50x50 pixels, à droite DIV J'ai une grille vide composée de 80x80 LIs. Les DIVs sur la gauche sont déplaçables et, une fois déposés sur un LI, ils doivent être alignés au centre de cette LI.

Cela semble simple, non? Je ne sais tout simplement pas comment y arriver. J'ai essayé de manipuler les propriétés CSS DIV et top abandonnées de left pour les faire correspondre à celles de la LI dans laquelle elles sont déposées, mais les propriétés left et top sont relatives à la gauche DIV.

Comment puis-je mieux faire en sorte que l'élément déposé s'aligne au centre de l'élément dans lequel il est déposé? Ça doit être simple, non?

Edit: J'utilise jQuery UI 1.7.2 avec jQuery 1.3.2.

Edit 2: Pour tous ceux qui ont ce problème, voici comment je l'ai résolu:

J'ai utilisé la solution de Keith consistant à supprimer l'élément déplacé et à le placer à l'intérieur de l'élément ajouté dans le rappel drop du plugin droppable:

function gallerySnap(droppedOn, droppedElement)
{
    $(droppedOn).html('<div class="drop_styles">'+$(droppedElement).html()+'</div>' );
    $(droppedElement).remove();
}

Je ne souhaite pas que l'élément déposé soit à nouveau déplaçable, mais si vous le faites, reliez-le simplement.

Pour moi, cette méthode a également résolu le problème que je rencontrais lors du positionnement des éléments supprimés (ce qui serait relatif par rapport à la variable DIV de gauche) et du défilement dans la seconde variable DIV. (Les éléments resteraient fixes sur la page, ils défilent maintenant).

J'ai joué avec les options d'accrochage pour que ça ait l'air bien en le glissant, alors merci à karim79 pour cette suggestion.

Je ne vais probablement pas gagner de prix Awesome Code avec cela, alors si vous voyez des améliorations à apporter, partagez-les!

28
10goto10

J'ai eu un problème similaire: j'ai résolu le problème en supprimant manuellement l'élément déplacé de son ancien parent et en l'ajoutant à l'élément déposé. 

16
Keith

J'ai trouvé que la méthode de Keith fonctionnait pour moi. Comme sa réponse n'inclut pas un exemple d'implémentation, je vais poster le mien:

$('.dropTarget').droppable({
    drop: function(ev, ui) {
        var dropped = ui.draggable;
        var droppedOn = $(this);
        $(dropped).detach().css({top: 0,left: 0}).appendTo(droppedOn);
    }
});

ou légèrement plus concise:

$('.dropTarget').droppable({
    drop: function(ev, ui) {
        $(ui.draggable).detach().css({top: 0,left: 0}).appendTo(this);
    }
});
72
Barry Pitman

Merci pour votre message - cela m'a aidé dans la bonne direction. Je trouve un peu plus simple de définir les propriétés de position de l'objet déplaçable au lieu de jouer avec le code HTML. Cela positionne la position dans le coin supérieur gauche de l'objet droppable, mais vous pouvez également le modifier pour le centrer.

drop: function(event, ui) {
   $(ui.draggable).css('top', $(this).position().top);
   $(ui.draggable).css('left', $(this).position().left);
}
10
glackk

J'ai trouvé que lorsque vous faites glisser, jQuery UI ajoute un inline pour vous dire où vous l'avez déposé. Vous trouverez ci-dessous un exemple du code que j'ai utilisé pour l'enclencher.

$('.droppable').droppable({ drop: function(ev, ui) { 
    //Get Details of dragged and dropped
    var draggedclass = ui.draggable.attr('class'),
        droppedclass = 'class' + $(this).attr('name').toLowerCase();

    //update the classes so that it looks od.       
    ui.draggable.removeClass(draggedclass).addClass(droppedclass);  
    ui.draggable.removeAttr('style');
});
3
AutomatedTester
$("form li").draggable({snap:'.ui-droppable', snapMode:'inner', revert:true});
$('.drop').droppable({drop:function(ev, ui)
                           {$(ui.draggable).appendTo($(this))
                                           .css({position:'static', left:'0px', top:'0px'})
                                           .draggable('option', 'disabled', false)
                                           .css({position:'relative'});
                           }
                     }
                    );
3
diyism

Si les divs à gauche se trouvent réellement dans le lis à droite (que vous pouvez confirmer avec Firebug), et si les lis figurent tous dans un ul (comme il se doit), essayez l'une ou les deux choses suivantes:

ul#right_div {
  text-align: center;
}

ul#right_div li {
  text-align: center;
}
0
Anthony

sur la base du code de Barry, que se passe-t-il si nous souhaitons ajouter une option avec un bouton "x" à l'élément à détacher de nouveau du nouveau parent et à être rattaché à l'initiale?

je pensais que ça ressemblait à ça, mais ça ne semblait pas fonctionner ... pour créer une sorte de variable qui conserve son état initial 

var flag;
$('.draggable-div').draggable({
    revert: 'invalid',
    stop: function(){
        $(this).draggable('option','revert','invalid');
        $(this).find('.undo').show();
    flag=$(this).parent();
    }
});


$('.draggable-div').find('.undo').click(function(i, e) {
    var $div = $(this).parent();
$($div).detach().appendTo(flag);
 }

sth est définitivement faux, mais je ne sais pas si vous pouvez comprendre le concept ......... être capable de renverser ce que vous avez laissé tomber à son état initial.

0
nikolas