2009-04-01 7 views
27

Ich bin auf der Suche nach einer Web-Schnittstelle mit einer Reihe von Elementen zu implementieren, die ausgewählt und gezogen werden können, entweder in Gruppen oder einzeln. Eher wie der Windows Desktop.Gibt es ein JQuery-Plugin, das Draggable und wählbar kombiniert

Wir verwenden bereits JQuery, also Ergänzungen zu diesem wäre die erste Wahl. JQuery UI Draggables und Selectables machen vieles von dem, was wir wollen, aber nicht wirklich zusammen, um den gewünschten Effekt zu erzielen.

Ich bin völlig überwältigt von der JQ-Plugin-Website (es ist "populären" Algorithmus scheint nicht sehr nützlich), und würde eine Anleitung begrüßen wie die beste Möglichkeit, eine Menge Rad-Neuerfindung hier zu vermeiden, wie ich denke dass diese Metapher bereits gemacht wurde.

+0

Code in http://stackoverflow.com/questions/34698117/elements-became-randomly-non-resizable-after-dragging queston enthält auch eine Antwort auf diese Frage Allerdings Code in Antworten verursachen zufällige Verlust der Größe in der Größe veränderbar – Andrus

Antwort

19

Ich musste auch dasselbe tun, und ich wollte keine Schnittstellenerweiterung von eyecon.ro verwenden. Nach einigen Recherchen fand ich Combining Selectables And Draggables Using jQuery UI. Es ist schön erzählt, aber um die Code-Schnipsel laufen zu lassen, müssen Sie hinein graben. Ich konnte es zum Laufen bringen. Ich habe es leicht geändert, das ist mein Weg, um es zu erledigen. Es braucht Modifikationen für den Einsatz auf Produktionsebene, aber ich hoffe, es hilft.

// 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}); 
     }); 
    } 
}); 

CSS-Stile in der Lage sein zu sehen, was passiert:

#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-Code:

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

Die Hauptproblem mit diesem Code lässt Sie nicht steuern Sie klicken, um zusätzliche Elemente hinzuzufügen. –

+2

Dies scheint nur zu ermöglichen, dass Sie mehrere ausgewählte Elemente ziehen, ich kann kein auswählbares Element mit einem einzigen Klick auswählen (geschweige denn Strg-Klick) – digout

+0

Dieser Code verursacht zufällige Verlust der Größe beim Ziehen. Dies wird in http://stackoverflow.com/questions/34698117/elements-became-randomly-non-resizable-after-dragging geschrieben Wie zu beheben? – Andrus

4

ich einige Änderungen an den von Sinan Yasar gegebene Antwort gemacht haben. Es ist nicht perfekt, aber es benimmt sich schon viel mehr als ich würde außer.

Ein wichtiger Zusatz ist ein Klick-Listener, der die Auswahl aufruft.

// 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); 
}); 

Sie können hier ein komplettes Arbeitsbeispiel sehen: http://jsfiddle.net/DXrNn/4/

Es gibt auch eine jquery-ui-Plugin zur Verfügung, die genau das tut: http://code.google.com/p/jqdragdropmultiselect/ Die Probleme ist, dass es gepflegt aussieht nicht.

edit: Wenn Sie die Option "filter" des ziehbaren Objekts definieren, müssen Sie selectable.refresh() vor dem selectable._mouseStop (null) aufrufen.

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

Egal, wie sehr ich Ihre Lösung in jfiddle versuche, kann ich keine Elemente zum Ziehen bekommen, nur auswählen. Chrome 19. – trusktr

+1

@trusktr Probieren Sie i mit 'jQuery 1.8.3' und' jQueryUI 1.9.2' – mraaroncruz

+1

@trusktr aus diesem Grund http://StackOverflow.com/Questions/14366322/error-Jquery-ui-draggable-cannot- read-property-msie scheint, dass Sie jQueryUI 1.10 benötigen würde, um jQuery EDGE – mraaroncruz

10

Diese Frage ist relevant, aber ist alt; Das sind auch die Antworten. Here's an updated version von @ idFlood des jsfiddle, die mit jQuery 1.9.1 + jQueryUI 1.10.3 funktioniert:

// 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"); 
     } 
    } 
}); 

Ich hatte ein Problem mit dem _mouseStop() Aufruf einen Fehler zu werfen, so dass ich es entfernt; Das bedeutet, dass der Zustand ui-selecting nicht mehr beim Klicken auftritt, aber alle anderen Funktionen bleiben erhalten.

+0

Diese Lösung funktioniert sehr gut, aber ich habe Probleme, es mit droppable arbeiten zu lassen. Gibt es etwas, das der Lösung immanent ist, von dem Sie denken, dass es mit dem Fall kollidieren würde, oder sollte ich weiterhin gegen diesen Code anklopfen? –

+0

@ericsoco Dieser Code bewirkt eine zufällige Verkleinerung der Größe beim Ziehen. Dies wird in http://stackoverflow.com/questions/34698117/elements-became-randomly-non-resizable-after-dragging geschrieben Wie zu beheben? – Andrus