Im using jquery-UI droppable, When I drag the small green box over the blue ones from top to bottom everything works as I want but when I drag the box from bot to top the parent box trigger the over event and gets highlighted, i want that just one element being highligthed at same time, one of the siblings or the parent.
HTML:
<div class="box">Drag me</div>
<div class="drop">Drophere
<div class="drop">Drophere</div>
<div class="drop">Drophere</div>
<div class="drop">Drophere</div>
</div>
JS:
$(".box").draggable();
$(".drop").droppable({
accept: ".box",
hoverClass: "drophere",
greedy:true
});
http://jsfiddle.net/Deivid11/44bg1bz4/4/
You can check on over event if a child .drop has class .drophere and if so, remove .drophere from the parent. Like this:
over: function (e, ui) {
$('.drop .drophere').parent().removeClass('drophere');
}
http://jsfiddle.net/p1wjk56h/1/
Related
I'm trying to deal with some sort of toggle view effect on a HTML unordered list.
What I'm trying to do is switch DIV views inside a LI, using jquery (not jquery mobile), when I touch it on a touch screen device and restore view when tapping somewhere else outside the current LI.
this is a HTML example:
<ul>
<li class="item1">
<div class="div1">Info</div>
<div class="div2" style="display:none;">Tools</div>
</li>
<li class="item2">
<div class="div1">Info</div>
<div class="div2" style="display:none;">Tools</div>
</li>
<li class="item3">
<div class="div1">Info</div>
<div class="div2" style="display:none;">Tools</div>
</li>
</ul>
So basically if I tap on "item2", "div1" should hide and "div2" should be visible, inside "div2" are some buttons that you can interact with. But then, when I touch outside "item2", "div1" should be visible again and "div2" should hide.
I tried using nouseenter and mouseleave with jquery, but it causes a mess when you try to scroll or tap the other LI elements in the same list, also tried using toggle, but so far no luck. Now I can't find a simple but effective way to achieve what I want, hope you guys can help me with this.
Thanks!
EDIT:
Here is a working example that doesn't work properly on touch devices http://jsfiddle.net/T5HMt/44/
As per my understanding you want corresponding div2 to show and to hide div1 when li is tapped (example- On tap event on "item2", "div1" of "item2" should hide and "div2" of "item2" should be visible). And you want to show "div1"and hide "div2" only when user taps somewhere outside the li (outside any LI mentioned in your question).
Please check this code if it helps you.
$(".item1, .item2, .item3").click(function(){
$(this).children(".div2").css("display", "block");
$(this).children(".div1").css("display", "none");
});
$(document).click(function(e) {
var target = e.target;
if (!$(target).parents().is('.item1') && !$(target).parents().is('.item2') && !$(target).parents().is('.item3')) {
$(".div2").css("display", "none");
$(".div1").css("display", "block");
}
});
Working fiddle - http://jsfiddle.net/Ashish_developer/5jpyzkmt/
In the fiddle I have given border to LI just to illustrate it.
Well it looks like I found a way to solve my own problem with a solution very similar to the one provided by Tushar Raj. Instead of displaying the hidden div on mouse over I did it on a click event and then hide it on mouse leave.
The thing is that mousenter triggers two things at the same time on touchscreens, the first thing is a 'mouseenter' event and then a 'touchstart' event, so if you have links inside the div that is being displayed on the mouseenter event, they will also be 'clicked'.
$(document).on({
click: function () {
$(this).find('.main').hide();
$(this).find('.second').show();
},
mouseleave: function (event) {
$(this).find('.main').show();
$(this).find('.second').hide();
}
},'.search');
And a working example it works as expected on touch screens
Thanks to everyone for helping me out
Try hover . It should work for touch devices too .
$('.item1,.item2,.item3').on('hover',function(){
$(this).find('.div1').hide();
$(this).find('.div2').show();
},function(){
$(this).find('.div1').show();
$(this).find('.div2').hide();
});
I have a page with two DIVs, both of which are droppable. One of them (#droppable2) is initially hidden and is only shown when I hover the draggable item over the first DIV #droppable (with the dropover event). Example see here: http://codepen.io/anon/pen/AdLJr
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
<div id="droppable">Drop here 1</div>
<div id="droppable2" style="top: 300px; display: none;">Drop here 2</div>
<div id="draggable">Drag me</div>
<div id="log"></div>
JS:
$( "#draggable" ).draggable();
$( "#droppable,#droppable2" ).droppable({
drop: function() {
$('#log').html($('#log').html() + '<br>DROP');
},
over: function() {
$('#log').html($('#log').html() + '<br>over');
$('#droppable2').show();
}
});
However, when I now hover the draggable item over the second DIV, its dropover event is not fired like it should. Only when drop the draggable item and then pick it up again does it seem to work. The drop event already works on the first try though.
Any ideas what's causing this? I assume this might be a bug?
Ok here is an actual answer. Change your first JS line to this:
$( "#draggable" ).draggable({ refreshPositions: true });
From the jQuery UI draggable docs for the refreshPositions option:
If set to true, all droppable positions are calculated on every mousemove.
Caution: This solves issues on highly dynamic pages,
but dramatically decreases performance.
I also did it in that way with this line $( "#draggable" ).draggable({ refreshPositions: true });, but using a class draggable, but only works for once. I can only drag and drop for once one element. And if there is another element in the place where a droped they all don't work
I am trying to drop an element on top of multiple droppable DIVs, but I have a problem with event bubbling. The droppable event gets executed multiple times, based on how many elements are layered on top of each other. I would like to execute it only for the last/top element.
Please see this jsFiddle.
HTML:
<div id="1" class="box droppable">1
<div id="2" class="box droppable">2
<div id="3" class="box droppable">3</div>
</div>
</div>
<div id="drag" class="draggable">Drag me! I dare you!</div>
<div id="output"></div>
jQuery:
$(function () {
$(".draggable").draggable({
revert: "invalid"
});
$(".droppable").droppable({
tolerance: 'pointer',
drop: function (event, ui) {
content = $('#output').html();
$('#output').html(content + "Dropped "+ui.draggable.prop('id') + " on " +$(this).attr('id')+".<br/>");
}
});
});
When you drop the draggable on element 1 it will say that you dropped it on 1. That's correct. If you drop it on element 3, it will say you dropped it on 1,2,3. I need to limit this only to the third/top-most element. How can I achieve this please?
I've experienced this in the past in a different situation, where it required a confirmation, so the droppable target ID could be stored in an invisible field (the last value), but I need to make it directly this time, no workarounds :(
Thanks!
If I only weren't so lazy to browse around the documentation for a bit. The solution to this problem can be found here. By specifying the greedy option user can limit the affected droppable elements.
In other words
$(".droppable").droppable({
tolerance: 'pointer',
greedy: true, //limit to only top-most droppable element
drop: function (event, ui) {
content = $('#output').html();
$('#output').html(content + "Dropped "+ui.draggable.prop('id') + " on " +$(this).attr('id')+".<br/>");
}
});
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 have a list of draggable items, and I wish to be able to drag them onto a sortable content block. Here’s my markup:
<div class='items'>
<div class="one">One</div>
<div class="two">Two</div>
</div>
<div class="content">
<div class="block">Foo</div>
<div class="block">Bar</div>
</div>
The thing is, that I want the dragged item to "become" a block as soon as the dragging starts and remain a block when it’s dropped. I have tried this:
$('.items div').draggable({
helper: function(e) {
return $('<div>').addClass('block').text( $(e.target).text() );
},
connectToSortable: ".content"
});
$('.content').sortable();
Fiddle: http://jsfiddle.net/MF4qu/
But even if I create a custom helper that looks like a block, it reverts back to the original dragged element as soon as it’s dropped. Does anyone know how to properly insert a block in my example page? I already looked through the UI API but I can’t figure it out.
When the draggable element is dropped into sortable, it triggers the sortable update event. One solution is to listen to that event, and turn the dropped item into a block:
$('.items div').draggable({
helper: function(e) {
return $('<div>').addClass('block').text( $(e.target).text() );
},
connectToSortable: ".content"
});
$('.content').sortable({
update: function (event, ui) {
ui.item.addClass('block');
}
});
Working demo: http://jsfiddle.net/DaXuT/1/