0

I am building a new UI using jquery and I am having some trouble using .sortable inside a div that is displayed using slide toggle. Here is the HTML (MVC Razor):

<div style="float:left; width:200px; margin-right:5px" >
    <div class="FeaturesContainer">  
    <b>Project backlog</b><br /> 
        @foreach (var feature in Model.Managment.tasksByFeature)
        {
            if (feature.Value.Count != 0)
            { 
                <div class="FeatureContainer">
                    <div class="FeatureHeading" id="@feature.Key.id">
                         <div class="icon" style="float:right">
                            <img width="20" src="../../Content/images/down.png" />
                         </div>
                        <span class="FeatureTitle">@feature.Key.summary</span>      
                    </div>
                    <div class="Feature">
                        <ul class="drop">
                        @foreach (var task in feature.Value)
                            { 
                                <li class="taskItem">
                                    @Html.ActionLink(task.summary, "Task", new { proj = Model.Managment.project.Id, id = task.id })<br />
                                    Effort: @task.Effort
                                </li>
                            }
                        </ul>
                    </div> 
                </div>
            }
        }
    </div>
</div>

<div style="float:left; width:190px;">
    <div class="SprintContainer" id="@Model.Managment.sprint.Id">
        <b>Tasks for this sprint</b><br />
        <ul class="drop">
        @foreach (var task in Model.Managment.tasksInSprint)
        {
            <li class="taskItem">
                @Html.ActionLink(task.summary, "Task", new { proj = Model.Managment.project.Id, id = task.id })<br />
                Effort: @task.Effort
            </li>
        }
        </ul>
        Max Effort: @Model.Metrics.Velocity<br />
        Total Effort: @Model.Managment.tasksInSprint.Sum(i => i.Effort)
    </div>
</div>

And the revlevent CSS:

.drop 
    { 
        list-style-type: none; 
        margin: 0; 
        float: left; 
        margin-right: 5px; 
        background: #eee; 
        padding: 5px; 
        width: 158px;
        min-height:75px;
    }    

    .drop li 
    { 
        padding: 5px; 
        font-size: .9em; 
        width: 145px; 
        cursor:move;
    }   

    .highlight
    {
        border: 1px dashed #3E3E3E;
        height:50px;
        margin-bottom:2px;
    }

    .FeaturesContainer
    {
        background-color:#FFFFFF;
        border: 2px solid #3E3E3E;
        color:#FE7F00;
        padding:5px;
        -moz-border-radius: 4px;
        border-radius: 4px;
        margin:  0 0 10px 0;  
    }

    .SprintContainer
    {
        background-color:#FFFFFF;
        border: 2px solid #3E3E3E;
        color:#FE7F00;
        padding:5px;
        -moz-border-radius: 4px;
        border-radius: 4px;
        margin-bottom:10px;
        margin-right: 5px;  
    }

    .FeatureContainer
    {
        background-color:#BEBEBE;
        border: 1px solid #3E3E3E;
        color:#FE7F00;
        padding:5px;
        margin-bottom:10px;
        margin-top:5px;
        margin-right: 5px;  
    }

    .FeatureHeading
    { 
        padding: 5px 10px;
        cursor: pointer;
        position: relative;
        margin:1px;
        color:#FFFFFF;
        background-color:#006600;
        border-left: 1px solid #3E3E3E;
        border-right: 1px solid #3E3E3E;
        border-top: 1px solid #3E3E3E;
    }

    .Feature
    {
        padding:0;
        margin:0 0 0 0;
        position:relative;
        border-left: 1px solid #3E3E3E;
        border-right: 1px solid #3E3E3E;
        border-bottom: 1px solid #3E3E3E;

    }

And the jQuery:

$(function () {
    $("ul.drop").sortable({ connectWith: "ul", dropOnEmpty: true, placeholder: "highlight" });
});

$(document).ready(function () {
        var visible = true;
        $(".Feature").hide();

        $(".FeatureHeading").click(function () {
            $(this).next(".Feature").slideToggle(function () {
                visible = !visible;
                $(this).css({'height': 'auto'})
                if (visible) {
                    $('img', this).attr('src', '../../Content/images/down.png');
                }
                else {
                    $('img', this).attr('src', '../../Content/images/up.png');
                }

            });
        });
});

The problem is, when I click the FeatureHeading, the Feature slides down as expected, but as soon as the animation is complete it immediately collapses, yet the content of the Feature div is still visible. The list items are still draggable, and I can drop them in the Sprintcontainer.

If I add overflow:hidden to the Feature, the feature will display as desired, however as soon as I try to drag a list item to the SprintContainer the item seems to go behind the FeatureContainer and I can’t see it being dragged until I release the mouse over the sprint container, at which point the list item appears in the sprint container as expected.

Is it possible to have a sortable list inside a slidetoggle div?

Mark Jones
  • 1,461
  • 1
  • 14
  • 23

1 Answers1

1

While you are using overflow:hidden, try using 'appendTo: document.body'

http://api.jqueryui.com/sortable/#option-appendTo

It will resolve your issues for the item going behind FeatureContainer

Mandeep Jain
  • 2,304
  • 4
  • 22
  • 38
  • You star!! After 3 days and no answers I was about ready to give up on this and go back to the designing a new interface. Thank you so much. If you ever find yourself in Nottingham I will buy you a pint! – Mark Jones Jan 25 '13 at 06:36
  • ohhh, just a note. I also had to add helper: "clone" to make the solution work. – Mark Jones Jan 25 '13 at 06:41
  • You are welcome. And yup, I forgot to mention helper:clone. Nottingham ... lets see :D – Mandeep Jain Jan 25 '13 at 09:18