views:

1126

answers:

4

I want to have a list that is sortable, but I also want the elements in that list to be droppable to the divs I have defined as droppable. I can't seem to find a way to do it. Any ideas?

A: 

I think this is what you're looking for: http://docs.jquery.com/UI/Draggable#option-connectToSortable

Cryo
This allows me to add new elements to the sort that are clones of a draggable, but doesn't let the sortable act as a draggable.
Colin
You can link sortables together with the connectWith option: http://docs.jquery.com/UI/Sortable#option-connectWith.
Cryo
Still not exactly what I'm going for. This is what I need, but it appears to use different draggable, droppable, and sortable functions than are in the UI. I've already developed heavily with the AI, and I'd rather not recode. It must be possible somehow:http://wiki.github.com/raid-ox/interaction.js/demo-draggable-sortable-and-droppableThanks
Colin
Can you clarify your specific project for me a little bit? You want one master sortable list that can be dragged from to another container that isn't draggable or sortable?
Cryo
Sure. It functions exactly as in that link. There's one sortable list. I want to make it so you can drag a sortable item away from the list and into a droppable to execute a drop function. When the drop function gets executed, the sortable list should maintain its position.
Colin
Something like this: http://www.codeclarity.com/sort_drop/? That's just a sortable and a droppable with no extra configuration, only a drop method that alerts the ID of the dropped element.
Cryo
A: 

I've spent all day on this, and I've gotten a lot closer, but still not doing as well as I'd like. I now have the functionality I need, but a Javascript error is getting thrown.

The issue is getting the sortable list to return to its previous position if the element is dropped in the droppable, rather than in the list. Currently, I'm saving the html onmousedown, then rewriting the html in the drop function of the droppable. This works, but its giving me a jquery variable is null error. Can anyone find a better solution?

Code:

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"&gt;&lt;/script&gt;
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js"&gt;&lt;/script&gt;
    <script type="text/javascript">

var templateHtml;
$(document).ready(function(){

    $("#sortable").sortable();
    $("#sortable li").addClass("drop").bind('mousedown',function(){
        templateHtml = $("#sortable").html();
    });
    $("#droppable").droppable({
        activeClass: 'active',
        hoverClass:'hovered',
        accept:".drop",
        drop:function(event,ui){
            $("#sortable").sortable('destroy').html(templateHtml);
            $("#sortable").sortable();
            $("#sortable li").addClass("drop").bind('mousedown',function(){
                templateHtml = $("#sortable").html();
            });          
        }
    });

});

    </script>
    <style type="text/css">
    #sortable li{
        clear:both;
        float:left;
    }

    #droppable {
        clear:both;
        height:300px;
        width:400px;
        background-color:#CCC;
    }
    #droppable.active {
        background-color:#CFC;
    }
    #droppable.hovered {
        background-color:#CCF;
    }
    </style>

</head>
<body>

<ul id="sortable">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
<li id="six">Six</li>
</ul>

<div id="droppable">
Drop Here
</div>

</body>
Colin
+2  A: 

As far as I could tell, the issue with the previous code I posted is that the drop function of the droppable was getting called before the mouseup of the sortable, and since I rewrote the list the sortable was getting angry (for lack of better terms). That's somewhat a guess.

Looking at the final code:

<html>
<head>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js"&gt;&lt;/script&gt;
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/jquery-ui.js"&gt;&lt;/script&gt;
    <script type="text/javascript">

var dropped = false;
var templateHtml;
$(document).ready(function(){

    setSortable();

    $("#droppable").droppable({
        activeClass: 'active',
        hoverClass:'hovered',
        accept:".drop",
        drop:function(event,ui){
            dropped = true;
            //alert(ui.draggable.text());
        }
    });

});

function setSortable(){
    $("#sortable").sortable({
        stop:function(event,ui){
            if(dropped){
                $("#sortable").sortable('destroy').html(templateHtml);
                dropped = false;
                setSortable();
            }
        }
    });

    $("#sortable li").addClass("drop").bind('mousedown',function(){
        templateHtml = $("#sortable").html();
    });
}

    </script>
    <style type="text/css">
    #sortable li{
        clear:both;
        float:left;
    }

    #droppable {
        clear:both;
        height:300px;
        width:400px;
        background-color:#CCC;
    }
    #droppable.active {
        background-color:#CFC;
    }
    #droppable.hovered {
        background-color:#CCF;
    }
    </style>

</head>
<body>

<ul id="sortable">
<li id="one">One</li>
<li id="two">Two</li>
<li id="three">Three</li>
<li id="four">Four</li>
<li id="five">Five</li>
<li id="six">Six</li>
</ul>

<div id="droppable">
Drop Here
</div>

</body>

Tons of quirks are involved here.

I tried to save the #sortable html on the start event of sortable, but that get's called after all of the ui-css gets applied, and ended up placing list elements in crazy places. So, I needed to use the mousedown function on the LIs.

The setSortable is in a function because the stop event rewrites the sortable, which is "recursive" I guess. Not sure the exact terminology here, but we can go with annoyingly confusing.

Fortunately, the droppable's drop function gets called before the sortables stop function, so I was able to set a global "dropped" variable that was used to see if the element was dropped.

I'm still surprised this wasn't easier to do, I thought jQuery would have functions to handle it a lot better. Perhaps I'm missing something?

Colin
A: 

I've been working on something practically identical. I created this originally in prototype, and its working flawlessly but recently decided because of upcoming functionality that JQuery should be used if possible so I've been trying to rewrite exactly what you describe here in JQuery. I psudo-solved the problem of returning sortable items by setting the "tolerance:" attribute for the sortable and droppable.

By setting tolerence: fit on the Sortable and Tolerance: touch on the droppable it is preventing any sort once the LI is moved outside the bounds of its parent UL. so once released over the droppable it snaps right back. The issue i've been running into now is accessing content of a textarea inside the sortable once dropped.

Nathan
The documentation on Tolerance doesn't really describe anything that would make it work. Did you just set it to 'pointer'? I might try that. Now you're having trouble accessing a <textarea>? Try setting a "handle" and you should be okay.
Colin
I set tolerance to "Fit" on the sortables i was using. then set tolerance to touch on the droppable area. This simulates a snap back but by no means enforces it. it works by simply bounding any sorting in the "sortable" area to inside the bounds of the sortable element. if that makes sence. Once you drag any of the individual sortable elements out side of the bounds of the parent they no longer shift position and simply fall back into place when you release.
Nathan