Getting old size values from jquery.ui.resizable - javascript

I am trying to get the new size of a div after resizing. However when using ui.size.height or $(e.target).height() I am getting instead the original height of the element.
function allowResizing(el){
$(el).resizable({
animate: true,
containment: "parent",
helper: "ui-resizable-helper",
minWidth: 250,
minHeight: 250,
grid: [20, 20],
stop: function( e, ui ) {
console.log("height: " + $(e.target).height())
console.log("height: " + ui.size.height)
console.log("originalHeight: " + ui.originalSize.height)
}
});
}
All three logs write the same value. When I try this code on any other div on another page I get the right values.
My hmtl:
<style>
.containment-wrapper > .row{
border: 3px solid white;
width: 100%;
height: calc(100vh - 200px);
min-height: 200px;
position:relative;
}
.ui-resizable-helper {
border: 2px dotted #b1b1b1;
}
</style>
<div class="containment-wrapper">
<div class="row">
<div id="resizable" class="ui-draggable ui-draggable-handle" style="position: absolute !important; outline: 1px solid white;">
<div class="Container_Header">
<span style="display: block; padding: 0 10px" class="Text_H2">$title</span>
</div>
<p style="padding: 10px">
Some text
</p>
</div>
<script type="text/javascript">
allowResizing("#resizable")
</script>
</div>
</div>
I also use ui.Draggable on the same element but also tried without it.
Appreciate every help. Thank you

Since you have defined a Helper, you will want to review the Size of that element.
$(function() {
function allowResizing(el) {
$(el).resizable({
animate: true,
containment: "parent",
helper: "ui-resizable-helper",
/*
minWidth: 250,
minHeight: 250,
grid: [20, 20],
*/
resize: function(e, ui) {
log("Height: " + ui.size.height);
},
stop: function(e, ui) {
log("El height: " + $(ui.element).height());
log("Stop height: " + ui.size.height);
log("Original Height: " + ui.originalSize.height);
log("Helper Height: " + ui.helper.height());
}
});
}
function log(str) {
var log = $("#log").length ? $("#log") : $("<div>", {
id: "log"
}).appendTo("body");
log.append(`<p>${str}</p>`).scrollTop(log.prop("scrollHeight"));
}
allowResizing("#resizable");
});
.containment-wrapper>.row {
border: 3px solid white;
width: 100%;
height: calc(100vh - 200px);
min-height: 200px;
position: relative;
}
.ui-resizable-helper {
border: 2px dotted #b1b1b1;
}
#log {
font-size: 65%;
height: 4em;
overflow: auto;
}
#log p {
padding: 0;
margin: 0;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="containment-wrapper">
<div class="row">
<div id="resizable" style="position: absolute !important; outline: 1px solid white;">
<div class="Container_Header">
<span style="display: block; padding: 0 10px" class="Text_H2">$title</span>
</div>
<p style="padding: 10px">
Some text
</p>
</div>
</div>
</div>

Related

jqueryUI, accept if 'drop to' container meets requirements

