2010-10-16 17 views
8

Robię aplikację, która używa jednego droppable div i kilku przeciągalnych div s. Jak mogę uczynić zrzucanie, aby nie zaakceptować więcej niż jednego przeciągalnego div? Wyszukałem Google, ale nie znalazłem żadnego obejścia.jQuery UI - Droppable akceptuje tylko jedną przeciągalną


Obejście problemu pojawiło się w moim umyśle. Jak mogę sprawdzić czy w tym niewidocznym dziale znajduje się upuszczony element? Jeśli jest tłoczno następnie przywrócić to przeciągać, który próbuje zostać usunięte

Odpowiedz

5

można zniszczyć widget .droppable() po pierwszym drop, tak:

$(".droppable").droppable({ 
    drop: function(event, ui) { 
     $(this).droppable("destroy"); 
    } 
}); 

You can try out a demo here.

+0

ok, ale kiedy uwolnić tę droppable dziedzinie, jak Zrobić to ponownie można zapisać –

+2

@Emil - Możesz użyć '" disable "' then '" enable "' później zamiast '" destroy "' jeśli musisz ponownie włączyć :) –

+1

Zrobiłem to, ale nie wiem jak aby go włączyć. Próbowałem bez użycia: enable_Droppable, ale nie działało. Co powinienem użyć zamiast "wyjść"? –

0

Aby ją włączyć, należy wybrać opcję: $(".selector").droppable({ disabled: **false** });

25

OK znaleźć ładne rozwiązanie tego problemu, w zasadzie na „spadku” ustawić droppable tylko zaakceptować element, który został przeciągnięty do niego.

Po wyłączeniu "wydarzenie", które trzeba ponownie zainicjować, nie jest już dostępne, dlatego zamiast tego zmieniłem odpowiednie elementy.

Wtedy to możliwe dla mnie, aby użyć zdarzenia OUT aby ponownie przyjąć wszystkich można przeciągać elementy, a ponieważ nic innego nie jest akceptowana OUT nie będą wyzwalane przez inne draggables:

$(".drop-zone").droppable({ 
    drop: function(event, ui) { 
     $(this).droppable('option', 'accept', ui.draggable); 
    }, 
    out: function(event, ui){ 
     $(this).droppable('option', 'accept', '.drag-item'); 
     } 
    }); 
}); 
+0

Miałem ten sam problem. Bardzo dobre rozwiązanie, dzięki. – flash

+0

Szybka uwaga: działa to tylko od jQuery 1.6 – Narretz

+0

Miałem ten sam problem, jak również. Inteligentne rozwiązanie! Dobra robota! –

1

Jak to około:

$(".drop-zone").droppable({ 
    accept: function(draggable) { 
     return $(this).find("*").length == 0; 
    }); 
}); 

W ten sposób funkcja akceptacji zwraca wartość true tylko wtedy, gdy żadne elementy nie zostały jeszcze upuszczone.

0

