I have an ul of draggable items (#doc-editor-options ul li), an area for dropping those items (#doc-editor-content) and an ul within that area for holding those items (#items-holder), which is sortable. This dragging and dropping is only one-way, only items from the list can be dragged and dropped into the holder.
$("#doc-editor-options ul li").draggable({
helper: 'clone',
connectToSortable: '#item-holder',
containment: $(".doc-editor")
});
$("#doc-editor-content").droppable({
drop: function(e, ui){
console.log('dropped');
}
});
$("#item-holder").sortable({
placeholder: 'placeholder-highlight',
cursor: 'pointer',
});
Two questions that I have:
Right now when I drag an item from the list and drop it into the other list, the drop callback for .droppable() is called twice. I think this has something to do with the #item-holder being sortable. I want it to only be fired when I drop an item into the list and only know about that item's event and ui in the callback.
I also need the functionality where by default, the items-holder is not sortable. The only time it becomes sortable is when you are dragging and hovering an item over it. So I can't sort the list by default, but if I drag an item over to it, I can choose where to place that item in the list (i.e. the list is now sortable) and once I drop it, the list becomes unsortable again.
EDIT: I figured out #2, I needed to bind mousedown to the draggable items which enables sorting then disables it on mouseup. Still having problems with #1, it seems like some of the sortable events are firing the drop callback when I drop an item in or I hover out of the item holder.
1:
Your drop() gets called twice because connectToSortable is also triggering a drop().
My suggestion would be to delete $("#doc-editor-content").droppable() altogether, and instead add the receive(e, ui) handler to your sortable.
2:
Your fix works. However I would suggest a much easier alternative: leave the sortable always enabled and add the option "handle: h2". (Pick any tag that will not exist within your LIs.) This will let you drop into the list, but disable user sorting in-place.
Example:
$('#item-holder').sortable({
placeholder: 'placeholder-highlight',
cursor: 'pointer',
handle: 'h2',
receive: function(e, ui) {
console.log('dropped');
}
});
Related
I have a sortable and droppable list, and also a separate set of draggables:
ul.sortable
li.droppable
li.droppable
li.droppable
/ul
ul
li.draggable
li.draggable
li.draggable
/ul
I apply a hover class on the droppables:
$(".droppable").droppable({ hoverClass: "hover" });
The hover is supposed to be a visual cue for the user, telling him that a draggable can be dropped onto a droppable.
The problem is that the hover class is also applied when a droppable is hovered by a sortable element as well. The visual cue is, in this case, totally wrong.
Here's a fiddle illustrating the issue (drag the draggables over the sortables, reorder the sortables): http://jsfiddle.net/TWXeH/
How do I make the hover class work only when there's a draggable over a droppable, but not with sortables?
You're looking for the accept option
$(".droppable").droppable({
hoverClass: "hover",
accept: ".draggable"
});
I've read everything similar to my problem posted here but not found any solution.
I have created a menu with sub menu entries inside dropdowns. All menu entries are sortable to all menu levels. root menu entries to child lists and the other way.
Nearly everything works fine but sorting to the first dropdown results a bug. It is neighter not possible to sort a menu entry before the first dropdown nor to sort inside the first dropdown. By trying to sort inside the first dropdown the placeholder code spawn inside the neighbor (last) dropdown and on stop sorting the entry also is inside the last dropdown and not inside the first like it should. Sorting to the other dropdowns does not have this behavior. Maybe anybody has an idea about it?
Here is the js-fiddle:
http://jsfiddle.net/dehil/Vy4pu/1/
$('ul').sortable({ //
connectWith: $('ul'),
items: 'li',
placeholder: 'pf_sortable-placeholder',
tolerance: 'pointer',
cursor: 'pointer',
cursorAt: {
top: -20
},
zIndex: 20000,
placeholder: 'pf_sortable-placeholder',
})
Nested lists are always a bit awkward with jQuery UI. Recently I found http://johnny.github.com/jquery-sortable/ which may be used to sort bootstrap navs.
See http://johnny.github.com/jquery-sortable/#bootstrap.
I have a list of elements that are sortable and sort fine. I also have a droppable that resides outside of the sortable list. When I drop items on the droppable, it is intended to perform a copy operation, meaning that sorting during this operation is not desirable.
Unfortunately however, dragging a sortable to an external droppable causes sortable.update to fire. Is there a way to have all sortable drag/drop events ignored if a sortable is dragged outside of a given element?
I've gone through all the relevant sortable events, and I can't seem to find any reference to the element the sortable was dropped on, in order to see if they have common parents.
Here's a fiddle to demonstrate: http://jsfiddle.net/6yhbG/
Dragging either sortable 1/2 to the droppable causes the sortable.sort to fire.
OK finally got to the bottom of it: sortable('cancel') needs to be called from sortable.stop and I'm simply adding a class to the sortable so it knows whether to cancel itself or not:
$('div').droppable({
drop: function(e, ui) {
ui.draggable.parent().addClass('dropped');
}
});
$('ul').sortable({
stop: function(){
if ($(this).hasClass('dropped')){
$(this).sortable('cancel');
$(this).removeClass('dropped');
}
}
});
With my updated example at: http://jsfiddle.net/6yhbG/1/
I'm using jQuery to create a droppable element - this appears to work fine, as the element gets the class ui-droppable.
I've set it up like this:
$('#trashcan').droppable({
drop: function( event, ui ) {
alert('Dropped');
}
});
where #trashcan is an image.
Later, in response to a user action, I set up some draggables. These are table rows, and I set them up like this ('element' is just the created table row):
$(element).draggable({
revert: false,
helper: 'clone',
intersect: 'pointer',
stop: function() {
alert('dropped');
}});
Afterwards, they look like this:
<tr class="ui-draggable">
<td>First</td>
<td>Name</td>
</tr>
So it all looks like it's set up ok. However, when I drag a table row over the trashcan, I get the 'dropped' from the draggable code, but not from the droppable. So the draggable has been dragged, but the droppable hasn't recognised it.
I'm not sure what to check for here. Is there any reason why it wouldn't work on table rows, for instance? I've checked things like z-index, and that doesn't appear to be the issue. Do I have to do something special to connect the draggable and droppable after the draggables are created (i.e. something that gets done when the droppable is created, which I need to re-do because the draggables are created later)?
I'm creating a sortable tab in jQuery UI but I want to lock the last tab. I already panned it to the right, but it can still be sorted. What do I need to do to lock the last added tab?
Officially, you can specify on the sortable which sub-items you want to be sortable, just set the property items to a selector.
While it disables sorting when moving the other tabs (meaning the disabled tab never moves), it can still be dragged. To work around this issue, just bind a function to the item's mousedown event and call stopPropagation() to prevent the drag.
See this jsfiddle example: http://jsfiddle.net/wZ4c6/1/
$('#tabs').tabs().find('.ui-tabs-nav').sortable({
axis: 'x',
items: '> li:not(.locked)' //This will prevent sortables to move around the locked item
});
$('button').button().click(function(){
// Lock last tab
$('#tabs > ul > li:last').addClass('locked').mousedown(function(event){
event.stopPropagation();
});
// Refresh sortable items
$('#tabs').find('.ui-tabs-nav').sortable('refresh');
});