Constraining the position on a resizable div - javascript

This effort is in response to my previously un-answered question: Resizable div doesn't stay within containment parameter
Since my resizable div, which is referred to as a pocket, is not the direct child of the container that I want it contained in, I supplied a callback in the resize method that should contain it within the container.
Fiddle here: http://jsfiddle.net/dKuER/12/
My Problem
When you re-size the resizable div to the left (which affects its left position) past the grid boundary, it does not always respect my logic in the callback function. As you drag to the left, you'll notice a blinking action, where the div will switch between its hard-coded left position to the left position determined by the mouse.
Depending on when you discontinue dragging, the left position of the div may either be at the hard-coded position or wherever the mouse stopped dragging.
How do I make sure the callback function's logic is ALWAYS respected?
// Relevant Code
// No blinking action when dealing with the width
//Re-sizing to the right works
if ( (pocketLeft + currentWidth) > (gridLeft + gridWidth) ) {
var deltaWidth = (gridLeft + gridWidth) - (pocketLeft + originalWidth);
ui.size.width = originalWidth -deltaWidth;
}
// This should force the position if the div is re-sized
// past the grid's left boundary
if (pocketLeft < gridLeft) {
ui.position.left = -120;
}

Using the mouse coordinates, and the width attained through the resizable div's object methods ( so obvious! ), rather than deriving it from some obscure calculations, I was able to achieve the correct effect
http://jsfiddle.net/dKuER/16/
var x = event.pageX - $('#grid').offset().left;
var y = event.pageY - $('#grid').offset().top;
if (x < 0)
{
ui.size.width = $(this).width();
ui.position.left = $(this).position().left;
}
I achieved this solution trying to understand the core of the jquery.ui.resizable code. However, I maintain there is more acceptable answer than mine.

Related

Dragging of element goes wrong when the container is scrolled

In this Fiddle, I made the red container draggable. As you can see, this is working fine but when the green container (parent container) is scrolled a bit and then the red container is dragged, the dragging is not happening at correct position.
Can someone please tell me what could be the problem?
I tried e.pageX, e.clientX and e.offsetX but still couldn't able to fix this. (or maybe I missed something)
You need to add the scrolling top position to your shape. If you want your square stay on the correct position check that:
function repositionShape(e) {
$self = repositionStart.self;
$commentSection = repositionStart.commentSection;
var dy = $('.wrapper').scrollTop(); // Get wrapper scroll position
$self.css({
'left': e.clientX - repositionStart.offset.left,
'top': e.clientY - repositionStart.offset.top +dy // Add delta to your square position
});
}

Position tooltip above mouse when room in viewport, otherwise below mouse

I am creating a tooltip and am having some problems with positioning it.
The tooltip is set to position: absolute, and I have a handler for mouse events that modifies it's top and left CSS depending on the pageX and pageY.
Now, I know I can just set the top to pageY and left to pageX. That will make the tooltip pop up to the bottom-right. I'm trying to orient it where it pops up on the top-right when there is room, but if it would be out of the viewport on the Y-axis, drop to the bottom-right position again.
At the moment, I'm stuck trying to get the tooltip to show to the top-right of the mouse. I don't even know where to begin detecting if it would be in the viewport. Can anyone point me in the right direction?
$('p').on('mouseenter', function(e) {
$(tt).css('top', e.pageY - $(tt).css('height'));
$(tt).css('left', e.pageX);
$(tt).appendTo('body');
}).on('mousemove', function(e) {
$(tt).css('top', e.pageY - $(tt).css('height'));
$(tt).css('left', e.pageX);
}).on('mouseleave', function(e) {
$(tt).detach();
});
Example on JSFiddle
There are many different ways to handle tooltips, especially when using jQuery. This method probably would not have been my first choice. However, the following changes should work how you intended.
var tt = document.createElement('div');
tt.id = "tt";
$('p').on('mouseenter', function(e) {
var curPos = $( this ).offset().top - $( window ).scrollTop();
var inView = (curPos < 250) ? 0 : 250;
$(tt).css('top', e.pageY - inView);
$(tt).css('left', e.pageX);
$(tt).append($( this ).attr("data-myId"));
$(tt).appendTo('body');
}).on('mousemove', function(e) {
$(tt).css('top', e.pageY - $(tt).css('height'));
$(tt).css('left', e.pageX);
}).on('mouseleave', function(e) {
$(tt).empty($( this ).attr("data-myId"));
$(tt).detach();
});
Full changes in JSFiddle.
I am taking advantage of jQuery's offset() and scrollTop() methods to estimate the position of the current element within the viewable area of the document.
According to jQuery's API documentation, the .offset() method
allows us to retrieve the current position of an element relative to
the document. The documentation also states that the vertical
scroll position (.scrollTop()) is the same as the number of pixels that are hidden
from view above the scrollable area.
We use both of these methods to our advantage and subtract the number of pixels above the scrollable area from the current position of the element relative to the document. One important thing to note is that the offset method returns an object with the properties top and left.
var curPos = $( this ).offset().top - $( window ).scrollTop();
Since you had the #tt id set to a static 250px height, we can check if the current element position relative to the viewable portion of the window is less than 250. If it is, then we subtract nothing and let the tool tip sit below the mouse position. If it is greater than 250 then we subtract 250px and the tool tip will be above the current mouse position.
I am not sure how you were intending to pull in the content for the tool tips, but I also added $(tt).append($( this ).attr("data-myId")); to use the data-myId value as the tool tip content and $(tt).empty($( this ).attr("data-myId")); to clear it on mouseleave. I hope this helps!

