Draggable elements hang in IE - javascript

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;
}
});
}

Related

Move a div to a drop position

Apologies in advance if I am bad at describing this problem... hope you can still understand it.
Right now I have a Div that has its display set to 'none'.
When I drag and drop a button on the screen, it will then add a class to unhide the div.
Those above work fine, but what I cannot figure out is how to have the div appear exactly at where I dropped the button, rather than always appearing at a fixed location in the middle of the screen (which is what it is doing right now).
Would appreciate any help I can get! Here is the part of the javascript I am using (please let me know if this isn't sufficient info):
$(document).ready(function() {
$('.js-hotspot').draggable({
helper: "clone",
revert: false,
start: function(event, ui) {
console.log("Started");
},
stop: function(event, ui) {
addAnyHotspot();
$( ".hotspot-tooltip" ).addClass( "open" ); //Unhide the div
}
});
});
I managed to solve it. This is my new code:
$(document).ready(function() {
$('.js-hotspot').draggable({
helper: "clone",
revert: false,
start: function(event, ui) {
console.log("Started");
$(document).ready(function() {
$(this).on("drag", function(e) {
var x = e.pageX;
var y = e.pageY;
var el = $("#meh"); //assign #meh to the div that needs to be opened
el.css('position', 'absolute');
el.css("left", x);
el.css("top", y);
console.log("Shifted Position");
})
});
},
stop: function(event, ui) {
addAnyHotspot();
console.log("AddAnyHotSpot");
$( ".hotspot-tooltip" ).addClass( "open" );
}
});
});

"this" not reffering to the selected element

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");
}
});

jQuery UI - drag an item from drop area and drop it back to same drop area - drop event doesn't fired

I have number of drop areas $('.drophere') and a storage of draggables $('.dragme').
Each drop area can contain just one dropped item.
You can drop new item over dropped one (replace). You can drag an item from one drop area to other.
If you start drag an item from drop area and decided drop it back to same area - drop event is not fired, thus the dragged item is lost.
Here is simplified code:
var draggedData;
$('.drophere').droppable({
drop: function (event, ui) {
$(this).attr('data-text', draggedData);
$(this).draggable('enable');
}
}).draggable({
disabled: true,
helper: "clone",
start: function (event, ui) {
draggedData = $(this).attr('data-text');
$(this).attr('data-text', "").draggable('disable');
}
});
$('.dragme').draggable({
helper: "clone",
start: function (event, ui) {
draggedData = $(this).attr('data-text');
}
});
Is it some kind of restriction in jQuery UI droppable? Is any way to "forget" the origins of such dragged item? Thank you.
just added: http://jsfiddle.net/gpnpwwbw/
Taking advantage of jQuery Draggables Stop event I came up with the following solution:
var draggedData,
dropLastDragged
startPosData = {};
function checkIntersect(posData){
var left = startPosData.left,
top = startPosData.top,
right = startPosData.left+startPosData.width,
bottom = startPosData.top+startPosData.height,
cornerLeftPos = posData.left,
cornerTopPos = posData.top;
cornerLeftPos += startPosData.width/2;
cornerTopPos += startPosData.height/2;
if((cornerLeftPos > left && cornerLeftPos < right) && (cornerTopPos > top && cornerTopPos < bottom)){
return true;
}
return false;
}
$('.drophere').droppable({
drop: function (event, ui) {
dropLastDragged = false;
$(this).html(draggedData);
$(this).draggable('enable');
}
}).draggable({
disabled: true,
helper: "clone",
start: function (event, ui) {
startPosData.left = ui.offset.left;
startPosData.width = $(this).width();
startPosData.top = ui.offset.top;
startPosData.height = $(this).height();
draggedData = $(this).html();
$(this).html('Drop here').draggable('disable');
dropLastDragged = this;
},
stop: function(event, ui) {
if(dropLastDragged){
if(checkIntersect(ui.offset)){
$(dropLastDragged).html(ui.helper.html());
$(dropLastDragged).draggable('enable');
}
}
}
});
$('.dragme').draggable({
helper: "clone",
start: function (event, ui) {
draggedData = $(this).html();
}
});
Fiddle

Create Drag & Drop, Destory, Save Re-create - jQuery

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

jQuery Selectable Events

I have a jQuery plugin that drags and drops elements into different containers, I want to attach some events, for example when an element is over a container. These events used to work perfectly but then they stopped working. for Some reason the Selectable specific events are not fired, but when i bind a click for example it works.
Example:
//these are not working
$('#sortable2').bind("sortover", function(event, ui) {
alert("here");
});
$('#sortable2').bind('sortreceive', function() {
alert('User clicked on "sortable2."');
});
$('.droptrue').bind("sortout", function(event, ui) {
$(this).css("background", "transparent");
});
The related code is:
var selectedClass = 'ui-state-highlight',
clickDelay = 300, // click time (milliseconds)
lastClick, diffClick; // timestamps
$("ul.droptrue li")
// Script to deferentiate a click from a mousedown for drag event
.bind('mousedown mouseup', function(e){
if (e.type=="mousedown") {
lastClick = e.timeStamp; // get mousedown time
} else {
diffClick = e.timeStamp - lastClick;
if ( diffClick < clickDelay ) {
// add selected class to group draggable objects
$(this).toggleClass(selectedClass);
}
}
})
.draggable({
revertDuration: 10, // grouped items animate separately, so leave this number low
containment: '.multiSelect',
start: function(e, ui) {
ui.helper.addClass(selectedClass);
},
stop: function(e, ui) {
// reset group positions
$('.' + selectedClass).css({ top:0, left:0 });
},
drag: function(e, ui) {
// set selected group position to main dragged object
// this works because the position is relative to the starting position
$('.' + selectedClass).css({
top : ui.position.top,
left: ui.position.left
});
}
});
$("ul.droptrue")
.sortable()
.droppable({
drop: function(e, ui) {
$('.' + selectedClass)
.appendTo($(this))
.add(ui.draggable) // ui.draggable is appended by the script, so add it after
.removeClass(selectedClass)
.css({ top:0, left:0 });
}
});
$('#total').text(autoCompleteSourceArray.length);
$('#filter-count').text(autoCompleteSourceArray.length);
//Adding Filtering functionality for the lists
$("#filter").keyup(function () {
var filter = $(this).val(), count = 0;
$("ul.droptrue:first li").each(function () {
if ($(this).text().search(new RegExp(filter, "i")) < 0) {
$(this).addClass("hidden");
} else {
$(this).removeClass("hidden");
count++;
}
});
$("#filter-count").text(count);
});
// bind events in order to show or hide the message in the drop zones
$('ul[id^="sortable"]').live("sortover", function(event, ui) {
$(this).css("background", "#f7f6d7");
});
$('ul[id^="sortable"]').live("sortout", function(event, ui) {
$(this).css("background", "transparent");
});
Thanks a lot
If you have recently updated to jQuery 1.7+ you should notice that the live() method is deprecated.
As of jQuery 1.7, the .live() method is deprecated. Use .on() to
attach event handlers. Users of older versions of jQuery should use
.delegate() in preference to .live().

Categories

Resources