creating multiple custom divs jquery - javascript

I am building a tool where multiple boxes (divs, in this case) can be drawn by clicking and dragging the mouse. I want a new div to be drawn each time the function is called. But with what i have now, i am unable to make the height and width of the div follow the mouse's movement.
Here is my code:
$('#work_area').click(function(e) {
var increment = increment + 1; //has been defined in the global scope
var newBox = 'newBox' + increment;
var workAreaOffset = $('#work_area').offset();
if (ctr == 0) {
var clickLocX = e.pageX; //x coordinate of origin of select box
var clickLocY = e.pageY; //y coordinate of origin of select box
$('<div>').attr({
'class':'newBox',
zIndex:'15'
})
.addClass(newBox) //set new class for every box
.css({
top:clickLocY - workAreaOffset.top,
left:clickLocX - workAreaOffset.left
})
.appendTo('#work_area');
ctr = 1; //next stage of select box method reached
if (ctr == 1) {
$('#work_area').mousemove(function(e){
var XpageCoord = e.pageX;
var YpageCoord = e.pageY;
var boxHeight = YpageCoord - clickLocY; //height of the box changes with mouse movement
var boxWidth = XpageCoord - clickLocX; //width of the box changes with mouse movement
$(newBox).css({
height:boxHeight + 'px', //connect mouse movement with css class for select box
width:boxWidth + 'px'
});
ctr = 2; //next stage of the select box method reached
});
}
}
else if (ctr == 2) {
//$('.newBox').remove(); //select box removed with second click
$('#work_area').css({
cursor: 'default' //cursor changed back to normal
});
$('#work_area').unbind('mousemove'); //mouse movement no longer has effect
$(newBox).appendTo('#work_area');
ctr = 0; //reset
}
else {
$.noop(); //fall back
}
});
Please help?

That was REALLY close to working. The code below will work.
The primary issue is that $(newBox) is not returning anything, because variable newBox is not a well formed jQuery selector. And that's fine, because you're using newBox to return a unique class for each box. All you have to do is modify the two spots where you have $(newBox) to be
$('.' + newBox)
A couple of other questions and pointers:
Why do you have the line
var increment = increment + 1; ?
this declares increment to be a local variable, so it returns 'NaN'
Also, the drag and drop blocks only work if the mouse goes from top left to bottom right.
Anyway, best of luck.
$('#work_area').click(function(e) {
increment = increment + 1; //has been defined in the global scope
var newBox = 'newBox' + increment;
var workAreaOffset = $('#work_area').offset();
if (ctr == 0) {
var clickLocX = e.pageX; //x coordinate of origin of select box
var clickLocY = e.pageY; //y coordinate of origin of select box
$('<div>').attr({
'class':'newBox',
zIndex:'15'
})
.addClass(newBox) //set new class for every box
.css({
top:clickLocY - workAreaOffset.top,
left:clickLocX - workAreaOffset.left
})
.appendTo('#work_area');
ctr = 1; //next stage of select box method reached
if (ctr == 1) {
$('#work_area').mousemove(function(e){
var XpageCoord = e.pageX;
var YpageCoord = e.pageY;
var boxHeight = YpageCoord - clickLocY; //height of the box changes with mouse movement
var boxWidth = XpageCoord - clickLocX; //width of the box changes with mouse movement
$('.' + newBox).css({
height:boxHeight + 'px', //connect mouse movement with css class for select box
width:boxWidth + 'px'
});
ctr = 2; //next stage of the select box method reached
});
}
}
else if (ctr == 2) {
//$('.newBox').remove(); //select box removed with second click
$('#work_area').css({
cursor: 'default' //cursor changed back to normal
});
$('#work_area').unbind('mousemove'); //mouse movement no longer has effect
$('.' + newBox).appendTo('#work_area');
ctr = 0; //reset
}
else {
$.noop(); //fall back
}
});

Related

How do I calculate and determine the area at which the div must be dropped?

I am building a drag and drop application purely in Javascript. I have coded the drag part where the element can be dragged and dropped randomly in the page. Now, I have built a drop zone that contains 9 boxes(divs) wherein 9 divs must be dropped. I can't think of an approach that will help me accomplish this task. I am thinking of making those divs 'absolute' and re-build them use top & left attributes. But how should I proceed further? How will the div that I drag i.e onmousedown will come to know that onmouseup it should drop at the specified location. Example: If I select a div numbered 1, it should drop at target numbered 1.
Here's the Javascript I am using for selecting and dragging:
window.onload = function() {
var el = document.getElementById('block1');
var mover = false, x, y, posx, posy, first = true;
el.onmousedown = function() {
mover = true;
};
el.onmouseup = function() {
mover = false;
first = true;
};
el.onmousemove = function(e) {
if (mover) {
if (first) {
x = e.offsetX;
y = e.offsetY;
first = false;
}
posx = e.pageX - x;
posy = e.pageY - y;
this.style.left = posx + 'px';
this.style.top = posy + 'px';
}
};
};
I would have the targets recognize a "onmouseenter" and set a Boolean to be true for that target, then set it to false "onmouseleave". then "onmouseup" check all of the booleans and if div1 has been dropped and target1 is true then div1 position = target position.
I know this is a pseudo code answer but its just my thought process on ho to solve the problem.

