Prevent dropping to div if it's not empty - javascript

I use jQuery UI .droppable for dropping elements to divs. Now I need to prevent dropping to divs with class .box if they are not empty.
I tried:
if ($('.box').is(':empty')) {
$(".box").droppable({
});
}
But this makes all .box divs non-droppable whether they are empty or not.

The code below will check, does element with class box has any text or other elements inside. You can try to put text or add child elements to that div to be sure, that it's working:
if (!$('.box').text() && $('.box').children().length === 0) {
console.log("droppable");
/*$(".box" ).droppable({
// code here
});*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box"></div>

So the solution is:
$(".box").droppable({
accept: function() {
return $(this).find("*").length == 0;
},
drop: function(event, ui) {
var $this = $(this);
$this.append(ui.draggable.css({
top: 0,
left: 0
}));
}
});

Related

jQuery - creating a new draggable div on mousedown which can then be dragged in the same action

I want to dynamically create a draggable div on mousedown, which within the same mousedown event can then be dragged into a droppable area and dropped.
The point that I have got to so far is that a new draggable div is created on mousedown and that div then follows the cursor. But it cannot be dropped into the droppable area.
JS Fiddle here - http://jsfiddle.net/rqyv6bpg/
The jQuery code:
jQuery(document).ready(function ($) {
//on mousedown, creates a new draggable div in the cursor position
$(".search-result-container").mousedown(function(e){
var x = e.pageX + 'px';
var y = e.pageY + 'px';
$('<div/>', {
"class": "test",
text: "Draggable track that can be dropped into droppable queue!",
}).css({
"position": "absolute",
"left": x,
"top": y,
"z-index": 1000
}).draggable()
.appendTo($(document.body))
});
//in order to get the newly created div to instantly follow the cursor
$(document).on('mousemove', function(e){
$('.test').css({
left: e.pageX,
top: e.pageY
});
});
$( "#queue-bar" ).droppable();
});
Help would be greatly appreciated! Thanks in advance.
If I understood correctly, you are looking for the helper option of draggable widget.
$(document).ready(function($) {
$(".search-result-container").draggable({
helper: "clone", // use a clone for the visual effect
revert: false
});
$("#queue-bar").droppable({
accept: "article",
drop: function(event, ui) {
ui.draggable.clone().appendTo(this); // actually append a clone to the droppable
}
});
});
$(document).ready(function($) {
$(".search-result-container").draggable({
helper: "clone", // use a clone for the visual effect
revert: false
});
$("#queue-bar").droppable({
accept: "article",
drop: function(event, ui) {
ui.draggable.clone().appendTo(this); // actually append a clone to the droppable
}
});
});
.search-result-container {
background-color: red
}
#queue-bar {
background-color: blue
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<article class="search-result-container">This is a track with lots of information</article>
<div id="queue-bar">This is the droppable area</div>
You can also create a custom helper by returning an element to be used as helper as shown below:
$(document).ready(function($) {
$(".search-result-container").draggable({
helper: function(){
// return a custom element to be used for dragging
return $("<div/>",{
text: $(this).text(),
class:"copy"
})
}, // use a clone for the visual effect
revert: false
});
$("#queue-bar").droppable({
accept: "article",
drop: function(event, ui) {
//you might want to reset the css using attr("style","")
ui.helper.clone().appendTo(this); // actually append a clone of helper to the droppable
}
});
});
.search-result-container {
background-color: red;
}
#queue-bar {
background-color: blue;
}
.copy{
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
<article class="search-result-container">This is a track with lots of information</article>
<div id="queue-bar">This is the droppable area</div>
Updated your fiddle, it works now!!
http://jsfiddle.net/rqyv6bpg/2/
Here is the JS code:
$( ".text" ).draggable({helper:'clone'});
$( "#queue-bar" ).droppable({
drop: function( event, ui ) {
$( this ).append( "<br/>"+ui.draggable.html() );
}
});

When a dragged element touches other element / leave other element

I have a element (#dot) which can be dragged. The dragged element (#dot) is just allowed to be in multiple (.way)s but when (#dot) leaves this element then a function should start (for now a alert is enough). I have search on stackoverflow and on other pages but I dont find out somethings like this.
Fiddle
Here is my JS:
$(document).ready(function (){
$('#dot').draggable({
containment: "#world",
});
});
Html:
<div id="world">
<div id="dot"></div>
<div class="way">
</div>
</div>
For now an alert is enough...
My question is, how can i check if the element touches on other element?
Updated answer:
Demo: http://jsbin.com/yorohimi/4
Seems like you can use jQuery draggable and droppable for this:
JS:
$(document).ready(function () {
$('#dot').draggable();
$('.way').droppable({
accept:'#dot',
tolerance:'fit',
over:function(event,ui){
$('p').text('moved inside way');
$('#world').removeClass('green');
},
out:function(event,ui){
$('p').text('moved outside way');
$('#world').addClass('green');
}
});
});
The key is to use tolerance:fit here in droppable. Whenever #dot touches #world the color of #world is changed for visual feedback.
Following method will work only for single .way.
You can compare the position using getBoundingClientRect method and execute your code.
Fiddle: http://jsfiddle.net/9SJam/4/
JS:
$(document).ready(function () {
$('#dot').draggable({
axis: "y",
containment: "#world",
drag: function (event, ui) {
drag_handler($(ui.helper));
}
});
});
function drag_handler(elem) {
var p = elem[0].getBoundingClientRect();
var P = $('.way')[0].getBoundingClientRect();
if ((P.top > p.top) || (P.bottom < p.bottom)) {
console.log('touched');
$('#world').addClass('color');//For visual feedback
} else {
$('#world').removeClass('color'); //For visual feedback
}
}
You need to declare #world as droppable, then you can use it's over event to trigger your function, which is triggered when an accepted draggable is dragged over the droppable.
something like
$( "#world" ).droppable({
over: function() {
// Your logic
}
});

jQuery hide parent block if all childs hidden

The question is how to hide parent block if all childs are hidden, and display it if they are visible again?
Is it possible to "monitor" block status with jQuery?
jsFiddle example - here red block must automatically hide if we hide yellow and green blocks.
Html
<div id="mother">
<div class="child1"></div>
<div class="child2"></div>
</div>
CSS
#mother {
width:200px;
height:200px;
background:red;
}
.child1, .child2 {
width:100px;
height:100px;
background: orange;
}
.child2 {
background:green;
}
JavaScript
$(function() {
var childs = $("[class^=child]");
childs.click(function() {
$(this).hide();
});
});
Try
$(function () {
var childs = $("[class^=child]");
childs.click(function () {
$(this).hide();
//check if any child is visible, if not hide the mother element
if(!childs.filter(':visible').length){
$('#mother').hide()
}
});
});
Demo: Fiddle
You can check the length of visible elements inside #mother div by using :visible selector along with .length, if it's equal to 0 then hide #mother:
$(function () {
var childs = $("[class^=child]");
childs.click(function () {
$(this).hide();
if ($("#mother").find(":visible").length == 0)
$("#mother").hide();
});
});
Fiddle Demo
Try this in child click event handlers:
if($('#mother').children(':visible').length == 0) {
$('#mother').hide();
}
Working Demo
You can try so:
$(function() {
var childs = $("[class^=child]");
childs.click(function() {
$(this).hide();
var $parent = $(this).parent();
var $child = $parent.find('div:visible');
if(!$child.length){
$parent.hide();
}
});
});

Add div on hover using jquery

I build a project something like "trip planner" but I need to add on my cloned div-object an verticl line on left border with css:
.line
{ width:5px, height:200px; background:red;}
so to be something like this (you can see on hover an vertical line)
I was try to do this with code:
$(function() {
//$( ".draggable" ).resizable();
$( ".draggable" ).draggable({
revert: 'invalid',
helper:"clone",
snap: "#drop_here td",
opacity: 0.7
});
$( "#drop_here td" ).droppable({
// accept only from left div,
// this is necessary to prevent clones duplicating inside droppable
accept: '#left .draggable',
drop: function( event, ui ) {
// 4 append clone to droppable
$( this ).append(
// 1 clone draggable helper
$(ui.helper).clone()
// 2 make the clone draggable
.draggable({
containment:"#table",
snap: "#drop_here td"
})
// 3 make the clone resizable
.resizable());
//HERE IS MY PROBLEM IN CODE
$(".draggable").hover(function() {
$(this).append("<div class='line'></div>");
}, function() {
$(this).removeClass("line");
});
}
});
});
but dont work!
DEMO
The first problem is that your css has a , insted of a ;
.line {
display: none;
width: 5px;
height: 200px;
background: red;
}
Then for the jquery modify like this:
$('.draggable').hover(function(){
$(this).find('.line').show();
}, function() {
$(this).find('.line').hide();
});
In your markup place a .line (only one) just after every .draggable, but not on hover or it will append it every time you hover the .draggable creating tons of .lines
JSfiddle : http://jsfiddle.net/steo/JB7jN/1/
You have to bind the .hover() in the document ready like this:
$(document).ready(function(){
$(".draggable").hover(function() {
$(this).append("<div class='line'></div>");
}, function() {
$(this).children('.line').remove();
});
});
Your "hover out" handler removes the class from $(this) -- not from the appended child.
It's probably bad practice to dynamically create elements on hover, that are never deleted & will presumably gradually fill the document with garbage.
if you only want to add the line to the clone add the start property to the draggable options like this:
$( ".draggable" ).draggable({
revert: 'invalid',
helper:"clone",
snap: "#drop_here td",
opacity: 0.7,
start: function(event, ui){
var clone = $(ui.helper);
if (clone.children('div.line').length == 0)
clone.append("<div class='line'></div>");
}
});
Tested this and it works like a charm.. Dont forget to remove this part:
$(".draggable").hover(function() {
$(this).append("<div class='line'></div>");
}, function() {
$(this).removeClass("line");
});

How do I select a div with its children as handles using jQuerys Selectable?

I have a div which contains two elements which dont fill up that div. I want selecting the elements to select the containing div instead. Also, I want that clicking in the div but outside the elements doesnt select the element (and triggers a deselect). How do i do this?
fiddle: http://jsfiddle.net/U5cmy/1/
$("#all").on("mousedown", function(event) {
if (!$(event.target).is(".item-top, .item-bottom") && !$(event.target).hasClass("ui-selected")) {
event.stopImmediatePropagation();
return false;
}
});
$('#all').selectable({
start: function(event, ui) {
$(this).data("isDeselect", $(event.target).is(".item"))
},
selected: function(e, ui) {
if ($(this).data("isDeselect") === true) {
$(ui.selected).removeClass("ui-selected");
ui.selected = null;
}
}
});
fiddle: http://jsfiddle.net/1stein/sNMw3/

Categories