2009-04-01 5 views
27

Je cherche à mettre en œuvre une interface web avec un certain nombre d'éléments qui peuvent être sélectionnés et déplacés pour les positionner, soit soit en groupes ou individuellement. Plutôt comme le bureau de Windows, vraiment.Y at-il un plugin JQuery qui combine Draggable et Selectable

Nous utilisons déjà JQuery, donc les ajouts à ce serait le premier choix. JQuery UI Draggables et Selectables font individuellement beaucoup de ce que nous voulons, mais ne fonctionnent pas vraiment ensemble pour donner le type d'effet que nous recherchons. Je suis complètement submergé par le site du plugin JQ (son algorithme 'populaire' ne me semble pas très utile), et souhaiterais avoir des conseils sur la meilleure façon d'éviter beaucoup de réinvention de la roue ici, comme je le devine que cette métaphore a déjà été faite.

+0

Le code dans http://stackoverflow.com/questions/34698117/elements-became-randomly-non-resizable-after-dragging queston contient aussi une réponse à cette question Cependant le code dans les réponses cause une perte aléatoire de redimensionnable par glisser – Andrus

Répondre

19

J'ai également dû faire la même chose, et je ne voulais pas utiliser l'extension d'interface de eyecon.ro. Après quelques recherches, j'ai trouvé Combining Selectables And Draggables Using jQuery UI. C'est bien dit, mais pour faire fonctionner les extraits de code, il faut creuser dedans. J'étais capable de le faire fonctionner. J'ai légèrement changé, c'est ma façon de le faire. Il a besoin de modifications pour être utilisé au niveau de la production, mais j'espère que cela aidera.

// this creates the selected variable 
// we are going to store the selected objects in here 
var selected = $([]), offset = {top:0, left:0}; 

// initiate the selectable id to be recognized by UI 
$("#selectable").selectable({ 
    filter: 'div', 
}); 

// declare draggable UI and what we are going to be doing on start 
$("#selectable div").draggable({ 
    start: function(ev, ui) { 
     selected = $(".ui-selected").each(function() { 
      var el = $(this); 
      el.data("offset", el.offset()); 
     }); 

     if(!$(this).hasClass("ui-selected")) $(this).addClass("ui-selected"); 
     offset = $(this).offset(); 
    }, 
    drag: function(ev, ui) { 
     var dt = ui.position.top - offset.top, dl = ui.position.left - offset.left; 

     // take all the elements that are selected expect $("this"), which is the element being dragged and loop through each. 
     selected.not(this).each(function() { 
      // create the variable for we don't need to keep calling $("this") 
      // el = current element we are on 
      // off = what position was this element at when it was selected, before drag 
      var el = $(this), off = el.data("offset"); 
      el.css({top: off.top + dt, left: off.left + dl}); 
     }); 
    } 
}); 

Styles CSS pour être en mesure de voir ce qui se passe:

#selectable { width: 100%; height: 100%;} 
#selectable div { 
    background: #ffc; 
    line-height: 25px; 
    height: 25px; 
    width: 200px; 
    border: 1px solid #fcc; 
    } 
#selectable div.ui-selected { 
    background: #fcaf3e; 
    } 
#selectable div.ui-selecting { 
    background: #8ae234; 
    } 

HTML Markup:

<div id="selectable"> 
    <div>item 1</div> 
    <div>item 2</div> 
    <div>item 3</div> 
    <div>item 4</div> 
</div> 
+2

problème principal avec ce code, il ne vous permet pas de contrôler cliquez pour ajouter des éléments supplémentaires. –

+2

Cela ne semble que vous permettre de faire glisser plusieurs éléments sélectionnés, je ne suis pas en mesure de sélectionner un élément sélectionnable avec un seul clic (sans parler ctrl click) – digout

+0

Ce code provoque une perte aléatoire de redimensionnable sur glisser. Ceci est publié dans http://stackoverflow.com/questions/34698117/elements-became-randomly-non-resizable-after-dragging Comment réparer? – Andrus

4

J'ai fait quelques modifications à la réponse donnée par Sinan Yasar. Ce n'est pas parfait mais il se comporte déjà beaucoup plus comme je le ferais sauf.

Un ajout principal est un écouteur de clic qui appelle le select.

