I can't figure out how to prevent that draggable objects are added several times in one drag event. I made a small example where you can produce the problem.
https://jsfiddle.net/richiwarmen/afqu96v3/1/
$( ".draggableEl" ).droppable({
accept: ".dropme",
drop: function( event, ui ) {
$(this).append(ui.draggable.clone().css("left","0px"));
}});
$( ".draggableEl" ).draggable();
$( ".dropme" ).draggable({
revert: 'invalid',
helper: "clone" ,
});
drag the purple block in the upper left of the green block, .
You have multiple droppable sibling divs on top of each other. When you drop onto one of them, the ones below it will also activate.
If you made them nested you could use the greedy: true option. But in this case since your divs are all siblings, you can't really do much about it.
Demo - https://jsfiddle.net/Patosai/afqu96v3/2/
See here - Jquery droppable - Greedy not working as expected.
I think you just want to remove the word clone:
$( ".draggableEl" ).droppable({
accept: ".dropme",
drop: function( event, ui ) {
$(this).append(ui.draggable.css("left","0px"));
}});
$( ".draggableEl" ).draggable();
$( ".dropme" ).draggable({
revert: 'invalid',
});
Related
Ok, I haven't been able to work out the solution to this. I found this answer that helps reject drops if there is already a draggable element in the droppable slot, but I haven't been able to make that slot restart accepting children once it has been emptied. Also, it doesn't work for the initial state of the draggable pieces (notice you can stack more than one piece in a slot if it is the initial state of its child).
Here is the link to the project
And here is the specific piece of code:
jQuery(window).on("load",function() //if document has loaded
{
//Code to be executed when the document loads here
$( ".b-piece" ).draggable({ cursor: "move", revert: "invalid"});
$( ".grid-b .grid-slot" ).droppable({
accept: ".b-piece",
drop: function(event, ui) {
$(this).droppable('option', 'accept', 'none'); /* STOP ACCEPTING OBJECTS */
$(this).append(ui.draggable); /* MOVE DRAG OBJECT TO NEW PARENT */
$(this).children(".game-piece").css({"top":"0", "left":"0"}); /* MAKE GAME PIECE SNAP INTO PLACE */
},
out: function(event, ui){
accept: ".b-piece"
}
});
});
Thanks!
To reactivate droppable, you can simply modify the option on draggable start. This will cause a problem with revert, so you should also move the droppable disabling on stop event of draggable. Like this:
$( ".b-piece" ).draggable({
cursor: "move",
revert: "invalid"
start: function(e, ui){
ui.helper.parent().droppable('option','accept','.b-piece');
},
stop: function(e, ui){
ui.helper.parent().droppable('option','accept','none');
}
});
As for initial state, run this after setting the droppable, it should do the trick:
$( ".grid-b:not(:empty) .grid-slot:not(:empty)" ).droppable('option', 'accept', 'none');
I have sortable elements in different sortable groups. I would like to use one element as a tool to add new elements. It should work this way: When a user drags this "add new" element to specific position there should be created new element and dragged one ("add new") should stay on it's previous position.
Do you have any idea if this is possible?
If my understanding is correct, this link may give you some idea of how to do it. Try the demo given on this page.
[link:- http://jqueryui.com/droppable/#revert]
// Here is the code copied from the same page. I have modified it a bit.
$(function() {
// Element which you will drag
$( "#draggable" ).draggable({ revert: "valid" });
// Element to which you will drag the above(draggable) element.
// On 'drop' event of this droppable you can add the element.
$( "#droppable" ).droppable({
activeClass: "ui-state-default",
hoverClass: "ui-state-hover",
drop: function( event, ui ) {
/*Write code for adding new item in the sortable list here*/
}
});
});
I am trying to setup somme kind of drag and drop wysiwyg editor using JQuery UI.
I have succesfully setup the elements but they have a strange behavior.
It is almost impossible to sort items because of the constant flickering.
i setup my draggables like this:
el.draggable({
containement:'.main-form-container',
revert: "invalid",
connectToSortable: '.sortable'
}).disableSelection();
If i dont set it as draggable the sortable will place the placeholder on itself! why?
Sometimes when an element is dropped into another it becomes ONE draggable element and seem tobe glued together. though that seems fixed with overriding sortable update:
update: function (event, ui) {
$(ui.item).css({
position: 'relative',
top:0,
left:0,
width: 'auto'
});
// init droppable draggable and sortable on this item
setupDandD($(ui.item));
}
and the setupDandD method:
setupDandD($('.form-container'));
function setupDandD(el) {
el.draggable({
containement:'.main-form-container',
revert: "invalid",
connectToSortable: '.sortable'
}).disableSelection();
el.droppable({
accept: '[data-section="toolbox"]',
greedy: true,
hoverClass: 'droppable-hovered',
drop: handleDrop
}).disableSelection();
el.filter('.sortable').sortable({
tolerance:'pointer',
containement:'.main-form-container',
connectWith: ".sortable:not(#" + $(this).id + ")",
revert: 'invalid',
helper: function () {
return $(this);
},
update: function (event, ui) {
console.log('here');
$(ui.item).css({
position: 'relative',
top:0,
left:0,
width: 'auto'
});
setupDandD($(ui.item));
}
}).disableSelection();
};
I guess I need to pickup some event somewhere on the sortable but i am quite lost now...
Well well! I found it!
Actually my biggest mistake was to mix droppable and sortable at the same time. I just had to use sortables and draggables with the connectToSortable option set.
The other weird behavior I had was the sortable trying to insert into itself. This is because sortable "connectWith" was set to a selector that returned self and therefor it instantly placed the placeholder on self when dragged. Quite logical actually!
To overcome this I just surrounded each child sortable with a div. It makes the div a sortable item and prevents triggering the events on self.
One thing to take into consideration when using draggable+sortable is that the sortable will always clone the object as it was when drag started. Meaning that even if you use a custom helper on the draggable, it will still insert the original item. For this I had to replace the item in the "stop" event of the sortable by the one i wanted if it came from my toolbox:
$('.main-form-container').sortable({
placeholder: "sortable-placeholder",
opacity: .35,
connectWith: ".sortable",
stop: function (e, t) {
if (t.item.attr('data-section') == "toolbox") {
$(t.item).replaceWith(createContainer());
}
$(".sortable").sortable({
opacity: .35,
placeholder: "sortable-placeholder",
connectWith: ".sortable"
}).disableSelection();
}
}).disableSelection();
and here is the working fiddle: http://jsfiddle.net/jmorvan/ag659/
I realize there is probably a cleaner way of doing this last fix by overriding some maybe undocumented event in sortable/draggable, but that did the trick for me!
what I want to do is to know where (not in terms of position (x, y), but a reference to the DOM element) an object was dropped.
I have a grid made up with divs where you can drop various items and I need to know which div on the grid was the item dropped on (getting its id would be fine). The callback function
function(event, ui) { //code here }
has just that ui object who doesn't apparently contain any information about this, but only about the draggable item or its helper.
What you need to use is the jQuery Droppable class, which you can read about in the jQuery docs.
Basically, for every element that you wish to be able to drop a draggable element on, you create a Droppable object, which will trigger once another object is dragged onto it. This is the example from the jQuery docs:
$(function() {
$( "#draggable" ).draggable();
$( "#droppable" ).droppable({
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
});
The $(this) in that example is the element you are looking for.
Is there any way of dropping a draggable into the droppable by hardcoding and not by actually going into the browser and doing drag-drop??
Thanks in advance.:D
I don't know if I have understood very clearly, in any case I think it is curious perspective,if you mean to animate and do the same things if we have dragged a layer into a droppable layer.
I suppose you could do it like this:
http://www.jsfiddle.net/dactivo/QLTUS/
You use animate() to move the layer to the droppable, and then in the complete function, you imitate what normally happens in a dropping action, that is to say change the class, and there you can include whatever.
I mean it is not important the drop event, but what you execute in the drop event, that can be included in your complete event of the animation. I have encapsulated this in a function called layerDrop().
$(function() {
$( "#draggable" ).draggable();
$( "#droppable" ).droppable({
drop: function( event, ui ) {
layerDrop();
}
});
$("#btnMove").click(function()
{
$("#draggable").animate({"left": $( "#droppable" ).offset().left ,"top": $( "#droppable" ).offset().top},
{
duration: 1000, specialEasing: { width: 'linear' },
complete:function()
{
$("#message").html("Completed!");
layerDrop();
//whatever
}
}
);
});
function layerDrop(){
$( "#droppable")
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
I think you mean to position a dragged option programmatically. If that is the case then look in the official jQuery draggable documentation: http://docs.jquery.com/UI/API/1.8/Draggable
It seems the short answer is:
To manipulate the position of a draggable during drag, you can either use a wrapper as the draggable helper and position the wrapped element with absolute positioning, or you can correct internal values like so:
$(this).data('draggable').offset.click.top -= x