How to drag an element using javascript?

I'm working on a project which needs pictures to be draggable across the page. I found jQuery UI to be a very useful solution which is working as expected but sadly I cannot use it in the project. Instead, I needed to do it using pure javascript only. With some googling, I came up with this: http://jsfiddle.net/tovic/Xcb8d/light/
This was perfect, the only problem with it was that it was using IDs which means I can't have multiple draggable items across the page. I modified it to use classes: http://jsfiddle.net/Xcb8d/690/. The problem with the code is that even though both elements were draggable, once you start dragging the second element it's x_elem and y_elem are off. This leads the element to move to a far direction from your mouse. Does anyone know what could be causing this?
var selected = null, // Object of the element to be moved
x_pos = 0, y_pos = 0, // Stores x & y coordinates of the mouse pointer
x_elem = 0, y_elem = 0; // Stores top, left values (edge) of the element
// Will be called when user starts dragging an element
function _drag_init(elem) {
// Store the object of the element which needs to be moved
selected = elem;
x_elem = x_pos - selected.offsetLeft;
y_elem = y_pos - selected.offsetTop;
}
// Will be called when user dragging an element
function _move_elem(e) {
x_pos = document.all ? window.event.clientX : e.pageX;
y_pos = document.all ? window.event.clientY : e.pageY;
if (selected !== null) {
selected.style.left = (x_pos - x_elem) + 'px';
selected.style.top = (y_pos - y_elem) + 'px';
}
}
// Destroy the object when we are done
function _destroy() {
selected = null;
}
// Bind the functions...
var draggables = document.getElementsByClassName('draggable-element');
for(i = 0; i < draggables.length; i++) {
draggables[i].onmousedown = function () {
_drag_init(this);
return false;
};
}
document.onmousemove = _move_elem;
document.onmouseup = _destroy;

Finding Image Height variable for multiple images in Jquery

I'm currently working on this script for "tooltips" on a website. I'm finding that the code I currently have will get the image height for my first tooltip image on the page ('pop1') but it ignores the rest (they come out as null).
What's the most effective way to get all the tooltip image heights, and use them every time the user scrolls over the tooltip image?
Another issue, if anyone is able to figure this one out - is that on my FULL webpage (many more divs, rows, columns, etc.) the script begins to break because clientX and clientY are being affected by the various divs and page elements.
I'd like to be able to set clientX and clientY to the exact (x, y) coordinates that the user's mouse is at, relative to the entire webpage, not relative to the page's child elements.
Thanks
Here's my JSFiddle: http://jsfiddle.net/tgs7px4f/18/
JS Code:
$('a.popper').hover(function (e) {
var target = '#' + ($(this).attr('data-popbox'));
$(target).show();
}, function () {
var target = '#' + ($(this).attr('data-popbox'));
if (!($("a.popper").hasClass("show"))) {
$(target).hide();
}
});
$('a.popper').mousemove(function (e) {
var target = '#' + ($(this).attr('data-popbox'));
// images vary in height!
// images are all 366px wide.
var imageWidth = 366;
var imageHeight = $(".popimg").height();
//alert('Image Height: ' + imageHeight);
//Offset tooltip:
//10px to the right of cursor
var imageX = e.clientX + 20;
//imageHeight up from cursor
var imageY = e.clientY - imageHeight - 20;
// Find bounds of current window, and if...
// Tooltip goes off right side:
if ((imageX + imageWidth) > $(window).width()) {
//Move tooltip left so it meets edge:
imageX = $(window).width() - imageWidth;
}
// Tooltip goes off top
if (imageY < 0) {
//Move tooltip down so it meets top:
imageY = 0;
}
$(target).css('top', imageY).css('left', imageX);
});
What's the most effective way to get all the tooltip image heights, and use them every time the user scrolls over the tooltip image?
First of all, I suppose you mean whenever a user does a mouseover on one of the elements? However, this seems to work and it cashes the height of the image directly on the element and uses it the next time a mouseover occurs:
$('a.popper').mousemove(function (e) {
var target = '#' + ($(this).attr('data-popbox'));
// images vary in height!
// images are all 366px wide.
var imageWidth = 366;
$target = $(target);
if (!$target.attr("height")) {
var img = $target.closest(".popbox").children("img");
var imageHeight = img.height();
$target.attr("height", imageHeight);
console.log("height attribute set");
} else {
var imageHeight = +($target.attr("height")) + 0;
console.log("cached height used");
}
console.log('Image Height: ', imageHeight);
//Offset tooltip:
//10px to the right of cursor
var imageX = e.clientX + 20;
//imageHeight up from cursor
var imageY = e.clientY - imageHeight - 20;
// Find bounds of current window, and if...
// Tooltip goes off right side:
if ((imageX + imageWidth) > $(window).width()) {
//Move tooltip left so it meets edge:
imageX = $(window).width() - imageWidth;
}
// Tooltip goes off top
if (imageY < 0) {
//Move tooltip down so it meets top:
imageY = 0;
}
$(target).css('top', imageY).css('left', imageX);
});
Obviously, you should remove all the console.log statements which are for testing purposes only.
jsFiddle
Regarding your second question, it's hard to say anything concrete without another jsFiddle or additional code.