// manually trigger the "select" of clicked elements 
$("#selectable > div").click(function(e){ 
    if (e.metaKey == false) { 
     // if command key is pressed don't deselect existing elements 
     $("#selectable > div").removeClass("ui-selected"); 
     $(this).addClass("ui-selecting"); 
    } 
    else { 
     if ($(this).hasClass("ui-selected")) { 
      // remove selected class from element if already selected 
      $(this).removeClass("ui-selected"); 
     } 
     else { 
      // add selecting class if not 
      $(this).addClass("ui-selecting"); 
     } 
    } 

    $("#selectable").data("selectable")._mouseStop(null); 
}); 

Vous pouvez voir un exemple de travail complet ici: http://jsfiddle.net/DXrNn/4/

Il y a aussi un plugin jquery-ui disponible qui fait exactement cela: http://code.google.com/p/jqdragdropmultiselect/ Le Probleme est qu'il n'a pas l'air maintenu. Edit: si vous définissez l'option "filter" du draggable, vous devrez appeler selectable.refresh() avant le selectable_mouseStop (null).

$("#selectable > div").click(function(e){ 
    ... 
    var selectable = $("#container").data("selectable"); 
    selectable.refresh(); 
    selectable._mouseStop(null); 
    ... 
+2

Peu importe combien j'essaye votre solution dans jsfiddle, je ne peux obtenir aucun élément à faire glisser, seulement sélectionner. Chrome 19. – trusktr

+1

@trusktr Essayez i avec 'jQuery 1.8.3' et' jQueryUI 1.9.2' – mraaroncruz

+1

@trusktr pour cette raison http://stackoverflow.com/questions/14366322/error-jquery-ui-draggable-cannot- read-property-msie semble que vous auriez besoin de jQueryUI 1.10 pour utiliser jQuery EDGE – mraaroncruz

10

Cette question est pertinente, mais elle est ancienne; ainsi sont les réponses. Here's an updated version de @ la jsFiddle de idFlood, qui fonctionne avec jQuery 1.9.1 + jQueryUI 1.10.3:

// store selected elements and the offset of the dragged element 
var selected = $([]), offset = {top:0, left:0}; 

$("#selectable > div").draggable({ 
    start: function (event, ui) { 
     var $this = $(this); 

     if ($this.hasClass("ui-selected")) { 
      // if this is selected, attach current offset 
      // of each selected element to that element 
      selected = $(".ui-selected").each(function() { 
       var el = $(this); 
       el.data("offset", el.offset()); 
      }); 
     } else { 
      // if this is not selected, clear current selection 
      selected = $([]); 
      $("#selectable > div").removeClass("ui-selected"); 
     } 
     offset = $this.offset(); 
    }, 

    drag: function (event, ui) { 
     // drag all selected elements simultaneously 
     var dt = ui.position.top - offset.top, dl = ui.position.left - offset.left; 
     selected.not(this).each(function() { 
      var $this = $(this); 
      var elOffset = $this.data("offset"); 
      $this.css({top: elOffset.top + dt, left: elOffset.left + dl}); 
     }); 
    } 
}); 

// enable marquee selecting and deselect on outside click... 
$("#selectable").selectable(); 

// ...but manually implement selection to prevent interference from draggable() 
$("#selectable").on("click", "div", function (e) { 
    if (!e.metaKey && !e.shiftKey) { 
     // deselect other elements if meta/shift not held down 
     // $("#dc-modules .dc-module").removeClass("ui-selected"); 
     $("#selectable > div").removeClass("ui-selected"); 
     $(this).addClass("ui-selected"); 
    } else { 
     if ($(this).hasClass("ui-selected")) { 
      $(this).removeClass("ui-selected"); 
     } else { 
      $(this).addClass("ui-selected"); 
     } 
    } 
}); 

J'ai eu un problème avec l'appel _mouseStop() lancer une erreur, donc je l'ai enlevé; cela signifie que l'état ui-selecting ne se produit plus lors du clic, mais toutes les autres fonctionnalités restent intactes.

+0

Cette solution fonctionne très bien mais j'ai du mal à la faire fonctionner avec droppable. Y a-t-il quelque chose d'intrinsèque à la solution qui, selon vous, entrerait en conflit avec droppable ou devrais-je continuer à me battre contre ce code? –

+0

@ericsoco Ce code provoque un loff aléatoire de redimensionnable sur glisser. Ceci est publié dans http://stackoverflow.com/questions/34698117/elements-became-randomly-non-resizable-after-dragging Comment réparer? – Andrus

Questions connexes