jQuery multi-draggable - javascript

Edit#1:
Since I asked this problem, I made a script which allows the elements to move together, but with problems. :(
$(this).append(
$('<div class="elem '+classes+'" style="width: 210px; height: 30px" data-modby="'+ui.draggable.attr("data-for")+'"><p>'+text+'</p></div>')
.resizable({
grid: 10,
maxHeight: 120,
maxWidth: 600,
minHeight: 30,
minWidth: 210,
containment: ".box-section"
})
.draggable({
grid: [10,10],
containment: ".box-section",
scroll: false,
helper: "original",
start: function(event, ui) {
posTopArray = [];
posLeftArray = [];
if ($(this).hasClass("r-active")) {
$(".elem.r-active").each(function(i) {
thiscsstop = $(this).css('top');
if (thiscsstop == 'auto') thiscsstop = 0;
thiscssleft = $(this).css('left');
if (thiscssleft == 'auto') thiscssleft = 0;
posTopArray[i] = parseInt(thiscsstop);
posLeftArray[i] = parseInt(thiscssleft);
});
}
begintop = $(this).offset().top;
beginleft = $(this).offset().left;
},
drag: function(event, ui) {
var topdiff = $(this).offset().top - begintop;
var leftdiff = $(this).offset().left - beginleft;
if ($(this).hasClass("r-active")) {
$(".elem.r-active").each(function(i) {
$(this).css('top', posTopArray[i] + topdiff);
$(this).css('left', posLeftArray[i] + leftdiff);
});
}
}
})
);
The actual problem is the moved elements have to stay in the containment box (called .box-section and if I have a single element it works fine. Also if i have two elements has not the same width, if i pick the sorter one and drag, I can pull out the longer of the container.
Also, if I move them fast (like a ninja) they will slip, and they won't be in the same grid they used to be.
30 percent solved since:
I'm going to make a new thingy which can drag and drop items to a box, and resize them.
My problem is that, I can't make them move together. But with some rules.
Rule one: They must move based on a 10x10px grid.
Rule two: They can't move outside their frame.
(Resize is an issue which i simply can't imagine, so I don't care about it, resize will be later)
I made a fiddle for it here: http://jsfiddle.net/9fueY/ you can see this.
In the right side, you can see inputs and a and a checkbox (and on hover a button).
The checkbox is the draggable object, drag it to the image. Now you have some text or a star appeared on the left.
If you type anything to the inputs, it refreshes the text.
OnHover the right boxes you can see a button. By clicking on it, will make a clone of the first element. Drag it inside.
If you click to a right-side box, it will glow blue. Click to two boxes on the right, makes all the two textfields glow blue in the image.
Now this is the case when i want them to move together. :D
What's your opinion, what should I do with this?
Thank you very much. - Répás

There is a plugin i developed for dragging elements together. Please do use it if it makes sense.
https://github.com/someshwara/MultiDraggable

Related

mdbootstrap: hidden floating buttons overlay content

I am using the mdbootstrap Pro 4.5.5 version and have the following problem.
For providing context based actions i use the fixed buttons:
https://mdbootstrap.com/components/buttons/#fixed-buttons
As us can see in the screen, the component overlays an hidden unordered list above the content. in this list the buttons are shown on hover or on click on mobile:
Problem is: if i have some links or other actions below the hidden list (that could happen on mobile, as u can see on the second scren), they are not clickable and the buttons are already shown when i will touch or click on the links under the list.
Would be very happy, if somebody could help. I am also happy about other examples or solutions to implement a fab-button-bar on html and js
Found the solution (more a hack than a solution) by myself. it depends on the init of velocity on the openFABMenu and closeFABMenu, where only the opacity is set to 0. that only hides the buttons but the container is already there:
var closeFABMenu = function closeFABMenu(btn) {
$this = btn;
// Get direction option
var horizontal = $this.hasClass('horizontal');
var offsetY = void 0,
offsetX = void 0;
if (horizontal === true) {
offsetX = 40;
} else {
offsetY = 40;
}
$this.removeClass('active');
var time = 0;
$this.find('ul .btn-floating').velocity('stop', true);
$this.find('ul .btn-floating').velocity({
opacity: '0',
scaleX: '.4',
scaleY: '.4',
translateY: offsetY + 'px',
translateX: offsetX + 'px'
}, {
duration: 80,
**display: "none"**
});
For now i overwrote the functions closeFABMenu/openFABMenu and inserted display: none and display:block on the inits of velocity.
atm it works for me, we hope the best. but the solution is not very clean, because i needed also to do some changes on css and html. wondering, that i am the only person with that overlaying problem....

Draggable containment buggs when the draggable element is rotated

I have a draggable element, which is also resizable and rotatable. These rotations are handled by CSS transformations, however, when an element is rotated, it makes the draggable feature spin out of control.
Heres a (updated) fiddle: Click me
What I think happens is that when an element is rotated, it's height and width obviously stay the same, just at an angle, however, jQuery doesn't account for the rotation, making it think that the element is in it's normal horizontal way, which results in the "bugg" shown in the fiddle above.
In a wild goose chase for the answer, I read somewhere that this would do the trick:
refreshPositions: true,
But it didn't work. Neither did destroying the draggable function on the element and then reinitiating it. Is there a way to fix this, so the containment will function normally, thus making jQuery recognise the rotation?
Thanks.
One option is to handle the containment yourself. Here is one possible way to do that.
I am using getBoundingClientRect to get the height and width of the rotated element. Using these values I can get an idea of where the dragged element resides in relation to it's parent container and force it to stay within those bounds.
var boundingContainer, boundingDraggable, prevLeft, prevTop;
$(".draggable").draggable({
classes: {
"ui-draggable-dragging": "highlight-draggable"
},
start: function(event, ui) {
boundingDraggable = ui.helper[0].getBoundingClientRect();
boundingContainer = ui.helper.closest('#draggableContainer')[0].getBoundingClientRect();
},
drag: function(event, ui) {
if(ui.offset.left <= boundingContainer.left){
if(ui.position.left < prevLeft){
ui.position.left = prevLeft;
}
}
if(ui.offset.top <= boundingContainer.top){
if(ui.position.top < prevTop){
ui.position.top = prevTop;
}
}
if(ui.offset.left+boundingDraggable.width >= boundingContainer.right){
if(ui.position.left > prevLeft){
ui.position.left = prevLeft;
}
}
if(ui.offset.top+boundingDraggable.height >= boundingContainer.bottom){
if(ui.position.top > prevTop){
ui.position.top = prevTop;
}
}
prevLeft = ui.position.left;
prevTop = ui.position.top;
}
});
Fiddle

jQuery draggable bug (element not in line with cursor)

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

trigger event when draggable hit edge of containment

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

Jquery UI Draggable + Resizable Containment issues

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

Categories