How can I limit a draggable child with right and bottom value of parent?

I am trying to make a draggable map. I found how to limit a draggable child for left and top sides but couldn't figure out how to make same thing for right and bottom sides.
How can I limit a draggble child with right and bottom value of parent?
var uright = ui.position.left + 960; /* 960 is map height*/
var pright = parentPos.left + 700; /* 500 is container height*/
if (ui.position.top > parentPos.top) {
ui.position.top = parentPos.top; // works fine
}
if (ui.position.left > parentPos.left) {
ui.position.left= parentPos.left; // works fine
}
if (uright > pright) {
uright = pright; // that doesnt work
}
Here is my jsfiddle
You can try using getBoundingClientRect method instead of using position method.The Element.getBoundingClientRect() method returns a text rectangle object that encloses a group of text rectangles.
rectObject = object.getBoundingClientRect();
The returned value is a TextRectangle object which is the union of the
rectangles returned by getClientRects() for the element, i.e., the CSS
border-boxes associated with the element.
The returned value is a TextRectangle object, which contains read-only
left, top, right and bottom properties describing the border-box in
pixels. top and left are relative to the top-left of the viewport.
You can then get top,left,right,bottom values of the element i.e. rectObject.right,rectObject.top,rectObject.bottom,
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Element.getBoundingClientRect
Alternatively, why don't you try containment option in jquery draggable.
Link : http://api.jqueryui.com/draggable/#option-containment

How use JQuery/Javascript to scroll down a page when the cursor at the top or bottom edge of the screen?