Można też zrobić to na odwrót, przez powracanie do przesunięcia gdy droppable ma pewnej klasy lub atrybutu (budynek na tym przykładzie: https://stackoverflow.com/a/3418306/1005334).

Tak na przykład, za pomocą atrybutu rel (można też użyć class lub coś innego), bo droppable:

$('.drop-zone').droppable({ 
    drop: function() { 
     drop.attr('rel', 'filled'); 
    } 
}); 

a przeciągany:

$('.draggable').draggable({ 
    revert: function (droppable) { 

     if (droppable.attr('rel') == 'filled') { 
      return true; 
     } 
    } 
}); 
3

Łatwa Peasey. Wystarczy włączyć wszystkie .drop-zone-tych, kiedy unosił się nad nimi, a następnie sprawdzić, czy aktualnie unosił .drop strefa zawiera Draggable elementu

$('.drop-zone').droppable({ 
    over: function(event, ui) { 

    // Enable all the .droppable elements 
    $('.droppable').droppable('enable'); 

    // If the droppable element we're hovered over already contains a .draggable element, 
    // don't allow another one to be dropped on it 
    if($(this).has('.draggable').length) { 
     $(this).droppable('disable'); 
    } 
    } 
}); 
+1

prostu chcę podkreślić, że jest to jeden z niewielu w odpowiedzi tutaj, że faktycznie pracują. – maxheld

+0

$ (this) .has ('. Przeciągalny'). Length zwraca zawsze 0 dla mnie. Czy jest może nowa składnia? – Metaphysiker

2

To rozwiązanie rozwiązuje poważny błąd w odpowiedzi Likwid_T użytkownika.

$('.draggable').draggable({ 
    start: function(ev, ui) { 
    $('.ui-droppable').each(function(i, el) { 
     if (!$(el).find('.ui-draggable').length) $(el).droppable('enable'); 
    }); 
    } 
}); 

$('.droppable').droppable({ 
    drop: function(ev, ui) { 
    $(ev['target']).droppable('disable'); 
    } 
}); 
0

Moje rozwiązanie jest podobne do Likwid_T, z wyjątkiem używa droppable drop zdarzenia, jak również utrzymanie więzi między draggables i droppables zamiast droppable na out imprezy. Myślę, że problem z używaniem out polega na tym, że jest on uruchamiany nawet wtedy, gdy przeciągany przeciągnięty jest nad już "pełnym" droppable, a następnie "out" go.

droppable({ 
    drop: function(event, ui) { 
    var $droppable = $(this); 
    var $draggable = ui.draggable; 

    // If the draggable is moved from another droppable, unlink it from the old droppable 
    var oldDropped = $draggable.data('dropped'); 
    if(oldDropped) { 
     $draggable.data('dropped', null); 
     oldDropped.data('dragged', null); 
    } 

    // Link the draggable and droppable 
    $draggable.data('dropped', $droppable); 
    $droppable.data('dragged', $draggable); 
    }, 
    accept: function() { 
    // Only accept if there is no draggable already associated 
    return !$(this).data('dragged'); 
    } 
}); 

A related cechą jest to, że jeden przeciągając jedną pozycję nad droppable że ma już przeciągać, stary dostanie wymienić i powrócić do swojej pierwotnej pozycji. Oto jak to zrobić:

droppable({ 
    drop: function(event, ui) { 
    var $droppable = $(this); 
    var $draggable = ui.draggable; 

    // Reset position of any old draggable here 
    var oldDragged = $droppable.data('dragged'); 
    if(oldDragged) { 
     // In the CSS I have transitions on top and left for .ui-draggable, so that it moves smoothly 
     oldDragged.css({top: 0, left: 0}); 
     oldDragged.data('dropped', null); 
    } 

    // If the draggable is moved from another droppable, unlink it from the old droppable 
    var oldDropped = $draggable.data('dropped'); 
    if(oldDropped) { 
     $draggable.data('dropped', null); 
     oldDropped.data('dragged', null); 
    } 

    // Link the draggable and droppable 
    $draggable.data('dropped', $droppable); 
    $droppable.data('dragged', $draggable); 
    }, 
}); 
1

spędzam wiele godzin, aby zrozumieć to i wreszcie to działa na mnie tak:

$(".drop-zone").droppable({ 
    classes: { 
     "ui-droppable-active": "ui-state-active", 
     "ui-droppable-hover": "ui-state-hover" 
    }, 
    accept: function(draggable){ 
     if (!$(this).hasClass('dropped') || draggable.hasClass('dropped')){ 
      return true; 
     } 
     return false; 
    }, 
    drop: function(event, ui) { 
     $(this).addClass('dropped'); 
     ui.draggable.addClass('dropped'); 
    }, 
    out: function(event, ui){ 
     $(this).removeClass('dropped'); 
     ui.draggable.removeClass('dropped'); 
    } 
}); 
Powiązane problemy