views:

35

answers:

2

I have two connected sortable lists. For the sake of my question, when I start dragging an item from #sortable1 to #sortable2, in the start event I want to cancel/ disable/ the drop in #sortable2

Nothing works?

$("#sortable1, #sortable2").sortable({
    connectWith: "#sortable1, #sortable2", 
    start: startDrag
});

function startDrag(event, ui) {
    $("#sortable2").css("opacity","0.5");

    // $("#sortable2").sortable("cancel"); // goes whooooo
    /* docs say:
    If the sortable item is being moved from one connected sortable to another:
    $(ui.sender).sortable('cancel');
    will cancel the change. Useful in the 'receive' callback. 
    */
    // $("#sortable1").sortable("cancel"); // I only want to cancel dropping in sortable2...
    // $("#sortable2").sortable("disable"); // disables only after the drop event
    // $("#sortable2").sortable("destroy"); // same as "disable"
}
function stopDrag(event, ui) {
    $("#sortable2").css("opacity","1.0");
    // $("#sortable2").sortable("enable");
}

My JSFiddle here: http://jsfiddle.net/tunafish/m32XW/

I have found 2 more questions like mine:
http://stackoverflow.com/questions/1189945/jquery-sortabledisable-from-start-event-not-entirely-working-like-expected
http://forum.jquery.com/topic/disable-a-sortable-while-dragging-with-connectedlists

No responses.. Anything appreciated!

EDIT: I also tried to overlay a div like a modal on the sortable, but can still be dragged to that way. The only thing that worked is a show/hide, but that's not an option for me.

A: 

Ok I found some sort of hack for this.
When an item is moved from #sortable1 to #sortable2, when dragged over #sortable2 there is a list item added with class .placeholder So in UI's over event I did

$("#sortable2 li.placeholder").hide();

Than set it back with UI's stop event

$("#sortable2 li.placeholder").show();

This is only for visuals though.. The item is still moved into #sortable2 so you need to remove() it there. To mimic copying you need to add a clone() back in #sortable2. You can get it's original index() in UI's start event and than use insertAfter(id - 1)

At the moment I can only clone in UI's receive event, I would prefer in UI's over but can't get it to work..

FFish
A: 

OK here is my app; two lists of images, sortable and you can copy over from the connected list.
If an item already exists in the target it's disabled.
Hopefully useful to someone...

JSFiffle here: http://jsfiddle.net/tunafish/VBG5V/

CSS:

.page { width: 410px; padding: 20px; margin: 0 auto; background: darkgray; }
.album { list-style: none; overflow: hidden; 
    width: 410px; margin: 0; padding: 0; padding-top: 5px;
    background: gray; 
} 
.listing { margin-bottom: 10px; }
.album li { float: left; outline: none;
    width: 120px; height: 80px; margin: 0 0 5px 5px; padding: 5px;
    background: #222222;
 }
li.placeholder { background: lightgray; }

JS:

$("ul, li").disableSelection();

$(".album, .favorites").sortable({
    connectWith: ".album, .favorites",
    placeholder: "placeholder", 
    forcePlaceholderSize: true, 
    revert: 300,
    helper: "clone",
    stop: uiStop,
    receive: uiReceive,
    over: uiOver
});


$(".album li").mousedown(mStart);

var iSender, iTarget, iIndex, iId, iSrc, iCopy;
var overCount = 0;

/* everything starts here */
function mStart() {
    // remove any remaining .copy classes
    $(iSender + " li").removeClass("copy");

    // set vars
    if ($(this).parent().hasClass("listing")) { iSender = ".listing"; iTarget = ".favorites"; } 
    else { iSender = ".favorites"; iTarget = ".listing"; }
    iIndex  = $(this).index();
    iId     = $(this).attr("id");
    iSrc    = $(this).find("img").attr("src");  
    iCopy   = $(iTarget + " li img[src*='" + iSrc + "']").length > 0; // boolean, true if there is allready a copy in the target list   

    // disable target if item is allready in there  
    if (iCopy) { $(iTarget).css("opacity","0.5").sortable("disable"); }
}

/* when sorting has stopped */
function uiStop(event, ui) {
    // enable target
    $(iTarget).css("opacity","1.0").sortable("enable");

    // reset item vars
    iSender = iTarget = iIndex = iId = iSrc = iCopy = undefined;
    overCount = 0;

    // reinit mousedown, live() did not work to disable
    $(".album li").mousedown(mStart);
}

/* rolling over the receiver - over, out, over etc. */
function uiOver(event, ui) {
    // only if item in not allready in the target
    if (!iCopy) {                   
        // counter for over/out (numbers even/uneven)
        overCount++;
        // if even [over], clone to original index in sender, show and fadein (sortables hides it)
        if (overCount%2) {
            if (iIndex == 0) { ui.item.clone().addClass("copy").attr("id", iId).prependTo(iSender).fadeIn("slow"); } 
            else { ui.item.clone().addClass("copy").attr("id", iId).insertAfter(iSender + " li:eq(" + iIndex + ")").fadeIn("slow"); }
        } 
        // else uneven [out], remove copies
        else { $(iSender + " li.copy").remove(); }
    } 
    // else whoooooo
}

/* list transfers, fix ID's here */
function uiReceive(event, ui) {
    (iTarget == ".favorites") ? liPrefix = "fli-" : liPrefix = "lli-";  
    // set ID with index for each matched element
    $(iTarget + " li").each(function(index) {
        $(this).attr("id", liPrefix + (index + 1)); // id's start from 1
    });
}

HTML:

<div class="page">

    <div class="container">
        <h2>Photo Album</h2>
        <ul class="listing album">
            <li id="li-1"><img src="tn/001.jpg" /></li>
            <li id="li-2"><img src="tn/002.jpg" /></li>
            <li id="li-3"><img src="tn/003.jpg" /></li>
            <li id="li-4"><img src="tn/004.jpg" /></li>
            <li id="li-5"><img src="tn/005.jpg" /></li>
        </ul>
    </div>

    <div style="clear:both;"></div>

    <div class="container">
        <h2>Favorites</h2>
        <ul class="favorites album">
            <li id="fli-1"><img src="tn/001.jpg" /></li>
            <li id="fli-2"><img src="tn/002.jpg" /></li>
            <li id="fli-3"><img src="tn/010.jpg" /></li>
        </ul>
    </div>

</div>
FFish