My page has several items (divs) that are draggable and resizable.
My code for doing this is given below:
part.draggable(
{
containment: 'parent',
drag: function(event, ui){
partIsDragging = true
part.prev().css('top', ui.position.top - 20 ).css('left', ui.position.left )
part.prev().show()
},
stop: function(event, ui) {
partIsDragging = false
}
}).resizable({
containment: 'parent',
handles: 'ne, se, sw, nw,n,w,e,s',
stop: function() {
}
});
The html structure for these is the following:
<body>
<div id="wrapper">
<div class="draggableItem"></div>
<div class="draggableItem"></div>
<div class="draggableItem"></div>
<div class="draggableItem"></div>
</div>
</body>
In my css files i have set body height: 100% and wrapper height: 100%. Width is always fixed for wrapper, width: 950px. I want my div to expand in height when the draggableItem reaches the bottom of the wrapper. Right now when the page is loaded, it has the height as big as the resolution allows it but in case I have more items in the wrapper then everything becomes cluttered and I would like when dragging an item to somehow expand the wrapper in height dynamically. This should happen only if I hit the bottom border.
PS: I am using jQuery and jQuery-ui.
I may have a solution. First off, I replaced part with '.draggableItem' and this where appropriate. Please tell me if that breaks the code in some critical way. In addition, I removed part.prev().css('top', ui.position.top - 20 ).css('left', ui.position.left ) in the code below.
function adjustWrapperHeight(movingObject)
{
var objectBottomPosition = $(movingObject).offset().top+$(movingObject).height()
var wrapperBottomPosition = $("#wrapper").offset().top+$("#wrapper").height()
if(wrapperBottomPosition-objectBottomPosition<distanceBuffer)
{
$("#wrapper").height($("#wrapper").height()+distanceBuffer+1)
}
}
var distanceBuffer = 20;
$('.draggableItem').draggable(
{
containment: 'parent',
drag: function(event, ui)
{
partIsDragging = true
adjustWrapperHeight(this)
},
stop: function(event, ui)
{
partIsDragging = false
}
}).resizable(
{
handles: 'ne, se, sw, nw,n,w,e,s',
resize: function(event, ui)
{
adjustWrapperHeight(this)
var objectRightPosition = $(this).offset().left+$(this).width()
var wrapperRightPosition = $("#wrapper").offset().left+$("#wrapper").width()
if(wrapperRightPosition<=objectRightPosition)
{
$(this).width(ui.originalSize.width)
var containmentLeftPosition = wrapperRightPosition-$(this).width()
$(this).offset({top:$(this).offset().top,left:containmentLeftPosition})
}
}
})
})
The function adjustWrapperHeight(movingObject) adjusts div#wrapper's height depending on a movingObject's bottom position. That is, when movingObject "pushes up" against div#wrapper's borders, it adjusts div#wrapper's height.
I had to use a hack for resizable. The containment: 'parent' for resizable (but not draggable) sets the containment to the container's ORIGINAL height or so it seems. That means as the height of div#wrapper dynamically changes, the constraint set by containment: 'parent' does not dynamically change. To fix this, I removed containment: 'parent' and indeed the entire containment and ensured that div#wrapper's right containment isn't broken within the resize event. Note that you should probably do this with div#wrapper's left containment as well.
Please tell me if this was helpful. Thank you.
Related
EDIT: JSFIDDLE: http://jsfiddle.net/h9yzsqfr/
--
Code:
elem.editor.find("div.ui-widget").draggable(
{
handle:"div.content",
containment:elem.editor,
snap:"*",
start: function(e,ui)
{
$(ui.helper).addClass("dragging");
},
drag: function(e,ui)
{
checkTop(ui);
if($(ui.helper).parents("div.lo-content").length > 0)
{
$(ui.helper).appendTo(elem.editor);
ui.position = { 'top': e.pageY, 'left': e.pageX };
}
},
stop: function(e,ui)
{
oldWidget.saveState($(ui.helper),1);
setTimeout(function() {
$(ui.helper).removeClass("dragging");
}, 300);
}
});
I have some draggable objects within a container defined by elem.editor; however I have some other draggable objects inside div.lo-content which is also inside elem.editor.
Whenever an object inside div.lo-content is dragged, it should reattach to the elem.editor container which is working fine; however as demonstrated in the following GIF (below), it is not setting the position of the draggable object to where the mouse cursor is.
What is a workaround for this problem?
The problem is your width: 100% and the containment option. As soon as its appended to body it stays 100%, but of the body, then it gets smaller but the containment has already been calculated.
One way to solve it is to reset containment. There are probably different ways to do it, one way could be like this:
start: function (e, ui) {
if ($(this).parents(".inner").length > 0) {
$(ui.helper).addClass("dragging");
ui.helper.css({
'width': '100px',
'left': '0px',
'top': '0px'
});
ui.helper.data()['ui-draggable'].containment = [0,0,$('body').width(), $('body').height()]
ui.helper.appendTo("body");
}
},
http://jsfiddle.net/puurqx8r/6/
connectToSortable
It's a Selector that Allows the draggable to be dropped onto the specified sortables. If this option is used, a draggable can be dropped onto a sortable list and then becomes part of it. Note: The helper option must be set to "clone" in order to work flawlessly. Requires the jQuery UI Sortable plugin to be included.
Code examples:
Initialize the draggable with the connectToSortableoption specified:
$( ".selector" ).draggable({
connectToSortable: "#my-sortable"
cursorAt:{top: 5, left: t}
});
Use cursorAt: top:, left: and appendTo: 'body'
See my answer with example here.
jQuery draggable shows helper in wrong place after page scrolled
I had the same problem. This is caused by the use of margins to center elements. Try using position absolute!
I removed position:absolute on dragable object
I have different draggable elements. They can be dragged into placeholders (100px x 100px), but the draggable elements has a width of 100% (body width).
Now when I start dragging I trigger a resize function:
// Dragging itself
function dragging () {
$("#draggable li.to-drag").draggable({
connectToSortable: ".items",
helper: "clone",
revert: false,
opacity: 0.5,
cursorAt: { top: 50, left: 50},
drag: resize,
start: function (event, ui) {
ui.draggable.height(ui.placeholder.outerHeight());
}
});
}
// Resize function triggered when I start dragging
function resize (event, ui) {
ui.helper.css({ height: "100px", width: "100px" });
}
As the width of the draggable element is greater than the placeholder, I can't get the placeholder to accept the draggable element to be droppable.
Sounds complicating, but here's a jsfiddle
There is an error in you fiddle line 70:
tolerance: pointer,
pointer is not define
replace it with
tolerance: "pointer",
than all should work correctly
jsfiddle
The issue is not with the width being 100%.You have changed the cursorAt to make it at the centre of the draggable item.But it still looks for the original cursor postion to drop the element
jQuery UI draggable plugin allow you to set contain for draggable like
$('.panel').draggable({
handle: ".head",
containment: "parent",
cursor: "pointer"
}
);
My question is how can I detect if div have reached the edge of its containment?
I want to mimic the Windows effect when you drag a panel to edge it go 50% width and 100% height but I don't know how to detect/trigger an event when div reaches the edge.
Thanks
You can use the drag function to return the position of the draggable element while it's being moved. Compare that against the position of the outer edge of the parent and when the two intersect trigger the resizing action.
This fiddle is a very simplified version of what you're looking for, but it should illustrate the basic concept and get you started in the right direction. Hopefully this helps.
http://jsfiddle.net/98jpC/1/
$(function(){
var draggableRight;
var draggableWidth = $('.draggable').width();
var parentWidth = $('#parent').width();
$('.draggable').draggable({
containment: 'parent',
drag: function(e, ui){
draggableRight = ui.position.left + draggableWidth;
if(draggableRight == parentWidth){
$(document).trigger("mouseup");
$('.draggable').css({
width: '50%',
height: '100%',
top: 0,
left: '50%'
});
}
}
});
});
I'm currently trying to apply a containment to both the resize and the drag of a component. The drag accepts the containment bounds perfectly but the resize decides to break out and not follow the specified boundaries that I have set - anything i'm doing wrong here?
See the following jsFiddle (http://jsfiddle.net/cyVYq/30/);
$(".Event3").draggable({
axis: "x",
containment: "#2"
}).resizable({
axis: "x",
handles: "e, w",
containment: "#2"
})
Many Thanks,
You're trying to contain the resizable in an element that isn't its parent (#2)
Try setting the container to its parent .TimelineContainer:
$(".Event3").resizable({
axis: "x",
handles: "e, w",
containment: ".TimelineContainer"
})
Fiddle
Update:
From the JQuery-UI documentation it appears that the intended use of the containment option is to be used within the confines of a parent element. It doesn't seem possible to use this option the way you intend. Try something like:
$(".Event3").resizable({
axis: "x",
handles: "e, w",
containment: ".TimelineContainer",
resize: function(event, ui) {
// Define the dimensions of this element
var left = ui.position.left;
var width = ui.size.width;
var right = left + width;
// Define my constraints based on the element #2
var constraintLeft = $('#2').position().left;
var constraintWidth = $('#2').width();
var constraintRight = constraintLeft + constraintWidth;
// if resizable has gone further left than the constraint
if(left < constraintLeft) {
var left = parseInt($(this).css('left'));
// measure the difference between this left and the constraint left
var difference = constraintLeft - left;
// make up the difference
$(this).css('left', constraintLeft);
// make sure your width stays the same
$(this).width($(this).width() - difference);
// cancel the event
$(this).resizable('widget').trigger('mouseup');
}
// if resizable has gone further right than the constraint
if( right > constraintRight) {
// change the width to fit between the constraint right and this left
$(this).width(constraintRight - left);
// cancel the event
$(this).resizable('widget').trigger('mouseup');
}
}
});
Where you manually define the boundaries of the resizable and then you call a mouseup when the resizable has reached those boundaries. Here's the fiddle to play around with:
Fiddle
I am using Jquery ui and it provide a function for me to make draggable content. It has an option 'containment' that force the draggable item move within the box.
However, for my case, the content (image) must exceed the screen , how can I force it not to drag inside the screen?
Thanks
$("#popup").draggable({
addClasses:true,
scrollSpeed: "200",
containment: "parent",
//appendTo: "body",
helper: function(){
// Create an invisible div as the helper. It will move and
// follow the cursor as usual.
return $('<div></div>').css('opacity',0);
},
drag: function(event, ui){
// During dragging, animate the original object to
// follow the invisible helper with custom easing.
var p = ui.helper.position();
$(this).stop().animate({
top: p.top,
left: p.left
},1000,'easeOutCirc');
}
});