Restrict jQueryUI drag to element, but allow moving from element to element?

I have two squares (divs) side by side. When you drag an item around inside of one I want it restricted to that one, but, if you move your mouse cursor out of it and into the next square over, I want the element to pop out of the first square and into the second and be restricted to the second (and then vice-versa if you move mouse back into the first again while still dragging). But, at no time should the element overlap the squares (it should be wholly always inside of either one or the other). How can I do this? I'm using jQuery UI.
http://jsbin.com/gecucotu/1/edit?js,output
Couldn't get jQuery UI to do it, but, was able to do it using Vanilla JavaScript
http://jsfiddle.net/cmcculloh/676fr/
var dragging = false;
var lastE;
$('#t1').mousedown(function(e){
dragging = true;
});
$('body').mousemove(function(e){
lastE = e;
}).mouseup(function(e){
dragging = false;
});
var placeT = function placeT(e) {
var newX = Math.round((e.pageX - 2)/20) * 20;
var newY = Math.round((e.pageY - 2)/20) * 20;
if(newX <= 100){
$('#t1').offset({ left: newX });
}else if(newX >= 220 && newX <= 300){
$('#t1').offset({ left: newX });
}else{
}
$('#t1').offset({ top: newY });
}
var drag = function drag() {
if(dragging){
placeT(lastE);
}
window.setTimeout(drag, 1);
};
window.setTimeout(drag, 100);

Make a div follow the mouse just when the mouse is on mousedown

I'm trying to make a jquery function to follow the mouse coursor with a div, when it is on mousedown and when it is on mouseup it stay in the last position it was.
any sugestion.
Why not simply use drag and drop by jquery:
<script>
$(function() {
$( "#draggable" ).draggable();
});
</script>
Jquery draggable
I've put together a simple working example that defines a Draggable object. You specify the drag item (the element that you're moving around), as well as a drag boundary (the space—or element—that you are moving the item inside of). The concept of a boundary is important if you ever want to restrict a draggable item to a certain space on the page (such as a container), or define a relative coordinate system on which to base your math.
My solution isn't the fastest, but it demonstrates the concept:
$(function() {
window.mousedown = 0;
$(window).on('mousedown mouseup', function(e) {
if(e.type == 'mousedown') { this.mousedown++; }
else { this.mousedown--; }
});
var Draggable = function(dragItem, dragBoundary) {
this.item = $(dragItem).css('position', 'absolute');
this.item.on('mousemove', $.proxy(this.handleDragEvent, this));
this.boundary = $(dragBoundary).css('position', 'relative');
};
Draggable.prototype.handleDragEvent = function(e) {
if(window.mousedown) {
var mousePosition = this.mapToBoundary([e.clientX, e.clientY]);
var mouseX = mousePosition[0],
mouseY = mousePosition[1];
if(typeof this.prevMouseX == "undefined") this.prevMouseX = mouseX;
if(typeof this.prevMouseY == "undefined") this.prevMouseY = mouseY;
this.itemX = this.item.offset().left - this.boundary.offset().left;
this.itemY = this.item.offset().top - this.boundary.offset().top;
var deltaX = mouseX - this.prevMouseX,
deltaY = mouseY - this.prevMouseY;
this.item.css({
'left': this.itemX + deltaX,
'top': this.itemY + deltaY
});
this.prevMouseX = mouseX;
this.prevMouseY = mouseY;
}
};
Draggable.prototype.mapToBoundary = function(coord) {
var x = coord[0] - this.boundary.offset().left;
var y = coord[1] - this.boundary.offset().top;
return [x,y];
};
var draggable = new Draggable($('.draggable'), $('.container'));
});
Notice that we are maintaining a mousedown value on global, allowing us to determine when it would be appropriate to drag around our element (we only add a mousemove listener to the drag item itself). I've also included a spacer div above the boundary div to demonstrate how you can move the boundary anywhere around the page and the coordinate system is still accurate. The code to actually restrict a draggable item within its assigned boundary could be written using simple math.
Here is the fiddle: http://jsfiddle.net/bTh9s/3/
EDIT:
Here is the start to some code for restricting a Draggable item within its container.
Draggable.prototype.restrictItemToBoundary = function() {
var position = this.item.position();
position.right = position.left + this.item.outerWidth();
position.bottom = position.top + this.item.outerHeight();
if(position.left <= 0) {
this.item.css('left', 1);
} else if(position.right >= this.boundary.outerWidth()) {
this.item.css('left', this.boundary.outerWidth() - this.item.outerWidth());
}
if(position.top <= 0) {
this.item.css('top', 1);
} else if(position.bottom >= this.boundary.outerHeight()) {
this.item.css('top', this.boundary.outerHeight() - this.item.outerHeight());
}
};
This method should be called inside of Draggable.handleDragEvent just after you update the CSS positioning of the drag item. It seems this solution is glitchy, but it's a start.

Categories

Resources