Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I drag an element into a dropdown list using jQuery UI sortable()?

Short version: How can I drag Link 1 into one of the dropdowns under Link 3 in this demo? http://jsfiddle.net/Gdadu/2/

EDIT: The issue has been brought up about what should happen when an item is dragged over another: should it be placed to the left/right or start a new submenu? In order for the list to be fully sortable, there has to be some way to drop items into non-existing submenus, starting a new ul dropdown. I could insert an empty ul in every list item that doesn't have one yet to serve as a drop target, but the problem above still exists.

This seems a lot more difficult than I initially thought, so I apologize for not having put more effort into this yet, as I hadn't considered some of these problems. I'm willing to accept an answer to the stated issue and worry about the rest later.


I have a basic dropdown navigation list that I want to be fully sortable, using jQuery UI. Any li element should be able to move to any position in the entire list. I'm having trouble with dragging top level list items into submenus, it seems that :hover doesn't trigger on the dropdown list while in "drag mode", so the dropdowns don't appear.

Example HTML:

<ul class="dropdown">
    <li><a href="#">Link 1</a></li>
    <li><a href="#">Link 2</a></li>
    <li><a href="#">Link 3</a>
        <ul>
            <li><a href="#">Link</a></li>
            <li><a href="#">Link</a></li>
            <li><a href="#">Link</a>
                 <ul>
                    <li><a href="#">Link</a></li>
                    <li><a href="#">Link</a></li>
                    <li><a href="#">Link</a></li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

My CSS:

.dropdown,
.dropdown li,
.dropdown ul {
    list-style:none;
    margin:0;
    padding:0;
}
.dropdown {
    position:relative;
    display:block;
    z-index:10000;
}
.dropdown ul {
    position:absolute;
    top:100%;
    width:100%;
    visibility:hidden;
    display:none;
    z-index:900;
}
.dropdown ul ul {
    top:0;
    left:100%;
}
.dropdown li {
    position:relative;
    float:left;
}
.dropdown li:hover{
    z-index:910;
    cursor:default;
}
.dropdown ul:hover,
.dropdown li:hover > ul,
.dropdown a:hover + ul,
.dropdown a:focus + ul {
    visibility:visible;
    display:block;
}
.dropdown a {
    text-decoration:none;
    display:block;
    padding:.5em 2em;
    background:#cde;
    border:1px solid #ccc;
}
.dropdown ul li {
    width:100%;
}

Sortable initialization:

$('.dropdown').sortable({
    items: 'li'
});

Demo: http://jsfiddle.net/Gdadu/2/

For example, I want to drag "Link 1" into a submenu, but can't do it because the submenu doesn't appear while dragging, as if :hover is ignored. I'm not sure if the problem lies in the CSS or javascript. What can I do about this?

Good idea from the comments:

Perhaps you could trigger everything to expand when a drag starts

This would probably work, but I don't want the entire menu to expand. It could be a lot of content with many links and 3 levels of navigation, and would probably overlap itself with all the flyouts/dropdowns (huge mess).

like image 416
Wesley Murch Avatar asked Nov 05 '22 06:11

Wesley Murch


1 Answers

Here is a fiddle that shows a few points that can help you with your implementation: http://jsfiddle.net/Gdadu/13/

It is far from perfect, and as pointed out in the comment, there is a few logical problems also with "sorting everything everywhere" :) Things not working here are sorting nested li's back to top level, sortables on nested ul's, ... but I think they are sketched out there. Distinguishing the sorting from the dragging might be one thing necessairy with jqueryui's current status. Also I shortcut your excellent css solution for the submenus and made them javascript based as to simplify things a bit.

But: You can drop link1 inside link3 or link3's nested ul ;)

like image 67
kontur Avatar answered Nov 07 '22 20:11

kontur