jquery: how to extend drop area of a sortable to entire div
I need the entire div that's containing the sortable ul to be drop area.
flexi comment box
It took me a while but I figured it out myself... Maybe I can save someone else the pain, so here goes...
just convert the div into a draggable and in drop event function add the dragged item in the children of the target list.
It is not that easy since when dragging the physical dragged element(object) ist not available programmtically with all its attributes. You just seem to get the text in attributes and not even the id.
My idea was to save the id of the element on mouse down event when dragging starts. then I created the complete list item giving the text from the dragged item text and giving it the id that I saved earlier. in mouse down event at the start of the process.
Setting mouse-down event on the draggable element (in my case a list item) ##
When the mouse is first down on the draggable element (that is when the dragging event starts) I capture the id of the element, since I need the element's id to be able to add it to the database running at backend.
<li align="left" onmousedown="mouseDown(this)" id="1832" class="ui-state-default">Advanced Econometrics II | E 805</li>
Mouse Down function saving the id of the dragged item
Maybe it is important to mention that you should not initialize the variable dragged_course_id with the word 'var' before it, because if you do the variable will become local and won't be available in the drop event function at the end of the drag process.
function mouseDown(item)
{
dragged_course_id = item.id;
// alert (dragged_course_id);
}
Droppable Div Configuration
$(function() {
$( "#droppable" ).droppable({
activeClass: "greedy",
hoverClass: "over_state",
drop: function( event, ui )
{
$( this ).removeClass("over_state");
target_stack = document.getElementById('sortable2');
var already_selected_courses = target_stack.childNodes;
ignore=false;
for (i=0;i<already_selected_courses.length; i++)
{
if (dragged_course_id == already_selected_courses[i].id) ignore=true;
}
if (!ignore) $( "<li align='left' class='ui-state-default' id= "+dragged_course_id+"></li>" ).text( ui.draggable.text() ).appendTo( target_stack);
available_stack = document.getElementById('sortable1').childNodes;
for (i=0; i<available_stack.length;i++)
if (available_stack[i].id == dragged_course_id) available_stack[i].parentNode.removeChild(available_stack[i]);
},
out: function(event, ui)
{
$(this)
.removeClass('over_state')
.removeClass('greedy')
}
});
});
This turned out to be fine but then there was this problem of the list itself being dropable. When an item was dropped on the div it drop event would trigger but when the element was dropped on the list itself then both the drop events would trigger, adding the dragged item twice. For that I came up with this cheeky (not particularly beautiful) idea: I remove the last element of the in the receive event of target sortable!
Target Sortable Configuration ##
$( "#sortable2" ).sortable({
greedy: 'true',
connectWith: ".connectedSortable",
cancel: ".ui-state-disabled",
items: "li:not(.ui-state-active)",
receive: function(event,ui)
{
target_stack = document.getElementById('sortable2');
target_stack.removeChild(target_stack.lastChild);
},
dropOnEmpty: false
});
Flexi Comment Box
you just need to re-run the sortable('.myclass')
after you have inserted the new item.
You may need to remove the existing sortable on the existing items.
精彩评论