the JqueryUi documentation mentions that there is a way to check if element that user 'drag and drop' meets the requiremments by using:
accept: function(el) {
return CHECK_REQUIREMENTS;
}
but how is it possible to check if the target element (the container the user is trying to place the item into) that meets some criteria?
My code is:
<html>
<head>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<style>
* * {
box-sizing: border-box;
}
.search-container {
display: flex;
flex-wrap: wrap;
width: 33%;
min-height: 200px;
border: 1px solid red;
}
.search-item {
border: 1px solid grey;
text-align: center;
margin: 5px;
width: 150px;
max-width: 300px;
flex-basis: 150px;
flex-grow: 1;
height: 80px;
}
</style>
</head>
<body>
<div id="myContainer">
<div id="firstContainer" class="search-container acceptableContainer" style="float:left">
<div class="search-item acceptable">first</div>
<div class="search-item acceptable">two</div>
<div class="search-item acceptable">three</div>
<div class="search-item acceptable">four</div>
<div class="search-item acceptable">five</div>
<div class="search-item">six</div>
<div class="search-item">seven</div>
<div class="search-item">eight</div>
<div class="search-item">nine</div>
</div>
<div id="secondContainer" class="search-container" style="float:left">
</div>
<div id="thirdContainer" class="search-container acceptableContainer">
</div>
</div>
</body>
<script>
$(".search-item").draggable({
revert: 'invalid'
});
$(".search-container").droppable({
accept: function(el) {
return el.hasClass('acceptable');
},
drop: function( event, ui ) {
var droppable = $(this);
var draggable = ui.draggable;
draggable.appendTo(droppable);
draggable.css({top: '0px', left: '0px'});
}
});
</script>
</html>
So this code checks if 'drag and drop' has class acceptable.
For example, I would like to check if target container has class acceptableContainer and accept the operation only if it returns true (so secondContainer can not be target container).
How is it posisble to deal with that?
Inside .drop event, you check the condition and if met, then proceed with the operation like appending to new location etc. Also modify css properties to match positioning in new location, and if conditions are not met, set the 'revert' option of draggable to 'true',
Below part might not be necessary I got mixed results
[then reset it to 'invalid' inside .stop event of draggable. Key is .stop of draggable is called after .drop of droppable.]
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Droppable </title>
<link rel="stylesheet" href="jquerylib/jquery-ui.css" />
<script src="jquerylib/jquery.js"></script>
<script src="jquerylib/jquery-ui.js"></script>
<!--<link rel="stylesheet" href="css/styles.css" />-->
<style>
.boxMain {
width: 40%;
height: 400px;
background-color: yellow;
border: 3px solid black;
color: black;
margin: 0px auto;
/*padding: 15% 15% 0% 15%;*/
float: left;
}
.box {
width: 100px;
height: 100px;
background-color: lightpink;
border: 1px solid black;
border-radius: 15px;
color: white;
margin: 5px;
z-index: 99;
float: left;
/*position: absolute;*/
}
</style>
<!--<script src="script/02droppable.js"></script>-->
<script>
$(document).ready(function () {
$(".box").draggable({
revert: "invalid",
stop: function () {
console.log("stopped");
$(this).draggable("option", "revert", "invalid");
}
});
$(".boxMain").droppable({
accept: ".box",
drop: function (e, u) {
console.log("dropped");
if ($(this).hasClass("AcceptingBox")) {
u.draggable.appendTo($(this));
u.draggable.css({
"left": 0,
"top": 0
});
} else {
console.log("No");
u.draggable.draggable("option", "revert", true);
}
}
});
});
</script>
</head>
<body>
<div style="height:200px;">
<div id="sub1" class="box" style="background: red"></div>
<div id="sub2" class="box" style="background: green"></div>
<div id="sub3" class="box" style="background: blue"><p>Click</p></div>
<div id="sub4" class="box" style="background: aqua"><p>Click</p></div>
</div>
<div id="main1" class="boxMain AcceptingBox">Accepting</div>
<div id="main2" class="boxMain"></div>
<!--<div id="main2" class="boxMain"></div>-->
</body>
</html>
Consider the following.
$(function() {
$(".search-item").draggable({
revert: 'valid'
});
$(".search-container").droppable({
accept: '.acceptable',
drop: function(event, ui) {
var droppable = $(this);
var draggable = ui.draggable;
if (droppable.hasClass("acceptableContainer")) {
draggable.appendTo(droppable);
draggable.css({
top: '0px',
left: '0px'
});
} else {
return false;
}
}
});
});
* * {
box-sizing: border-box;
}
.search-container {
display: flex;
flex-wrap: wrap;
width: 33%;
min-height: 200px;
border: 1px solid red;
}
.search-item {
border: 1px solid grey;
text-align: center;
margin: 5px;
width: 150px;
max-width: 300px;
flex-basis: 150px;
flex-grow: 1;
height: 80px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div id="myContainer">
<div id="firstContainer" class="search-container acceptableContainer" style="float:left">
<div class="search-item acceptable">first</div>
<div class="search-item acceptable">two</div>
<div class="search-item acceptable">three</div>
<div class="search-item acceptable">four</div>
<div class="search-item acceptable">five</div>
<div class="search-item">six</div>
<div class="search-item">seven</div>
<div class="search-item">eight</div>
<div class="search-item">nine</div>
</div>
<div id="secondContainer" class="search-container" style="float:left">
</div>
<div id="thirdContainer" class="search-container acceptableContainer">
</div>
</div>
You will need to return a false to invoke the revert upon drop. It's sort of backward logic.

Exclude element from JQuery-UI containment

I am trying to allow an element to be dragable/resizable inside of another element but not in the area of another child of that element.
Given the following table row:
I want to be able to drag and resize the blue area anywhere within the table row, but not where the grey table cell is (i.e. it would move/resize freely within the first four cells but be stopped when it reaches the last one).
I can constrain it to the table row using the containment: '.middle tr' or containment: $el.closest('tr'), (where $el is a selector for the blue element) options in JQuery.draggable and JQuery.resizable, but I haven't been able to find a way that works for excluding the last column from the containment.
How do you exclude an element from the containment area?
Example with code:
$(function() {
$("td").droppable({
drop: function(event, ui) {
var draggable = ui.draggable;
var newLeft = draggable.offset().left - draggable.closest(".middle table").offset().left;
var childNum = Math.round((newLeft + 100) / 100);
var newContainer = $(this).closest('tr').find('td:nth-of-type(' + childNum + ')');
draggable.css({
top: '',
left: ''
});
newContainer.append(draggable);
},
});
$(".planning-spot").resizable({
grid: [100, 10000000],
handles: "e",
containment: ".middle tr"
}).each(function() {
var $el = $(this);
$el.draggable({
containment: $el.closest('tr'),
axis: 'x',
});
});
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
table {
border-collapse: collapse;
overflow: hidden;
table-layout: fixed;
width: 500px;
margin: 20px;
}
tr {
position: relative;
background: #FFF;
}
td, th {
position: relative;
padding: 0;
width: 100px;
height: 30px;
border: 1px solid #000;
}
.planning-spot {
position: absolute;
top: 0;
left: 0;
height: 20px;
width: 90px;
border-radius: 10px;
margin: 5px;
text-align: center;
z-index: 1;
cursor: pointer;
color: #FFF;
width: 290px;
background: #3CF;
}
.no-planning {
background: #CCC;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>
<div class="wrapper">
<div class="middle">
<table>
<tbody>
<tr>
<td>
<div></div>
<div class="planning-spot">18 / 20</div>
</td>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
<td class="no-planning">
<div></div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
http://jsfiddle.net/xpvt214o/668937/
I'm aware that I can check the location during the drop and stop functions of droppable and resizable respectively and reverse the action if needed (which is my current solution), but I'm looking for a solution to prevent it being moved into an "unwanted" area in the first place.
You can determine the draggable area with getBoundingClientRect() and assign containment to an array wich take the width of each resizeable elements
$(function() {
$("td").droppable({
drop: function(event, ui) {
var draggable = ui.draggable;
var newLeft = draggable.offset().left - draggable.closest(".middle table").offset().left;
var childNum = Math.round((newLeft + 100) / 100);
var newContainer = $(this).closest('tr').find('td:nth-of-type(' + childNum + ')');
draggable.css({
top: '',
left: ''
});
newContainer.append(draggable);
},
});
$(".planning-spot").resizable({
grid: [100, 10000000],
handles: "e",
containment: ".middle tr"
}).each(function() {
var $el = $(this);
var bBoxTr = $el.closest('tr')[0].getBoundingClientRect();
var bBoxTd = $el.closest('tr').children(".no-planning")[0].getBoundingClientRect();
var x1 = bBoxTr.x, y1 = bBoxTr.y;
var x2 = bBoxTr.right-bBoxTd.width, y2 = bBoxTr.bottom;
$el.draggable({
// containment: $el.closest('tr'),
containment: [x1,y1,x2-$el.width()-10,y2],
axis: 'x',
});
});
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
table {
border-collapse: no-collapse;
overflow: hidden;
table-layout: fixed;
width: 500px;
margin: 20px;
}
tr {
position: relative;
background: #FFF;
}
td, th {
position: relative;
padding: 0;
width: 100px;
height: 30px;
border: 1px solid #000;
}
.planning-spot {
position: absolute;
top: 0;
left: 0;
height: 20px;
width: 90px;
border-radius: 10px;
margin: 5px;
text-align: center;
z-index: 1;
cursor: pointer;
color: #FFF;
width: 290px;
background: #3CF;
}
.no-planning {
background: #CCC;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>
<div class="wrapper">
<div class="middle">
<table>
<tbody>
<tr id="test">
<td>
<div></div>
<div class="planning-spot">18 / 20</div>
</td>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
<td class="no-planning">
<div></div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
Edit:
Since getBoundingClientRect(); is not supported by all browsers, better go with jquery features, position(), height() and width();.
See the revised snippet below, the function getDragArea returns an array with the coordinates of the drag area. I add a listener (mouseover) which permit to reset drag area when needed.
The table is wrapped in a scrolling div to test behavior.
$(function() {
$("td").droppable({
drop: function(event, ui) {
var draggable = ui.draggable;
var newLeft = draggable.offset().left - draggable.closest(".middle table").offset().left;
var childNum = Math.round((newLeft + 100) / 100);
var newContainer = $(this).closest('tr').find('td:nth-of-type(' + childNum + ')');
draggable.css({
top: '',
left: ''
});
newContainer.append(draggable);
},
});
$(".planning-spot").resizable({
grid: [100, 10000000],
handles: "e",
containment: ".middle tr"
}).each(function() {
$(this).on('mouseover',function(){
$(this).draggable({
containment: getDragArea($(this)),
axis: 'x',
});
})
});
function getDragArea($el){
var $tr = $el.closest('tr');
var $tds = $el.closest('tr').children(".no-planning");
var width = $el.closest('tr').width()-$tds.width()*$tds.length;
var height = $el.closest('tr').height();
var position = $el.closest('tr').position();
var x1 = position.left, y1 = position.top;
var x2 = x1+width, y2 = y1+height;
return [x1,y1,x2-$el.width()-10,y2]
}
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
table {
border-collapse: no-collapse;
overflow: hidden;
table-layout: fixed;
width: 500px;
margin: 20px;
}
tr {
position: relative;
background: #FFF;
}
td, th {
position: relative;
padding: 0;
width: 100px;
height: 30px;
border: 1px solid #000;
}
.planning-spot {
position: absolute;
top: 0;
left: 0;
height: 20px;
width: 90px;
border-radius: 10px;
margin: 5px;
text-align: center;
z-index: 1;
cursor: pointer;
color: #FFF;
width: 290px;
background: #3CF;
}
.no-planning {
background: #CCC;
}
.wrapper{
overflow:auto;
width:500px;
height:120px;
border: solid 1px red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link href="https://code.jquery.com/ui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>
<div class="wrapper">
<div class="middle">
<table>
<tbody>
<tr id="test">
<td>
<div></div>
<div class="planning-spot">18 / 20</div>
</td>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
<td class="no-planning">
<div></div>
</td>
<td class="no-planning">
<div></div>
</td>
</tr>
</tbody>
</table>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</div>
</div>
I did the trick by checking if drag event will cause collision with non dragable item.
Checkout code below:
$(function() {
var nonDragableItems = $(".no-planning");
$("td").droppable({
drop: function(event, ui) {
var draggable = ui.draggable;
var newLeft = draggable.offset().left - draggable.closest(".middle table").offset().left;
var childNum = Math.round((newLeft + 100) / 100);
var newContainer = $(this).closest('tr').find('td:nth-of-type(' + childNum + ')');
draggable.css({
top: '',
left: ''
});
newContainer.append(draggable);
},
});
function onDrag(e, ui){
var dragElemRect = ui.helper[0].getBoundingClientRect();
for(var i=0;i<nonDragableItems.length;i++){
var elemRect = nonDragableItems[i].getBoundingClientRect();
if(areColliding(dragElemRect, elemRect))
return false;
}
}
function areColliding(rect1, rect2){
if(rect1.bottom <= rect2.top ||
rect1.top >= rect2.bottom ||
rect1.left >= rect2.right ||
rect1.right <= rect2.left)
return false;
return true;
}
$(".planning-spot").resizable({
grid: [100, 10000000],
handles: "e",
containment: ".middle tr"
}).each(function() {
var $el = $(this);
$el.draggable({
containment: $el.closest('tr'),
axis: 'x',
drag: onDrag
});
});
});
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
table {
border-collapse: collapse;
overflow: hidden;
table-layout: fixed;
width: 500px;
margin: 20px;
}
tr {
position: relative;
background: #FFF;
}
td, th {
position: relative;
padding: 0;
width: 100px;
height: 30px;
border: 1px solid #000;
}
.planning-spot {
position: absolute;
top: 0;
left: 0;
height: 20px;
width: 90px;
border-radius: 10px;
margin: 5px;
text-align: center;
z-index: 1;
cursor: pointer;
color: #FFF;
width: 290px;
background: #3CF;
}
.no-planning {
background: #CCC;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="wrapper">
<div class="middle">
<table>
<tbody>
<tr>
<td>
<div></div>
<div class="planning-spot">18 / 20</div>
</td>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
<td>
<div></div>
</td>
<td class="no-planning">
<div></div>
</td>
</tr>
</tbody>
</table>
</div>
</div>

Drag image inside a div cell

I'm writing an email template builder. How can I drag image inside one of div cells ?
Actually I want to drag yellow and red divs to main container and then drag image inside one of div cells.
The HTML is:
<script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<div class="container" style="width:900px;height:400px; border:solid 1px red;">
drag here
</div>
<h2>From this list</h2>
<div id="toolBox" class="linked">
<div class="customeDraggable">
<div style="border: solid 1px yellow; float: right; height: 150px; width: 50%"> 1 </div>
<div style="border: solid 1px yellow; float: left; height: 150px; width: 49%"> 2 </div>
</div>
<div class="customeDraggable">
<div style="border: solid 1px red; float: right; height: 150px; width: 33%"> 1 </div>
<div style="border: solid 1px red; float: left; height: 150px; width: 33%"> 2 </div>
<div style="border: solid 1px red; float: left; height: 150px; width: 33%"> 3 </div>
</div>
<div class="customeDraggable">
<img src="http://icons.iconarchive.com/icons/artua/mac/128/Setting-icon.png" />
</div>
</div>
and the JavaScript code is:
$(function () {
toolBox = $('#toolBox'),
container = $('.container'),
container.sortable({
revert: false,
beforeStop: function (event, ui) {
$(this).data("lastItem", ui.item);
debugger;
},
receive: function (event, ui) {
$(this).data("lastItem").find('img').css('opacity', '1');
debugger;
//ui.item.draggable('destroy').css('opacity', '0.2');
}
});
toolBox.find('.customeDraggable').draggable({
connectToSortable: container,
helper: "clone",
revert: "invalid",
stop: handleDragStop
});
function handleDragStop(event, ui) {
debugger;
var offsetXPos = parseInt(ui.offset.left);
var offsetYPos = parseInt(ui.offset.top);
//alert("Drag stopped!\n\nOffset: (" + offsetXPos + ", " + offsetYPos + ")\n");
}
});
Here is the example on jsfiddle
Once you have moved the yellow div to the red, you must change the class of the div, in order to be able to receive stuff by dragging, instead of just being an element.
On the other hand, if the image cannot be dragged into the red div, it just must to be able to be dragged into the yellow one with a new class just for that.
finally I found a sample , now just customize it . jsfiddle sample
the html :
<ul class="widgets col-sm-2">
<li class="col-xs-6" data-type="grid-row" style="background-image: url(https://s3.amazonaws.com/jetstrap-site/images/builder/components/grid_row.png); background-repeat: no-repeat;" data-html='<div class="row"><div class="col-md-4 target"><h3>Span 4</h3><p>Content</p></div><div class="col-md-4 target"><h3>Span 4</h3><p>Content</p></div><div class="col-md-4 target"><h3>Span 4</h3><p>Content</p></div></div>'>Grid Row
</li>
<li class="col-xs-6" data-type="button" style="background-image: url(https://s3.amazonaws.com/jetstrap-site/images/builder/components/button.png); background-repeat: no-repeat;" data-html='Default'>Button
</li>
<li class="col-xs-6" data-type="heading" style="background-image: url(https://s3.amazonaws.com/jetstrap-site/images/builder/components/heading.png); background-repeat: no-repeat;" data-html='<h1>Heading 1</h1>'>Heading
</li>
<li class="col-xs-6" data-type="jumbotron" style="background-image: url(https://s3.amazonaws.com/jetstrap-site/images/builder/components/hero_unit.png); background-repeat: no-repeat;" data-html='<div class="jumbotron">
<h1>Jumbotron</h1>
<p>This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.</p>
<p><a class="btn btn-primary btn-lg">Learn more</a></p>
</div>'>Jumbotron
</li>
the css :
.widgets {
height: 800px;
background: #454443;
}
.widgets li {
float: left;
color: #fff;
list-style: none;
font-size: 13px;
font-weight: bold;
opacity: 0.85;
width: 125px;
padding-top: 75px;
text-align: center;
font-family:'ProximaNova-Regular', 'Helvetica Neue', Helvetica, Arial, sans- serif;
}
.widgets li:hover {
background-color: #454443;
opacity: 1.0;
cursor: -webkit-grab;
}
.widgets li a:hover {
cursor: -webkit-grab;
}
.widgets li a {
color: #fff;
text-decoration: none;
text-shadow: none;
}
.widget {
width: 150px;
height: 150px;
margin: 15px;
}
.page {
height: 800px;
border: thin solid red;
}
.page .row {
min-height: 50px;
}
.page .row div {
border-radius: 5px;
padding: 10px;
min-height: 30px;
border: 1px dotted #ccc;
}
and the js :
// Make all widgets draggable
$(".widgets li").draggable({
revert: "valid",
helper: "clone",
cursor: "move"
});
setDrop = function(targets) {
$(targets).droppable({
accept: ".widgets li",
greedy: true,
drop: function (event, ui) {
console.log(this);
var el = $($(ui.helper[0]).data("html"));
$(this).append(el);
setDrop($(".target", el));
}
});
};
setDrop($('.target'));
BTW, jquery-UI.js , bootstrap.css and bootstrap.js are needed

jQuery UI Drag/Droppable animation issue

I'm trying to use jQuery Ui for sorting some Items with Drag and Drop.
If one element passes the dropzone, the dropzone should expand. This works good. But my problem is that the attribute of event.target.clientWidth is still 25. So the dropzone is still 25px, while the container is allready 250px.
I dont know how to change it (i allready tried event.target.clientWidth = 250 but this doesnt work) and hoped you could maybe help me
This is a part of my code:
Html:
<section id="plot" class="plot">
<div class="cards">
<div id="card__container" class="card__container" style="width: 1392px;">
<div class="card__dropzone">
<div class="card__dropzone--inner"></div>
</div>
<div><div class="card ui-widget-content" id="card1">
<span class="card__id">1</span>
<span class="card__text">Hektor runs away followed by police</span>
</div>
</div>
<div class="card__dropzone">
<div class="card__dropzone--inner"></div>
</div>
<div><div class="card ui-widget-content" id="card2">
<span class="card__id">2</span>
<span class="card__text">Hektor stumbles and falls</span>
</div></div>
<div class="card__dropzone">
<div class="card__dropzone--inner"></div>
</div>
<div><div class="card ui-widget-content" id="card3">
<span class="card__id">3</span>
<span class="card__text">Hektor get catched by police and trys to bluff hisself out</span>
</div></div>
<div class="card__dropzone">
<div class="card__dropzone--inner"></div>
</div>
<div><div class="card ui-widget-content" id="card5">
<span class="card__id">5</span>
<span class="card__text">Hektor did say something stupid</span>
</div></div>
<div class="card__dropzone">
<div class="card__dropzone--inner"></div>
</div>
<div><div class="card ui-widget-content" id="card4">
<span class="card__id">4</span>
<span class="card__text">Police a bit confused and believes him</span>
</div></div>
<div class="card__dropzone">
<div class="card__dropzone--inner"></div>
</div>
<div><div class="card ui-widget-content" id="card6">
<span class="card__id">6</span>
<span class="card__text">Police arrested him</span>
</div>
</div>
</div>
</div>
</section>
Css:
.card {
cursor: pointer;
}
.plot {
overflow-y: hidden;
overflow-x: visible;
height: 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
width: 100vw;
padding-top: 25%;
}
.cards {
position: relative;
left: 0;
right: 0;
margin: auto;
}
.card__container {
left:0;
right: 0;
margin: 25px auto;
height: 100%;
display: table;
}
.card {
margin-top: 50px;
width: 200px;
height: 150px;
border: 1px solid #d3d3d3;
display: table-cell;
}
.card__dropzone--inner {
width: 25px;
height: 150px;
}
.card__id {
font-size: 1.5em;
font-weight: bold;
display: block;
padding: 10px;
}
.card__text {
display: block;
padding: 10px;
font-family: sans-serif;
}
.card__dropzone {
display: table-cell;
vertical-align: top;
}
.card__dropzone--active {
background: blue;
box-shadow: 0 0 10px blue;
}
Javascript:
$(document).ready(function() {
$(".card").draggable({ helper: "clone",
revert: true,
opacity: 0.5,
scroll:true,
scrollSensitivity: 100});
$(".card__dropzone--inner").droppable({
activeClass: "card__dropzone--active",
over: function(event) {
$(this).animate({
width: "250px"
}, 200);
event.target.clientWidth = 250;
console.log("over");
},
out: function(event) {
console.log("now?!");
$(event.target).animate({
width: "25px"
},200);
event.target.clientWidth = 25;
console.log("out");
},
drop: function(event) {
console.log("drop");
}
});
});
And this is my jsfiddle
http://jsfiddle.net/qthrvt8s/
You have to add refreshPositions: true while initializing .draggable() to tell your droppable area to take new dimensions in account :
$(document).ready(function() {
$(".card").draggable({ helper: "clone",
revert: true,
opacity: 0.5,
scroll:true,
refreshPositions: true,
scrollSensitivity: 100});
$(".card__dropzone--inner").droppable({
activeClass: "card__dropzone--active",
over: function(event) {
$(this).animate({
width: "250px"
}, 200);
console.log("over");
},
out: function(event) {
console.log("now?!");
$(event.target).animate({
width: "25px"
},200);
console.log("out");
},
drop: function(event) {
console.log("drop");
}
});
});
Please see the updated fiddle

jQuery UI drag and drop snap to center

I need a little help please.
I need to have a blue circle, a red circle, a blue square and a red square. I need to drag the red circle to the center of the red square and the blue circle to the center of the blue square. Unless I drag it to the correct position, it should revert to original position.
This is what I have so far:
$("#draggable, #draggable2").draggable({
revert: 'invalid', snap: "#droppable2"
});
$("#droppable").droppable({
accept: '#draggable'
});
$("#droppable2").droppable({
accept: '#draggable2',
});
http://jsfiddle.net/tM7cp/269/
I can't position them the circles to the center of the squares, how can I do that?
You can manually snap the items to the center of droppables using jQuery Ui's position() utility method as follows (I changed your logic slightly to avoid repetition of code and CSS):
$(".draggable").draggable({
revert: 'invalid'
});
$(".droppable").droppable({
accept: function(item) {
return $(this).data("color") == item.data("color");
},
drop: function(event, ui) {
var $this = $(this);
ui.draggable.position({
my: "center",
at: "center",
of: $this,
using: function(pos) {
$(this).animate(pos, 200, "linear");
}
});
}
});
.draggable {
float: left;
width: 100px;
height: 100px;
padding: 0.5em;
margin: 10px 10px 10px 0;
border: 1px solid black;
border-radius: 50%;
}
#draggable {
background-color: red;
}
#draggable2 {
background-color: blue;
}
.droppable {
padding: 0.5em;
float: left;
margin: 10px;
}
#droppable {
width: 100px;
height: 100px;
background-color: red;
}
#droppable2 {
width: 120px;
height: 120px;
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>
<div id="draggable" class="draggable" data-color="red"></div>
<div id="draggable2" class="draggable" data-color="blue"></div>
<div id="droppable" class="droppable" data-color="red"></div>
<div id="droppable2" class="droppable" data-color="blue"></div>
Here is an updated example of TJ's response. I created a jQuery plugin that can be called to center the draggable item within the droppable region.
(function($) {
$.fn.centerOnDrop = function(ui) {
ui.draggable.position({
my: 'center',
at: 'center',
of: this,
using: function(pos) {
$(this).animate(pos, 200, 'linear');
}
});
};
})(jQuery);
$('.draggable').draggable({ revert: 'invalid' });
$('.droppable').droppable({
accept: function($item) {
return $(this).data('color') === $item.data('color');
},
drop: function(event, ui) {
$(this).centerOnDrop(ui);
}
});
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
display: grid;
grid-template-columns: repeat(2, 1fr);
justify-items: center;
align-items: center;
}
.draggable { width: 4em; height: 4em; border-radius: 50%; }
#draggable-1 { background-color: pink; border: 1px solid red; }
#draggable-2 { background-color: lightblue; border: 1px solid blue; }
.droppable { width: 5em; height: 5em; }
#droppable-1 { background-color: red; }
#droppable-2 { background-color: blue; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div id="draggable-1" class="draggable" data-color="red"></div>
<div id="draggable-2" class="draggable" data-color="blue"></div>
<div id="droppable-1" class="droppable" data-color="red"></div>
<div id="droppable-2" class="droppable" data-color="blue"></div>

Categories