I have two set of draggable and two sets of dropable elements.
What I want is the first set of draggable elements to be droppable only inside the first set of droppables.
The second set of draggables should be droppable only to inside the second set of droppables.
A code snippet:
// this can be dropped only inside .drop elements
$('.drag').draggable({ revert: true });
$('.drop').droppable({
drop: function() {
//
}
});
// this can be dropped only inside .drop2 elements
$('.drag2').draggable({ revert: true });
$('.drop2').droppable({
drop: function() {
//
}
});
So a user won't be able to drop element with .drag class to .drop2 container.
This is what you want.
Use Accept property of droppable widget and revert property of draggable widget to achieve this.
Related
I am new with learning jQuery UI and I am having a bit of trouble.
I am trying to create a droppable element, that can be dropped in divs with a certain class.
I have this working (so it the element will drop in that class), but I would want to "update" the old class, when the element is dropped into a new class.
http://jsfiddle.net/nxkLf1y9/1/
My fiddle shows the example (so it can be dropped in any element with the class "droppable" (to show this, the class will turn green.) When i drop the element into the next class, I want the color of the old class to revert back to normal, and for the new class to be green (where the element currently is sitting.)
so drop the box in the first div, the div will turn green, it won't drop in the 2nd div because it doesn't have the class "droppable", drop it in the 3rd div, and it will turn green, but the first box is still green too.
My js.
jQuery(function() {
jQuery( "#draggable" ).draggable({revert: "invalid"});
jQuery( ".droppable" ).droppable({
drop: function( event, ui ) {
jQuery( this )
.css({backgroundColor:'green'});
jQuery('#draggable').appendTo('#droppable')
}
});
});
Thanks for the help!
What you can do is use a class instead of inline styles:
Fiddle Example
jQuery(function() {
jQuery("#draggable").draggable({
revert: "invalid"
});
jQuery(".droppable").droppable({
drop: function(event, ui) {
//Remove Class of previous active
jQuery('.active').removeClass('active');
//Make this active
jQuery(this)
.addClass('active');
jQuery('#draggable').appendTo('#droppable')
}
});
});
CSS
.droppable.active {
background: green;
}
I have an issue regarding jquery Ui droppable.
I need to drop an element before or after the element it's dragged over. Is there anyway to detect which element it's over, and then append/prepend it in the parent container.
Right now, I just drops in the end of the div, because of append, I'm a little clueless.
I made a fiddle to hopefully better illustrate my issue:
http://jsfiddle.net/tsxzf80u/
$('section').droppable({
accept:'.dragme',
drop:function(event, ui){
var div = $("<div />").addClass('full').html('test');
$(this).append(div);
}
});
Thanks in advance
If you make each of the divs inside of the section individually droppable, then use after(), seems to do what you want.
$('#fullId1, #fullId2').droppable({
accept: '.dragme',
drop: function (event, ui) {
var div = $("<div />").addClass('full').html('test');
$(this).after(div);
}
});
http://jsfiddle.net/tsxzf80u/2/
I want it to be possible to drag (draggables) several HTML elements into several other HTML elements. (droppables)
I found the jQuery UI draggable/droppable.
Currently, I define all li elements inside an ul as draggable. I also have three divs which accept all the draggable li elements.
<ul>
<li>foo</li>
<li>bar</li>
<li>baz</li>
</ul>
Defining them as draggable:
$('li').draggable({ revert: 'invalid' });
My droppable divs:
<div class="droppable" id="div1"></div>
<div class="droppable" id="div2"></div>
<div class="droppable" id="div3"></div>
Make the divs droppable:
$('div.droppable').droppable({ accept: 'li', drop: funcDrop, out: funcOut });
I now want that only one li element can be dropped into a div at the same time. I am trying to do that by disabling the droppability inside the div element I dropped the draggable, like so:
funcDrop = function(event, ui) {
$(this).droppable('disable');
}
This works. Now I am not able drop any further li elements into this div. The problem is, how/when to enable the div again? Clearly if the contianing draggable was removed. So I tried to enable the div inside funcOut:
funcOut= function(event, ui) {
strIdValue = event.target.id;
$('#' + strIdValue).droppable('enable');
}
But this does not work.
It seems also that I can't work with $(this) selector inside the funcOut.
Does anyone have a hint?
Best regards
I use jQuery 2.1 and UI 1.10.4
I figured out an alternative solution:
It seems if an element once was disabled, the out event does not fire and I am therefore not able to enable it again using the element itself. So what I did, is this:
If you drop a draggable element on a droppable element, the drop event is triggered and does this:
$(this).droppable({ accept: ('#' + $(ui.draggable).attr('id')) });
So the droppable is not disabled, but accepts only the received draggable by its unique HTML id. Because it is not disabled the out event will now be triggered. This is what I do in it:
$(this).droppable({ accept: 'li' });
Now the droppable accepts all HTML li elements as ever. Now each droppable accepts only one draggable. The droppable is now "locked" if it receives a draggable.
I wonder if this is a valid solution or just a dirty hack.
(Possible duplicate/related: jQuery UI - Droppable only accept one draggable)
Based on the JSFiddle you've shared (which currently is not doing what you asked), here is a modified version of the droppable function that you can use to achieve the desired result:
$(".droppable").droppable({
accept: "li",
drop: function(event, ui) {
$(this).droppable('option', 'accept', ui.draggable);
},
out: function(event, ui){
$(this).droppable('option', 'accept', 'li');
}
});
As the other answer stated, the trick is to make our droppable div accept 'ui.draggable', being ui the item that is currently being dragged to our droppable div.
Hope that helps!
(EDITED: Grammar)
I'm creating a management application with some element on the page. Those element can be dragged around. but in the page you have 2 seperate places where it could be dragged.
So is there a way you can set more then one class in the containment option of the jQuery draggeble?
Thanks
Per containment:
Multiple types supported:
Selector: The draggable element will be contained to the bounding box of the first element found by the selector. If no element is
found, no containment will be set.
Element: The draggable element will be contained to the bounding box of this element.
String: Possible values: "parent", "document", "window".
Array: An array defining a bounding box in the form [ x1, y1, x2, y2 ].
Via https://api.jqueryui.com/draggable/#option-containment - #Vaindil mentioned this
The following is a "creative" answer regarding 'multiple containment selectors' not being directly supported by jQuery UI sortable. This is an "idea" which may help; in practice it did for my app:
You could set containment using Selector or Element (see above) mode with a higher-level parent element; meaning not just the actual 'parent' but maybe something a few DOM elements higher. (If you're using sortable, you can connect the two.) Then use the draggable method over to determine if you're on a dropzone.
You can also instantiate droppable on each dropzone. Here's some code that can help you determine what element you're over --- whereas this is highlighting all dropzone targets with a light-yellow bg class ('highlight') and the specific dropzone hovered with a bright-yellow bg class ('current-target'). Maybe you can use something like this to show the user where they're allowed to drop.
function droppable_on_deactivate_out() {
$('.dropzone').removeClass('target');
this.$dragElm.removeClass('over-outermost-parent');
this.$sortableElm.sortable('option', {
connectWith: this.activateConnectWith,
axis: 'y',
tolerance: 'pointer'
});
$(this).off('mousemove.droppableNamespace mouseout.droppableNamespace'); // Cleanup listeners
self.showGrid.tbody.animate({scrollTop: this.scrollBackTo}, 250);
}
$('.draggable').draggable({
// Or you could instantiate `sortable` instead of this `draggable` fn
});
$('#outermost-parent').droppable({
accept: '.draggable',
activate: function (droppableActivateEvent, ui) {
this.$dragElm = $(ui.draggable.context);
this.activateConnectWith = this.$dragElm.sortable('option', 'connectWith');
},
deactivate: droppable_on_deactivate_out,
over: function () {
$(this).on('mousemove.droppableNamespace', function (mousemoveEvent) {
$(mousemoveEvent.target)
.addClass('current-target')
.on('mouseout.droppableNamespace', function () {
$(this)
.removeClass('current-target')
.off('mousemove.droppableNamespace mouseout.droppableNamespace'); // Cleanup listeners
});
});
$('.dropzone').addClass('target');
this.$dragElm
.addClass('over-outermost-parent'); // Indicate something on UI
.sortable('option', {
connectWith: '#outermost-parent',
axis: false,
tolerance: 'intersect'
});
},
out: droppable_on_deactivate_out
});
Thus related to your containment question, depending on where the mouse/drag is (what it is over) you can alter the UI or the draggable option axis (etc) on-the-fly. Try some creative solutions like this; I hope it helps!
set the ui containment options like following:
containment:'selector_1, selector_2,...'
I am actually trying to make a .php page where I am going to have 3 draggable elements which have to be dragged to 3 droppable elements -each draggable to a droppable, and they are unique, so one each droppable will only accept a certain draggable.
The thing is that I need to control that all of the elements have been dragged to the right spot, in which case I should redirect the user for example to success.php, otherwise, if some of the elements were dragged to the wrong droppable, the user have to go to for example failure.php.
Is there anyway for example to save a certain value in a $_SESSION in PHP in order to know that all the draggables have been dropped in the right place?
This is the code for the drag&drop:
$(function() {
$("#draggableLeiden").draggable();
$("#draggableTheHague").draggable();
$("#draggableRotterdam").draggable();
$("#droppableLeiden").droppable({
accept: '.imgLeiden',
drop: function(event, ui)
{
$(this).addClass('ui-state-highlight');
}
});
$("#droppableTheHague").droppable({
accept: '.imgTheHague',
drop: function(event, ui)
{
$(this).addClass('ui-state-highlight');
}
});
$("#droppableRotterdam").droppable({
accept: '.imgRotterdam',
drop: function()
{
$(this).addClass('ui-state-highlight');
//var activeClass = $(this).droppable('option', 'activeClass','ui-state-highlight');
}
});
});
I am trying to do this for example getting the active class of the droppable elements to see if it matches 'ui-state-highlight', but actually, that tag is gonna be executed everytime the page reloads, so if I try to insert any code into the
drop: function()
it will always execute.
Thanks a lot in advance!
Use the revert option instead. When a draggable element is dropped on anything but the accepted droppable element then it will slide back to its original spot. Does this work for you?
Are you by chance looking for ui.draggable it holds the element that was dropped?
http://jqueryui.com/demos/droppable/
$('#target').droppable({
drop : function(event,ui){
if($(ui.draggable).attr('id') == "correcttarget")
{
window.location = "yay.php";
}
else
{
window.location = "awwww.php";
}
}
})