Change JQuery droppable over behavior - javascript

Please see my source code at: http://jsfiddle.net/rAmSG/9/
The blue item should be dropped at an of the other 3 divs. This already works correctly. But I want to have a effect when the blue item is over one of the other divs (and the mouse is not released yet). The corresponing div should be colored grey (but only the smallest div, like the drop behavior).
Does anyone have a suggestion how to do this?
Also I'm not able to get the 'hoverClass' settings working, any solutions for this too?
Thanks in advance!

You have problems with hoverClass because you're defining a background color for the droppable elements using an id selector, and that rule takes precedence even when you apply the dark class to the elements.
You can increase the .dark rule's priority with !important:
.dark {
background-color: #333333 !important;
}
Then you can use hoverClass as expected:
$("#dropDiv1, #dropDiv2, #dropDiv3").droppable({
greedy: true,
drop: function() {
$(this).css("background-color", "black");
},
tolerance: "pointer",
hoverClass: "dark"
});
You will find an updated fiddle here.

Add an out function:
$(document).ready(function(e) {
$("#dragDiv").draggable();
$("#dropDiv1, #dropDiv2 , #dropDiv3").droppable({
greedy: true,
drop: function()
{
$(this).css("background-color", "black");
},
over: function()
{
$(this).css("background-color", "#333");
},
out: function()
{
$(this).css("background-color", "");
},
tolerance: "pointer"
});
});
This will reset the background-color when the blue square leaves a rectangle.

Related

jQuery draggable with position conditionals

Trying to figure out how to be able to drag the red square ONLY AFTER the blue square has been dragged to the other end of its parent.
Also wondering if it is possible (in a separate scenario) to have the red square mirror the blue square when the blue square is dragged.
https://jsfiddle.net/t167y2ga/14/
$(function() {
$("#draggable_left").draggable({
containment: "parent",
});
});
$(function() {
$("#draggable_right").draggable({
containment: "parent",
});
});
You can use stop event:
stop:function(ev,ui){
if(ui.position.left === 150) {
$("#draggable_right").draggable({
containment: "parent",
});
}
Something like this will do the first part:
Fiddle
To achieve your first goal
be able to drag the red square ONLY AFTER the blue square has been
dragged to the other end of its parent
You just need to apply the draggable to the html element after the stop event is fired from the first draggable element. Sample code is:
$(function() {
$("#draggable_left").draggable({
containment: "parent",
stop: function(e, ui) {
$("#draggable_right").draggable({
containment: "parent",
});
},
});
});
See the JSFiddle working example here
EDIT: In case you want to disable the draggable when blue element is not in the right side, see this other JSFiddle

z-index stacking issue on draggable element (jQuery UI)

I'm having an issue in a jQuery UI app I'm writing (a klondike solitaire game) that happens when I'm attempting to drag a part of a flipped over stack from one stack to another. You can see this illustrated in the screenshot below:
The app in its entirety can be found in this Fiddle: http://jsfiddle.net/damo_s/hy2dvL1u/
I have an idea of what's going wrong but not sure how to engineer it to work as expected.
I initially tried to fix it by adding a class to the hovered over droppable but this only works to the extent that I have to have the draggable at least 50% over the droppable (because I'm using intersect mode on the tolerance option) before the draggable comes to the front. The relevant code:
$('.drop-area').droppable({
over: function (event, ui) {
$(this).closest('.main-stack').addClass('droppable-above');
},
out: function (event, ui) {
$('.main-stack').removeClass('droppable-above');
},
drop: function (event, ui) {
$('.main-stack').removeClass('droppable-above');
...
My guess of what's going on is that the stacks with class .main-stack are absolutely positioned layers with their own z-index values (though not explicitly set in my css) and thus the z-index of the draggable has no bearing on whether it will be above or below a particular .main-stack
Any further clarification on what's going on and what can be done to fix it would be much appreciated.
A solution came to me shortly after I posted the question.
I added this to the start: method of the draggable initialization:
if ($(this).closest('.main-stack').length) {
$(this).closest('.main-stack').addClass('dragging-card');
$(this).closest('.main-stack').siblings().removeClass('dragging-card');
}
So my code became:
$('.card').draggable({
start: function (event, ui) {
positionTop = $(this).css('top');
// On drag start check each stack for an empty stack
$('.main-stack').each(function () {
if (!$(this).find('.card').length) {
$(this).droppable('option', 'disabled', false);
return false;
}
});
// If dragging from a main stack
if ($(this).closest('.main-stack').length) {
// Set the class of the draggable's containing stack
$(this).closest('.main-stack').addClass('dragging-card');
$(this).closest('.main-stack').siblings().removeClass('dragging-card');
}
},
And my CSS changed to:
.under-card {
z-index: 1000!important;
}
.ui-front, .top-card {
z-index: 1001!important;
}
.dragging-card {
z-index: 1002!important;
}
.ui-draggable-dragging {
z-index: 1003!important;
}

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

get ID of dropped div and hide all other divs without this class

Sorry for the confusing title, I hope I can explain.
http://thetally.efinancialnews.com/tallyassets/suebanks/suebanks.html
In this example you can drag a red box from the right into the grey box at the top left, each red box has a unique ID. When this red box is dropped in, I would like all the black boxes below to disappear EXCEPT the ones who's CLASS matches the unique ID of the red square.
The first box has an ID of 'barclays', as do 2 of the black boxes, so those 2 should remain
The second has an ID of lloyds, so only 1 of those black boxes should remain.
Here is the javascript code I am using:
$(init);
function init() {
$('.draggable').draggable({
containment: '#maincontain',
stack: '.bankbox div',
cursor: 'move',
revert: true
});
$('.judge').droppable({
drop: handleDropEvent
});
}
function handleDropEvent(event, ui) {
var draggable = ui.draggable;
ui.draggable.position({
of: $(this),
my: 'center bottom',
at: 'center bottom'
});
alert('The square with ID "' + draggable.attr('id') + '" was dropped onto me!');
}
...so what I need to do is get the 'draggable.attr('id') as is displayed in the alert, then create something in the handleDropEvent that says... HIDE all divs in .lawyers div, except those with a class equal to draggable.attr('id')
I've tried hacking it together but not getting the result I'm after
Hope it isnt too confusing, thanks for any advice
untested but your handleDropEvent should look similar to this...
function handleDropEvent(event, ui) {
var draggable = ui.draggable;
ui.draggable.position({
of: $(this),
my: 'center bottom',
at: 'center bottom'
});
alert('The square with ID "' + draggable.attr('id') + '" was dropped onto me!');
//Add these lines:
var lawyers = $('.lawyers .lawyer');
lawyers.not('.'+draggable.attr('id')).hide();
lawyers.filter('.'+draggable.attr('id')).show();
}
here is a working fiddle:
http://jsfiddle.net/g30rg3/c3Dt9/1/
Check this page:
http://api.jqueryui.com/droppable/#event-drop
Hmm - i usually have the droppable area named droppable ...
Think it will be something like this:
$( ".droppable" ).droppable({
drop: function( event, ui )
{
$( ".blackBox" ).addClass('hideBox');
}
});
Then use the hideBox class that has now appended itself to blackBox to hide??
Check the info in that link though i think it might be what you need. Or pop it into codepen so people can play :)
You just have to add
$('.lawyers').not('.' + draggable.attr('id')).hide();
after the ui.draggable.position command.

jQuery multi-draggable

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

Categories