I am trying to drag and drop elements to a div from another div through jQuery. I am adding the clone but not the actual element I have dragged to the droppable div.
I have then added the original element which I have dragged to the source div. Also, I have added the class "clone" to the clone element.
The problem is when I drag and drop the element in the droppable div(which is actually a clone), the element is copied and added to the droppable div but at the wrong position.
$("#drop").droppable({ accept: ".draggable",
drop: function(event, ui) {
var droppable = $(this);
console.log("drop");
$(this).removeClass("border").removeClass("over");
var dropped = ui.draggable;
var droppedOn = $(this);
console.log($(this).attr('class'));
if(!($(this).hasClass("clone"))) {
console.log("no clone");
$(dropped).detach().css({top: 0,left: 0}).appendTo("#origin");
var clone = dropped.clone().addClass("clone");
clone.appendTo(droppedOn);
}
},
I then found out that the "this" I was referring to is not updating correctly and I am very confused at this point.
I am a noob and I can't think of the solution.
Here is the pen:
https://codepen.io/ishankgupta95/pen/rZyOYb
The problem with your code is that your $(this) is pointing your div id="box" rather than the individual cloned div or images. so $(this) will never have a class named clone.
Here, solved it replace this in your code, Issue is fixed.
$("#drop").droppable({ accept: ".draggable",
drop: function(event, ui) {
var check = 0;
// $( "#test" ).droppable( "dragstart", function( event, ui ) {check = 1;} );
var x = event.clientX, y = event.clientY,
elementMouseIsOver = document.elementFromPoint(x, y);
var droppable = $(this);
console.log("drop");
$(this).removeClass("border").removeClass("over");
var dropped = ui.draggable;
var droppedOn = $(this);
console.log($(this).attr('class'));
if(!elementMouseIsOver.classList.contains("clone")) {
console.log("no clone");
$(dropped).detach().css({top: 0,left: 0}).appendTo("#origin");
// dropped.clone().appendTo(droppedOn);
var clone = dropped.clone().addClass("clone");
clone[0].id = 'test';
clone.appendTo(droppedOn);
}
},
over: function(event, elem) {
$(this).addClass("over");
console.log("over");
},
out: function(event, elem) {
$(this).removeClass("over");
}
});
Related
I would appreciate if someone can help me out,
here's my code :
`https://jsfiddle.net/m796a3ud/`
What I want to do is drag an image from these list of Images and be able to get a clone that's draggable, and when I put it inside the box it counts how many images are inside, it works good for the most part but when I try to drag the cloned image in and out of the box a couple of times the clone gets cloned it self which is not what I want, I would really appreciate the help!
thanks.
You have to call ui.helper.remove(); on the out event, try this:
$(function() {
// document.addEventListener('mousemove', function(event) {
// console.log($(':hover').hasClass('draggable'))
// })
var n = 0;
$( ".draggable" ).draggable({helper: 'clone'});
$( ".wrong" ).draggable();
$( "#droppable" ).droppable({
accept: ".draggable",
drop: function( event, ui) {
console.log(ui.draggable)
console.log($(':hover').hasClass('draggable'))
var new_signature = $(ui.helper).clone().removeClass('draggable');
new_signature.draggable();
$(this).append(new_signature);
if($(new_signature).hasClass("ui-draggable") && !$(new_signature).hasClass("dropped")){
$(new_signature).addClass("dropped draggable")
n++;
$(".count").text("There are " + n + " divs inside parent box detail.");
}
},
out: function(event, ui) {
ui.helper.remove();
if($(ui.draggable).hasClass("draggable") && $(ui.draggable).hasClass("dropped")) {
$(ui.draggable).removeClass("dropped")
console.log(ui.helper)
}
if( n > 0) {
n--
}
$(".count").text("There are " + n + " divs inside parent box detail.");
}
});
});
Ok, I have an issue with drag and drop.
What they do, they click a button, it initializes the whole drag and drop.
function sortElements() {
// Place droppable elements
var x = 0;
$("#content-body div[data-type='column'],#content-body div[data-type='carousel']").each(function() {
var el = $(this);
if(x == 0){
el.before('<div class="neoDroppableEle" id="neoDroppableEle-' + x + '"><\/div>');
x++;
}
el.addClass('edit_el').after('<div class="neoDroppableEle" id="neoDroppableEle-' + x + '"><\/div>');
x++;
el.append('<div class="drag-handle"><i class="fa fa-arrows"></i></div>');
var w = el.width();
el.css('width',w+'px');
});
$("#content-body div[data-type='insertable']").each(function() {
var el = $(this);
el.prepend('<div class="neoDroppableEle" id="neoDroppableEle-' + x + '"><\/div>');
x++;
});
// Swap entire columns
$("#content-body div[data-type='column']").draggable({
refreshPositions: true,
helper: "clone",
handle:'.drag-handle',
appendTo: "body",
zIndex: 10000,
start: function( event, ui ) {
$(".neoDroppableEle").addClass('dragging');
},
stop: function( event, ui ) {
$(".neoDroppableEle").removeClass('dragging');
}
});
$(".neoDroppableEle").droppable({
accept: "div[data-type='column']",
tolerance: "pointer",
hoverClass: "focus_in",
activeClass: "focus_in_active",
drop: function(event, ui) {
cur_ele = this.id;
var el = ui.draggable;
var html = el.html();
el.remove();
$("#" + cur_ele).replaceWith('<div class="row" data-type="column">'+html+'</div>');
}
});
// Swap individual photos within columns
$("#content-body div[data-type='imagewrap']").each(function(){
$(this).draggable({
revert: "invalid",
helper: "clone" ,
zIndex: 10001,
});
$(this).droppable({
accept: "div[data-type='imagewrap']",
activeClass: "ui-state-hover",
hoverClass: "ui-state-active",
drop: function( event, ui ) {
var draggable = ui.draggable, droppable = $(this);
draggable.swap(droppable);
}
});
});
}
When they are done, they click the button again.
function sortElementsComplete() {
$(".ui-droppable").droppable("destroy");
$(".ui-draggable").draggable("destroy");
$(".edit_el").removeAttr('style').removeClass('edit_el');
$(".neoDroppableEle").remove();
$(".drag-handle").remove();
}
This all runs and works great!
But now I am tryng to save the HTML code after each drop for undo's. And when I save the undo, I need to remove all additional classes and elements my function to drag and drop add's. Because they may not be in the sorting area when they click undo and do not want drag handles and my borders I set up as visual aids just appearing.
So now I have:
$(".neoDroppableEle").droppable({
accept: "div[data-type='column']",
tolerance: "pointer",
hoverClass: "focus_in",
activeClass: "focus_in_active",
drop: function(event, ui) {
cur_ele = this.id;
var el = ui.draggable;
var html = el.html();
el.remove();
$("#" + cur_ele).replaceWith('<div class="row" data-type="column">'+html+'</div>');
setTimeout(function(){
sortElementsComplete();
editor_add();
},1000);
}
});
The above with the timeout code always fails with:
Error: cannot call methods on droppable prior to initialization;
attempted to call method 'destroy'
How so? It IS initialized and running. After the drop I should be able to destroy it, make my save and rebuild it. Using disable gives the same error. To me the error makes no sense.
After editor_add() is ran, it re-builds whatever they were doing, in this case it will fire sortElements(); after the save.
But the below runs fine?
// Swap individual photos within columns
$(this).droppable({
accept: "div[data-type='imagewrap']",
activeClass: "ui-state-hover",
hoverClass: "ui-state-active",
drop: function( event, ui ) {
var draggable = ui.draggable, droppable = $(this);
draggable.swap(droppable);
setTimeout(function(){
sortElementsComplete();
editor_add();
},250);
}
});
It will error if I do not have the timeout above. Seems 250 is the min, anything lower it errors. But the first one will not ever work, no matter how long or short I make the timeout.
Really hope this makes sense.
Maybe if I used
var draggable = ui.draggable, droppable = $(this);
draggable.swap(droppable);
On it instead it would work. o.O
I have been trying to clone and drop a draggable at the position in a droppable at the coordinates where the drop happens. I have found examples online that deal with appending draggables to droppables, but they all seem to move the draggable to a specific part of the droppable on the initial drop.
Here is an example that does just that: - http://jsfiddle.net/scaillerie/njYqA/
//JavaScript from the jsfiddle
jQuery(function() {
jQuery(".component").draggable({
// use a helper-clone that is append to 'body' so is not 'contained' by a pane
helper: function() {
return jQuery(this).clone().appendTo('body').css({
'zIndex': 5
});
},
cursor: 'move',
containment: "document"
});
jQuery('.ui-layout-center').droppable({
activeClass: 'ui-state-hover',
accept: '.component',
drop: function(event, ui) {
if (!ui.draggable.hasClass("dropped"))
jQuery(this).append(jQuery(ui.draggable).clone().addClass("dropped").draggable());
}
});
});
Is there anyway I can make the draggable stay at the coordinates where the drop occured?
you must define the coordinates in the cloned element on the drop:
drop: function(event, ui) {
if (!ui.draggable.hasClass("dropped"))
var clone=jQuery(ui.draggable).clone().addClass("dropped").draggable();
clone.css('left',ui.position.left);
clone.css('top',ui.position.top);
jQuery(this).append(clone);
}
});
and also set the position absolute by css on the cloned components
.ui-layout-center .component {
position:absolute !important;
}
Here is working: http://jsfiddle.net/o2epq7p2/
Edited you code and used appendTo() and set the offset
jQuery(function() {
jQuery(".component").draggable({
// use a helper-clone that is append to 'body' so is not 'contained' by a pane
helper: function() {
return jQuery(this).clone().appendTo('body').css({
'zIndex': 5
});
},
cursor: 'move',
containment: "document"
});
jQuery('.ui-layout-center').droppable({
activeClass: 'ui-state-hover',
accept: '.component',
drop: function(event, ui) {
var _this = jQuery(this);
if (!ui.draggable.hasClass("dropped")) {
var cloned = jQuery(ui.draggable).clone().addClass("dropped").draggable();
jQuery(cloned).appendTo(this).offset({
top : ui.offset.top,
left: ui.offset.left
});
}
}
});
});
ui in the drop handler contains the dragged element's position absolute to the page. You need to transform those values to a position relative to the drop target and absolute position the cloned element inside the drop target using these values.
drop: function(e, ui) {
if (!ui.draggable.hasClass("dropped")) {
var parentOffset = jQuery('.ui-layout-center').offset();
var dropped = jQuery(ui.draggable).clone().addClass("dropped").draggable();
dropped.css('left', (ui.position.left - parentOffset.left) +'px');
dropped.css('top', (ui.position.top - parentOffset.top) +'px');
jQuery(this).append(dropped);
}
}
http://jsfiddle.net/3Lnqocf3/
I've got a bug from testers when they double clicked on element or something like then dragged it to the bottom of page,even if draggable element has containment set,mouse goes down than the element. After that you can release mouse click and draggable element hang on mouse pointer. Only in IE :( has anyone any ideea why or how to stop this?
My code looks like :
EDIT: http://jsfiddle.net/j2GyK/
function dragNdrop(){
for(var i = 0; i < 3; i++){
dragObjects.push(document.getElementById("box" + i));
$(dragObjects[i]).css( 'cursor', 'pointer' );
$(dragObjects[i]).draggable({
containment:'#decor',
zIndex: 1000,
revert: true,
start: function(event, ui) {
dragTarget = event.currentTarget; // luam date despre obiectul curent tras
}
});
}
$("#drop").droppable({
drop: function( event, ui )
{
dropTarget = event.target; // luam date despre drop target
$(dropTarget).prop('src', dragTarget.src);
$(dragObjects).css("visibility", "visible");
$(dragTarget).css("visibility", "hidden");
thisSRC = dropTarget.src.charAt(dropTarget.src.length-5);
checkBtn.disabled = false;
}
});
}
I have a function called saveSmilies which accepts two parameters: the dragged element id and the dropped element id.
I'm trying to do this like:
$('.draggable').draggable({
revert: true,
drop: function() {
$dropped = $(this);
},
stop: function() {
quiz1.saveSmilies($(this).attr('id'), $dropped);
}
});
But it doesn't work... Am I doing this completely wrong? Or just a typo somewhere?
So basically If I dragged an element with an id of 'box1' and dropped it on an element with an id of 'box2' then it would do the following: quiz1.saveSmilies('box1','box2');
This should work:
drop: function(ev, ui) {
var draggedID = ui.draggable.attr("id");
var droppedID = $(this).attr("id");
}