Jquery Drag and Drop without plugins - javascript

I have tried to create a drag and drop plugin using JQuery.
$('.draggable').on{
mousemove : function(){
var mouseposition = { // this also needs to account for onclick offset of pointer vis-a-vis element
x : pageX,
y : pageY
};
$(this).css({
top : mouseposition.y,
left : mouseposition.y
});
if( // this statement is kinda bogus, idea is to perform a collision detection via coordinate comparison
$('.draggable').offset().top < $(.droppable').offset().top
&&
$('.draggable').offset().left < $(.droppable').offset().left
) {
alert('the item has been dropped');
}
}
});
Here is the demo link what I have tried.

I have reworked your code, and updated the fiddle.
http://jsfiddle.net/XTMK8/2/
var dragging = undefined;
$('.draggable').on('mousedown', function(){
dragging = $(this);
});
$('body').on('mousemove', function(e){
if(typeof dragging != "undefined") {
dragging.css({
top : e.pageY - 50,
left : e.pageX - 50
});
}
});
$('body').on('mouseup', function(){
dragging = undefined;
});
Collision Detection
I would then recommend using the following snippet to handle collision:
jQuery/JavaScript collision detection

I'm assuming this must be an academic task or you want to do it for learning purposes (otherwise, why someone wouldn't want to use JQuery UI's draggable?) but anyway, the link below should guide in the right direction: http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/
If you still want to know what's wrong with your code, I recommend starting over and add bit by bit to try to achieve the basic functionalities before coming up with a draggable and droppable at once, e.g., your mousemove function seems different from the one in JQuery's doc, I believe that, in order to retrieve pageX and pageY, you need the event object within the function's parameters:
$("#target").mousemove(function(event) {
var msg = "Handler for .mousemove() called at ";
msg += event.pageX + ", " + event.pageY;
$("#log").append("<div>" + msg + "</div>");
});
Try to set some breakpoints using Firebug and see if all variables are being populated accordingly.
I hope that helps, cheers!

Related

After dragging I get incorrect coordinates of all the elements but the first

There are some div elements on my page. A user can drag any of them many times. After every dragging, I need to get new coordinates of the div that was dragged.
My code works good with div[0]: I actually get new coordinates after every new dragging.
The problem is with all the other divs, like div[1], div[2], div[10]... Script gets coordinates after the first dragging, but all the next times coordinates are still the same. They don't change.
I tried to clear variables, but that didn't help.
What could be this problem caused by? What should I check to find the solution?
I use jQuery and jQuery UI. Code:
$(document).ready(function(){
$(".rD").draggable({
stop: function(event, ui) {
// get the index of the dragged element
id = $(this).index();
// get coordinates of the dragged element
rect = document.getElementsByTagName("div")[id].getBoundingClientRect();
alert("top:" + rect.top + ", left: " + rect.left);
// clearing variables didn't help to solve the problem
delete rect;
delete id;
}
});
Try to:
alert(ui.position.top, ui.position.left)
Documentation
Whole code:
$(document).ready(function(){
$(".rD").draggable({
stop: function(event, ui) {
// Use var keyword for your local variables
// var rect = ui.helper[0].getBoundingClientRect();
alert("top:" + ui.position.top + ", left: " + ui.position.left);
}
});
});

HTML5 draggable's drop event not getting triggered intermittently due to DOM manipulation in dragover event

I am using html5 'draggable' attribute to drag 2 elements within a container and svg line to connect the two.
Once connected, Dragging the first Div should redraw the connecting svg line (i do on dragover event by calling 'handleDragOver' function). But If you drag the first div faster, drop event is not triggered and the div maintains it's original place while the line gets drawn.
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
//Some code doing DOM computation and manipulation
}
return false;
//e.dataTransfer.dropEffect = 'move';
}
How can I ensure that drop event gets triggered every time.
Please note:
I can't use any framework, just plain javascript
I can't not redraw line while dragging.
drag functionality works fine when I'm not doing any computation/redrawing in 'handleDragOver'
Here is the code: http://jsfiddle.net/bhuwanbhasker/3yx9ds4m/1/
Please take a look on the updated fiddle: http://jsfiddle.net/sejoker/d4vs9fgs/1/
following changes:
line manipulation moved from dragover's handler to handleDrop, redraw line once during drag'n'drop operation
calling moveLine in setTimeout seems to improve usability (optional)
minor changes in moveLine function to connect draggable elements properly (optional)
function handleDrop(e) {
console.log('enter Drop');
if (e.stopPropagation) {
e.stopPropagation(); // stops the browser from redirecting.
}
var offset = e.dataTransfer.getData('Text').split(',');
dragSrcEl.style.left = (e.clientX + parseInt(offset[0], 10)) + 'px';
dragSrcEl.style.top = (e.clientY + parseInt(offset[1], 10)) + 'px';
setTimeout(function(){
var elem = svgLine.aLine;
if (elem !== null) {
var x = e.clientX - svgLine.left,
y = e.clientY - svgLine.top;
moveLine(x, y, elem, offset[2]);
}
}, 50)

What is the best method to trigger a mouse indicator using synthetic events?

I have some charts with a mouse indicators attached. I want to activate the indicator via events from other places in my app on a certain location in the data.
My basic approach so far has been to change some of the values in another event object, and then pass it to the onMouseMove() method in all of my indicators like so:
funct.forEach(registry.byClass("graph"), function (item) {
on(item, "mouseover", function (e) {
funct.forEach(registry.byClass("indicator"), function (indicator) {
var position = domGeom.position(indicator.chart.node, false);
e.pageX = e.clientX;
e.pageY = position.y - 10;
indicator.onMouseMove(e);
});
});
});
The onMouseMove() method is found in the path dojox/charting/action2d/MouseIndicator.js, and looks like looks like:
onMouseMove: function(event){
if(this._isMouseDown || this.opt.mouseOver){
this._onMouseSingle(event);
}
},
_onMouseSingle: function(event){
var plot = this.chart.getPlot(this._uName);
plot.pageCoord = {x: event.pageX, y: event.pageY};
plot.dirty = true;
this.chart.render();
eventUtil.stop(event);
},
This works, but is a disgusting hack because I don't know what would happen if e changed, or if there are side effects that are not being processed by directly calling onMouseMove(). Is there a more uniform and correct way to accomplish what I am trying to accomplish?
This is on dojo 1.10

changing button order in js

I have a series of buttons of fixed height and width, those need to be draggable and droppable anywhere inside the parent div.
As per client request, I cannot use any external libraries, meh... I could have done this with jQuery in seconds but, I guess this is one of its drawbacks: you don't get to learn more basic stuff...
How would I go about doing it? A problem with this is that those buttons are inside a div that is also draggable so I need to be careful about positioning, I can only probably use relative.
Any ideas how I can go about doing it? Thanks in advance.
Peter-Paul Koch wrote an excellent how-to on drag and drop. I only remembered this 3/4 of the way through writing my own, so I wrapped that up in a fiddle.
function makeDraggable(draggable, container){
// In case you don't want to have a container
var container = container || window;
// So we know what to do on mouseup:
// At this point we're not sure the user wants to drag
var dragging = false;
// The movement listener and position modifier
function dragHandler(moveEvent){
moveEvent.preventDefault();
dragging = true;
// Ascertain where the mouse is
var coordinates = [
moveEvent.clientX,
moveEvent.clientY
];
// Style properties we need to apply to the element
var styleValues = {
position : 'absolute',
left : coordinates[0] + 'px',
top : coordinates[1] + 'px'
};
// Apply said styles
for(property in styleValues){
if(styleValues.hasOwnProperty(property)){
draggable.style[property] = styleValues[property];
}
}
}
function dropHandler(upEvent){
// Only interfere if we've had a drag event
if(dragging === true){
// We don't want the button click event to fire!
upEvent.preventDefault();
// We don't want to listen for drag and drop until this is clicked again
container.removeEventListener('mousemove', dragHandler, false);
draggable.removeEventListener('mouseup', dropHandler, false);
dragging = false;
}
}
// Where all the fun happens
draggable.addEventListener('mousedown', function dragListener(downEvent){
downEvent.preventDefault();
// The drag event
container.addEventListener('mousemove', dragHandler, false);
// The end of drag, if dragging occurred
draggable.addEventListener('mouseup', dropHandler, false);
}, false);
}​

Handle feature on Drag and Drop, not working

I'm creating a Drag and Drop plugin.
Right now i'm trying to create as many as features as possible. My current goal is to get my handle feature to work.
This is the code i'm using:
$(o.handle).mousedown(function (event) {
down = true;
if (o.activeClass === true) {
$(oj).addClass(o.activeClass);
}
var dx = event.clientX - $(o.handle).position().left,
dy = event.clientY - $(o.handle).position().top;
$(o.handle).mousemove(function (event) {
if (down == true) {
if (o.dragClass === true) {
$(oj).addClass(o.dragClass);
}
$(oj).css({
cursor: 'move',
left: event.clientX - dx,
top: event.clientY - dy
});
}
});
});
About the Code. oj is referring to this. this is the element that is being dragged by the handle.
o.handle is referring to the element of the handle. The o in o.handle is referring to:
var o = $.extend(defaults, options);
Problem: The First time I try to click on o.handle. The element jumps to: top:0px;left:0px;. Then it drags fine. But then once I drop it and then pick up the element and try to drag it again. It jumps to: top:0px;left:1px;. This happens over and over, non stop. I don't why though. You can see the problem here. Do you see an error in my code?
Thanks for any help

Categories