Simple, I just would like to have it so when a user is dragging an item and they reach the very bottom or top of the viewport (10px or so), the page (about 3000px long) gently scrolls down or up, until they move their cursor (and thus the item being dragged) out of the region.
An item is an li tag which uses jquery to make the list items draggable. To be specific:
../jquery-ui-1.8.14.custom.min.js
http://code.jquery.com/jquery-1.6.2.min.js
I currently use window.scrollBy(x=0,y=3) to scroll the page and have the variables of:
e.pageY ... provides absolute Y-coordinates of cursor on page (not relative to screen)
$.scrollTop() ... provides offset from top of page (when scroll bar is all the way up, it is 0)
$.height()... provides the height of viewable area in the user's browser/viewport
body.offsetHeight ... height of the entire page
How can I achieve this and which event best accommodates this (currently its in mouseover)?
My ideas:
use a an if/else to check if it is in top region or bottom, scroll up if e.pageY is showing it is in the top, down if e.page& is in bottom, and then calling the $('li').mouseover() event to iterate through...
Use a do while loop... this has worked moderately well actually, but is hard to stop from scrolling to far. But I am not sure how to control the iterations....
My latest attempt:
('li').mouseover(function(e) {
totalHeight = document.body.offsetHeight;
cursor.y = e.pageY;
var papaWindow = window;
var $pxFromTop = $(papaWindow).scrollTop();
var $userScreenHeight = $(papaWindow).height();
var iterate = 0;
do {
papaWindow.scrollBy(0, 2);
iterate++;
console.log(cursor.y, $pxFromTop, $userScreenHeight);
}
while (iterate < 20);
});
Works pretty well now, user just needs to "jiggle" the mouse when dragging items sometimes to keep scrolling, but for scrolling just with mouse position its pretty solid. Here is what I finally ended up using:
$("li").mouseover(function(e) {
e = e || window.event; var cursor = { y: 0 }; cursor.y = e.pageY; //Cursor YPos
var papaWindow = parent.window;
var $pxFromTop = $(papaWindow).scrollTop();
var $userScreenHeight = $(papaWindow).height();
if (cursor.y > (($userScreenHeight + $pxFromTop) / 1.25)) {
if ($pxFromTop < ($userScreenHeight * 3.2)) {
papaWindow.scrollBy(0, ($userScreenHeight / 30));
}
}
else if (cursor.y < (($userScreenHeight + $pxFromTop) * .75)) {
papaWindow.scrollBy(0, -($userScreenHeight / 30));
}
}); //End mouseover()
This won't work as the event only fires while you're mouse is over the li.
('li').mouseover(function(e) { });
You need to be able to tell the position of the mouse relative to the viewport when an item is being dragged. When the users starts to drag an item attach an 'mousemove' event to the body and then in that check the mouse position and scroll when necessary.
$("body").on("mousemove", function(event) {
// Check mouse position - scroll if near bottom or top
});
Dont forget to remove your event when the user stops dragging.
$("body").off("mousemove", function(event) {
// Check mouse position - scroll if near bottom or top
});
This may not be exactly what you want, but it might help. It will auto-scroll when the mouse is over the 'border of the screen' (a user defined region). Say you have a 40px wide bar on the right of the screen, if the mouse reaches the first 1px, it will start scrolling. Each px you move into it, the speed will increase. It even has a nice easing animation.
http://www.smoothdivscroll.com/v1-2.htm
I get a weekly newsletter (email) from CodeProject, and it had some stuff that certainly looks like it will solve my problem... hopefully this can help others:
http://johnpolacek.github.com/scrollorama/ -- JQuery based and animates the scroll
https://github.com/IanLunn/jQuery-Parallax -- JQuery based, similar to above
http:// remysharp. com/2009/01/26/element-in-view-event-plugin/ -- JQuery, detects whether an element is currently in view of the user (super helpful for this issue!)
Also the site in #2 had some interesting code:
var windowHeight = $window.height();
var navHeight = $('#nav').height() / 2;
var windowCenter = (windowHeight / 2);
var newtop = windowCenter - navHeight;
//ToDo: Find a way to use these vars and my original ones to determine scroll regions

CSS dynamic position of tooltip on hover with jQuery

I'm writing a simple tooltip that can hold HTML tags. Please check http://jsfiddle.net/Qkwm8/ for the demo.
I want the tooltip box to show properly regardless of the position of element, in this case <a>, that shows tooltips on mouseover event.
The tooltips are shown fine except when <a> floats right (or is at the end of the line) or at the bottom of the screen where it doesn't show properly, it appears off the screen
If the <a> floats right, or at the end of the line, or is at the bottom of the screen, I want the tooltip to change position so it remains visible
Thank you.
Update demo link
here's the complete result: http://jsfiddle.net/Qkwm8/3/
You can use the document width to check how wide the html document is and adjust the left position accordingly. Say:
//set the left position
var left = $(this).offset().left + 10;
if(left + 200 > $(document).width()){
left = $(document).width() - 200;
}
I used 200 here because you are setting your tooltip to 200px wide. Something similar can be done with height.
There is also a window width but I always get confused about the difference so you should check which one gives you better results.
An example of the bottom of the page is:
//set the height, top position
var height = $(this).height();
var top = $(this).offset().top;
if(top + 200 > $(window).height()){
top = $(window).height() - 200 - height;
}
Again, using 200 since you are setting your tooltip to 200px height.
$('a.show-tooltips').mouseover(function() {
if(($(this).parent()).css('float')) =="right") add the proper class to left
else -> the proper class the right
....
}

Categories

Resources