2010-10-16 12 views
8

Sto realizzando un'app, ovvero utilizzando un droppable div e alcuni trascinabili div s. Come posso rendere il droppable non accettare più di uno div trascinabile? Ho cercato su Google, ma non ho trovato soluzioni alternative.Interfaccia utente jQuery - Droppable accetta solo uno trascinabile


Una soluzione è venuto fuori in mente. Come posso verificare se ci sono elementi scartati in questo div trascurabile? Se è occupato poi invertire questa trascinabili, che sta cercando di essere caduto

risposta

5

Puoi distruggere il widget .droppable() dopo la prima drop, in questo modo:

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

You can try out a demo here.

+0

ok, ma quando ho gratuitamente questo campo droppable, come rendilo nuovamente trascinabile –

+2

@Emil - Puoi usare '" disable "' quindi '" enable "' successivamente invece di '" destroy "' se hai bisogno di riattivarlo :) –

+1

l'ho fatto, ma non so come per abilitarlo. Ho provato senza: enable_Droppable, ma non ha funzionato. Cosa dovrei usare al posto di 'out' –

0

Per abilitarla, usare l'opzione: $(".selector").droppable({ disabled: **false** });

25

OK trovato una bella soluzione per questo, in sostanza, il 'drop' ho impostato il droppable di accettare solo l'elemento che è stato trascinato in esso.

Quando si "disabilita", l'evento "out" che è necessario re-inizializzare non è più disponibile, quindi ho semplicemente cambiato gli elementi idonei in giro.

Poi è possibile per me di utilizzare l'evento OUT ad accettare nuovamente tutti gli elementi trascinabili e perché niente altro è stata accettata l'OUT non verrà attivato da altri 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

Ho avuto lo stesso problema. Ottima soluzione, grazie. – flash

+0

Nota rapida: funziona solo da jQuery 1.6 – Narretz

+0

Ho avuto lo stesso problema. Soluzione intelligente! Ottimo lavoro! –

1

Come su questo:

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

In questo modo la funzione accept restituisce true solo quando non è stato ancora eliminato alcun elemento.

0

Si potrebbe anche fare il contrario, ripristinando il trascinamento quando il droppable ha una determinata classe o attributo (basandosi su questo esempio: https://stackoverflow.com/a/3418306/1005334).

Così, per esempio, utilizzando l'attributo rel (si potrebbe anche usare class o altro), per il droppable:

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

E il trascinabile:

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

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

Facile Peasey. Basta attivare tutto, quando aleggiava su di loro, e quindi verificare se il momento aleggiava .Drop-zona contiene un elemento trascinabile

$('.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

vogliono solo far notare che questo è uno dei pochi risposte in qui che funzionano davvero. – maxheld

+0

$ (this) .has ('. Draggable'). Length restituisce sempre 0 per me. C'è forse una nuova sintassi? – Metaphysiker

2

Questa soluzione risolve un bug importante nella risposta di Likwid_T il .Drop-zona.

$('.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

La mia soluzione è simile a Likwid_T di, tranne che utilizza il droppable drop evento oltre a mantenere i legami tra draggables e droppables invece di di droppable dell'evento out. Penso che il problema con l'utilizzo di out è che viene attivato anche quando un trascinamento viene trascinato su un "droppable" completo e quindi "out" di esso.

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

Una caratteristica correlato è che si trascina un elemento in una droppable che ha già un trascinabile, il vecchio otterrebbe sostituito e tornare alla sua posizione iniziale. Questo è come lo faccio:

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

trascorro molte ore per capirlo e, infine, per me funziona in questo modo:

$(".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'); 
    } 
}); 
Problemi correlati