jQuery draggable and scroll not working : mobile devices - javascript

i am trying to figure out how to make draggable and scollable work simulatnoeusuly:
http://159.8.132.20/alldevice/
when u try to drag image on either side draggable action also starts, i want that area to be easily scrollable, means when i am scrolling draggble event should not be there
var $drop = $('#canvas-drop-area,#canvas-drop-area1'),
$gallery = $('#image-list li'),
$draggedImage = null,
$canvasp1old = null,
$canvasp2old = null;
$gallery.draggable({
//refreshPositions: true,
scroll: false,
start: function(e) {
$draggedImage = event.target;
$drop.css({
'display': 'block'
});
},
helper: function(e) {
return $('<img src="' + $(this).find('img').attr("src") + '" width="'+imgwidth+'">');
},
stop: function() {
$draggedImage = null;
},
revert: true
});

This might help you.
HTML
$("#draggable").draggable({
snap: true
});
$("#draggable2").draggable({
snap: ".ui-widget-header"
});
$("#draggable3").draggable({
snap: ".ui-widget-header",
snapMode: "outer"
});
$("#draggable4").draggable({
grid: [20, 20]
});
$("#draggable5").draggable({
grid: [80, 80]
});
.draggable {
width: 90px;
height: 80px;
padding: 5px;
float: left;
margin: 0 10px 10px 0;
font-size: .9em;
}
.ui-widget-header p,
.ui-widget-content p {
margin: 0;
}
#snaptarget {
height: 600px;
width: 200px;
}
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<table>
<tr>
<td>
<div id="draggable" class="draggable ui-widget-content">
<p>Default (snap: true), snaps to all other draggable elements</p>
</div>
<div id="draggable2" class="draggable ui-widget-content">
<p>I only snap to the big box</p>
</div>
</td>
<td>
<div id="snaptarget" class="ui-widget-header">
<p>I'm a snap target</p>
</div>
</td>
<td>
<div id="draggable3" class="draggable ui-widget-content">
<p>I only snap to the outer edges of the big box</p>
</div>
<div id="draggable4" class="draggable ui-widget-content">
<p>I snap to a 20 x 20 grid</p>
</div>
<div id="draggable5" class="draggable ui-widget-content">
<p>I snap to a 80 x 80 grid</p>
</div>
</td>
</tr>
</table>
javascript
$(function() {
$("#draggable").draggable({
snap: true
});
$("#draggable2").draggable({
snap: ".ui-widget-header"
});
$("#draggable3").draggable({
snap: ".ui-widget-header",
snapMode: "outer"
});
$("#draggable4").draggable({
grid: [20, 20]
});
$("#draggable5").draggable({
grid: [80, 80]
});
});
For Mobile you can use jquery ui touch punch it will help you and best solution is here
as per my knowledge jquery and jquery-ui is working awesome on 159.8.132.20/alldevice/.

Related

How to make dynamically created elements draggable with gridstack?

In my project I'm using this drag and drop library called gridstack. You can see their documentation on github here. When you hardcode elements inside the dom and initialize the gridstack, those elements are draggable. But when the elements are created dynamically with a forloop, they are not draggable even if they have the proper draggable classes. How can I make this work?
//initialize grid stack
var grid = GridStack.init({
minRow: 5, // don't collapse when empty
cellHeight: 70,
acceptWidgets: true,// acceptWidgets - accept widgets dragged from other grids or from outside (default: false).
dragIn: '.newWidget', // class that can be dragged from outside
dragInOptions: { revert: 'invalid', scroll: false, appendTo: 'body', helper:'clone' }, // clone or can be your function
removable: '#trash', // drag-out delete class
});
//gridstack on change
grid.on('added removed change', function(e, items) {
let str = '';
items.forEach(function(item) { str += ' (x,y)=' + item.x + ',' + item.y; });
console.log(e.type + ' ' + items.length + ' items:' + str );
});
//dynamic elemenets
const arr = ["Bruh cant drag me!", "Nope me neither", "Me too mouhahaha"];
//loop
for (let i = 0; i < arr.length; i++) {
var div = document.createElement('div');
var el = "<div class='newWidget grid-stack-item ui-draggable ui-resizable ui-resizable-autohide'> <div class='grid-stack-item-content' style='padding: 5px;'> "+arr[i]+"</div></div>";
div.innerHTML = el;
$('.dynamic').append(div);
}
.grid-stack-item-removing {
opacity: 0.8;
filter: blur(5px);
}
#trash {
background: rgba(255, 0, 0, 0.4);
padding: 5px;
text-align: center;
}
.grid-stack-item{
background: whitesmoke;
width: 50%;
border: 1px dashed grey;
}
.grid-stack {
background : #F0FFC0;
}
<!-- jquery -->
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<!-- gridstack-->
<link rel="stylesheet" href="https://gridstackjs.com/node_modules/gridstack/dist/gridstack-extra.min.css"/>
<script src="https://gridstackjs.com/node_modules/gridstack/dist/gridstack-h5.js"></script>
<!-- body-->
<body>
<div id="trash"><span>drop here to remove</span> </div>
<br>
<div class="dynamic"></div>
<div class="newWidget grid-stack-item ui-draggable ui-resizable ui-resizable-autohide">
<div class="grid-stack-item-content" style="padding: 5px;">
<div>
</div>
<div>
<span>I'm original domster! Drag and drop me!</span>
</div>
</div>
</div>
<br>
<div class="grid-stack"></div>
</body>
This issue was raised here. The grid does not automatically track external changes so the grid needs to be re-initialize for the dragIn option to notice the new dynamic widgets
GridStack.setupDragIn()
Full code
//initialize grid stack
var grid = GridStack.init({
minRow: 5, // don't collapse when empty
cellHeight: 70,
acceptWidgets: true,// acceptWidgets - accept widgets dragged from other grids or from outside (default: false).
dragIn: '.newWidget', // class that can be dragged from outside
dragInOptions: { revert: 'invalid', scroll: false, appendTo: 'body', helper:'clone' }, // clone or can be your function
removable: '#trash', // drag-out delete class
});
//gridstack on change
grid.on('added removed change', function(e, items) {
let str = '';
items.forEach(function(item) { str += ' (x,y)=' + item.x + ',' + item.y; });
console.log(e.type + ' ' + items.length + ' items:' + str );
});
//dynamic elemenets
const arr = ["Bruh cant drag me!", "Nope me neither", "Me too mouhahaha"];
//loop
for (let i = 0; i < arr.length; i++) {
var div = document.createElement('div');
var el = "<div class='newWidget grid-stack-item ui-draggable ui-resizable ui-resizable-autohide'> <div class='grid-stack-item-content' style='padding: 5px;'> "+arr[i]+"</div></div>";
div.innerHTML = el;
$('.dynamic').append(div);
}
GridStack.setupDragIn(
'.newWidget',
);
.grid-stack-item-removing {
opacity: 0.8;
filter: blur(5px);
}
#trash {
background: rgba(255, 0, 0, 0.4);
padding: 5px;
text-align: center;
}
.grid-stack-item{
background: whitesmoke;
width: 50%;
border: 1px dashed grey;
}
.grid-stack {
background : #F0FFC0;
}
<!-- jquery -->
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<!-- gridstack-->
<link rel="stylesheet" href="https://gridstackjs.com/node_modules/gridstack/dist/gridstack-extra.min.css"/>
<script src="https://gridstackjs.com/node_modules/gridstack/dist/gridstack-h5.js"></script>
<!-- body-->
<body>
<div id="trash"><span>drop here to remove</span> </div>
<br>
<div class="dynamic"></div>
<div class="newWidget grid-stack-item ui-draggable ui-resizable ui-resizable-autohide">
<div class="grid-stack-item-content" style="padding: 5px;">
<div>
</div>
<div>
<span>I'm original domster! Drag and drop me!</span>
</div>
</div>
</div>
<br>
<div class="grid-stack"></div>
</body>

how could you copy any src image from one side to another side droppable with method bind and url?

you can copy only one image to the droppable area with the bind method and url with javascript but you can not change any image,
i tried sourceImage = new Image() but the plugin only works with url
<div class="draggable">
<img src='team.jpg' class="resizable ui-resizable draggable" style="width:300px"/>
</div>
<div class="draggable">
<img src='foto11.jpg' class="resizable ui-resizable draggable" style="width:300px"/>
</div>
<div id="vanilla-demo" class='droppable' style="width:356px;height:286px;position:absolute;top:29.1em;left:73px;background-color: yellow">
</div>
<script>
$(".draggable").draggable({cursor:"grabbing",helper:"clone",opacity:0.8,grid:[20,20]});
$( ".droppable" ).droppable({
op: function(event,ui) {
vanilla.bind({
url: 'team.jpg',
orientation: 4
});
}
});
var el = document.getElementById('vanilla-demo');
var vanilla = new Croppie(el, {
viewport: { width: 300, height: 250 },
boundary: { width: 300, height: 250 },
showZoomer: true,
enableOrientation: false
});
vanilla.bind({
url: '',
orientation: 4
});
</script>
I hope the url shows the image when drope the image,
When you drag an item to a droppable, you can use the ui.draggable passed into drop.
drop( event, ui )
Triggered when an accepted draggable is dropped on the droppable (based on the tolerance option).
event
ui
draggable Type: jQuery A jQuery object representing the draggable element.
Consider the following code.
$(function() {
var el = $('#vanilla-demo');
var vanilla = new Croppie(el[0], {
viewport: {
width: 300,
height: 250
},
boundary: {
width: 300,
height: 250
},
showZoomer: true,
enableOrientation: false
});
vanilla.bind({
url: '',
orientation: 4
});
$(".draggable").draggable({
cursor: "grabbing",
helper: "clone",
opacity: 0.8,
grid: [20, 20],
zIndex: 1002
});
$(".droppable").droppable({
classes: {
"ui-droppable-hover": "ui-state-hover"
},
drop: function(event, ui) {
var newImage = ui.draggable;
vanilla.bind({
url: newImage.attr("src"),
orientation: 4
});
}
});
});
.droppable {
width: 356px;
height: 286px;
position: absolute;
top: 29.1em;
left: 73px;
background-color: #cccccc;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/croppie/2.6.4/croppie.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/croppie/2.6.4/croppie.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="draggable">
<img src='https://i.imgur.com/WDds7On.jpg' class="resizable ui-resizable draggable" style="width:300px" />
</div>
<div class="draggable">
<img src='https://i.imgur.com/p77MNQh.jpg' class="resizable ui-resizable draggable" style="width:300px" />
</div>
<div id="vanilla-demo" class='droppable'></div>
When the new item is dropped, the Binding is updated for Croppie.
Hope that helps.

How to make row of DIVs resizable with jQuery

I'm working on a scheduling widget concept. The basic idea is to have a row of DIVs for each day of the week. Each row has a fixed number of time periods represented by DIVs. I want to be able to resize each DIV by dragging a handle on the left hand side. The leftmost DIV cannot be dragged, but it resizes depending on the resizing of the DIV to its right. This continues down the row, i.e., the DIV to the left is resized automatically when the DIV to the right is resized. I'm using the Resizable widget in jQuery UI for the basic resize function.
I have prepared an example fiddle at: https://jsfiddle.net/profnimrod/rpzyv0nd/4/
For some reason the draggable handle on the left hand side of each DIV (other than the first one) is not moving as I would expect.
The Fontawesome icon inside each DIV (other than the first one), which I'd like to use as the resize handle is also not displaying.
Any ideas on how to fix these two issues.
Note that the there is a canvas element behind the DIV containing the row. The intent here is that I will be adding graphical elements behind the rows at somepoint (the row DIVs will be transparent).
The code I'm starting with (available at the Fiddle) is:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Schedule test</title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-6jHF7Z3XI3fF4XZixAuSu0gGKrXwoX/w3uFPxC56OtjChio7wtTGJWRW53Nhx6Ev" crossorigin="anonymous">
<style>
#container { width: 600px; height: 300px; }
#resizable1 { width: 150px; height: 50px; display:inline; float:left;}
#resizable2 { width: 150px; height: 50px; display:inline; float:left;}
#resizable3 { width: 150px; height: 50px; display:inline; float:left;}
#resizable4 { width: 142px; height: 50px; display:inline; float:left;}
#resizable1, #resizable2, #resizable3, #resizable4, #container { padding: 0em; }
</style>
<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>
<script>
$( function() {
$( "#resizable2" ).resizable({
grid: 50,
handles: "w",
maxHeight: 50,
minHeight: 50,
containment: "#container",
resize: function(e, ui) {
//var change = ui.size.width - ui.originalSize.width;
if(ui.originalSize.width > ui.size.width)
{
$("#resizable1").width($("#resizable1").width() + 50);
}
else {
$("#resizable1").width($("#resizable1").width() - 50);
}
}
});
$( "#resizable3" ).resizable({
grid: 50,
handles: "w",
maxHeight: 50,
minHeight: 50,
containment: "#container",
resize: function(e, ui) {
//var change = ui.size.width - ui.originalSize.width;
if(ui.originalSize.width > ui.size.width)
{
$("#resizable2").width($("#resizable2").width() + 50);
}
else {
$("#resizable2").width($("#resizable2").width() - 50);
}
}
});
$( "#resizable4" ).resizable({
grid: 50,
handles: "w",
maxHeight: 50,
minHeight: 50,
containment: "#container",
resize: function(e, ui) {
//var change = ui.size.width - ui.originalSize.width;
if(ui.originalSize.width > ui.size.width)
{
$("#resizable3").width($("#resizable3").width() + 50);
}
else {
$("#resizable3").width($("#resizable3").width() - 50);
}
}
});
});
</script>
</head>
<body>
<div class="scheduleWrapper">
<div id="canvasOverlay" style="position:absolute; width:600px !important; display:block; z-index:9999">
<div id="container" class="ui-widget-content">
<div id="resizable1" class="ui-state-active">
</div>
<div id="resizable2" class="ui-state-active">
<div class="ui-resizable-handle ui-resizable-w">
<span class="fa fa-cogs fa-fw"></span>
</div>
</div>
<div id="resizable3" class="ui-state-active">
<div class="ui-resizable-handle ui-resizable-w">
<span class="fa fa-cogs fa-fw"></span>
</div>
</div>
<div id="resizable4" class="ui-state-active">
<div class="ui-resizable-handle ui-resizable-w">
<span class="fa fa-cogs fa-fw"></span>
</div>
</div>
</div>
</div>
<canvas style="width: 600px; height: 300px;"></canvas>
</div>
</body>
</html>
Consider the following Fiddle: https://jsfiddle.net/Twisty/0r8v47yL/29/
JavaScript
$(function() {
$(".re-size").resizable({
grid: 50,
handles: "w",
maxHeight: 50,
minHeight: 50,
containment: "#container",
resize: function(e, ui) {
ui.position.top = 0;
ui.position.left = 0;
ui.size.height = 50;
}
});
});
I added classes to your DIV elements to make it easier to assign. First thing to know about resizing on w is that both left and width of the element will be adjusted. For example if you have:
<div id="resizable2" class="ui-state-active re-size item">
<div class="ui-resizable-handle ui-resizable-w">
<span class="fas fa-cogs fa-fw"></span>
</div>
</div>
This being set in CSS to 150px width and 50px height, when we drag the handle over, the left will be updated to say 45px and width will be changed to 105px. From a UI perspective this is what the user is expecting the action to do, the left hand side is moved. For your project, this does not work well.
Another issue that this does not address is that widening the element becomes more difficult. You can look at the event and review mouse movement to see if the user is trying to move the mouse closer to the left edge.
More complete example: https://jsfiddle.net/Twisty/0r8v47yL/61/
HTML
<div class="scheduleWrapper">
<div id="canvasOverlay" style="position:absolute; width:600px !important; display:block; z-index:9999">
<div id="container" class="ui-widget-content">
<div id="resizable1" class="ui-state-active no-re-size item">
</div>
<div id="resizable2" class="ui-state-active re-size item">
<div class="ui-resizable-handle ui-resizable-w">
<span class="fas fa-cogs fa-fw"></span>
</div>
</div>
<div id="resizable3" class="ui-state-active re-size item">
<div class="ui-resizable-handle ui-resizable-w">
<span class="fas fa-cogs fa-fw"></span>
</div>
</div>
<div id="resizable4" class="ui-state-active re-size item">
<div class="ui-resizable-handle ui-resizable-w">
<span class="fas fa-cogs fa-fw"></span>
</div>
</div>
</div>
</div>
<canvas style="width: 600px; height: 300px;"></canvas>
</div>
JavaScript
$(function() {
$(".re-size").resizable({
handles: "w",
containment: "#container",
resize: function(e, ui) {
//console.log(e);
var x = e.originalEvent.originalEvent.movementX;
ui.position.top = 0;
ui.position.left = 0;
ui.size.height = 50;
if (x < 0) {
console.log(ui.size.width + Math.abs(x));
ui.element.width(ui.size.width + 50);
} else {
ui.size.width = ui.size.width - 50;
}
}
});
});
Hope this helps.

make a dropped div, droppable again

I am trying to make an editor of a sort were you choose your layout for the given section and then drop another paragraph, button, img etc. on to the content area of that layout.
The thing is that when ever i drop the first div "layout" and i try to drop an item to that div, it chooses the wrong droppable area, because it is located "behind" the, as if the z-index is wrong, but the correct area is visible.
i made i jsfiddle as an example of the code, I'am logging the id of the droppable area and the dropped item in the console:
https://jsfiddle.net/g9aragsp/3/
so i would to add one of the "items" to the "insidedrop" instead of the "editor". Ive only set the id "insidedrop" on the first layout for testing purpose.
My html:
<div class="container-fluid">
<div class="row content">
<div class="col-sm-8 col-sm-offset-2">
<div class="row htmlEditor">
<div class="col-sm-3" style="background-color: gray; min-height: 800px;">
<p style="border-bottom: 5px solid black">Layouts</p>
<ul id="layouts" style="list-style-type: none;">
<li id="layout1" class="PickerButton">layout1</li>
<li id="layout2" class="PickerButton">layout2</li>
<li id="layout3" class="PickerButton">layout3</li>
</ul>
<p style="border-bottom: 5px solid black">Items</p>
<ul id="items" style="list-style-type: none;">
<li id="item1" class="PickerButton">button</li>
<li id="item2" class="PickerButton">img</li>
<li id="item3" class="PickerButton">text</li>
</ul>
</div>
<div id="editor" class="col-sm-9" style="background-color: lightgray; min-height: 800px; padding: 20px;">
</div>
</div>
</div>
</div>
</div>
My Javascript:
$(function () {
var $layouts = $("#layouts"),
$items = $("#items"),
$insideDrop = $("#insideDrop"),
$trash = $("#editor");
$("li", $layouts).draggable({
cancel: "button", // these elements won't initiate dragging
revert: "invalid", // when not dropped, the item will revert back to its initial position
containment: "document",
helper: "clone",
cursor: "move"
});
$("li", $items).draggable({
cancel: "button", // these elements won't initiate dragging
revert: "invalid", // when not dropped, the item will revert back to its initial position
containment: "document",
helper: "clone",
cursor: "move"
});
$trash.droppable({
//accept: "#list1 > li",
drop: function (event, ui) {
console.log(ui.draggable.attr("id"));
console.log($(this).attr("id"));
if (ui.draggable.attr("id") == "layout1")
$("#editor").append("<div class='layout1Outer' style='min-height:400px; margin-bottom: 15px;'><div class='layout1imageplaceholder' style='background-color:#8a2be2;height:150px'></div><div class='layout1content' id='insideDrop' style='background-color:bisque;min-height:250px'></div></div>");
if (ui.draggable.attr("id") == "layout2")
$("#editor").append("<div class='layout2Outer' style='min-height:400px; margin-bottom: 15px;'><div class='layout2imageplaceholder' style='background-color:#8a2be2;float:right;height:400px;width:40%'></div><div class='layout2content' style='background-color:bisque;float:left;min-height:400px;width:60%'></div></div>");
if (ui.draggable.attr("id") == "layout3")
$("#editor").append("<div class='layout3Outer' style='min-height:400px; margin-bottom: 15px;'><div class='layout3imageplaceholder' style='background-color:#8a2be2;float:left;height:400px;width:40%'></div><div class='layout3content' style='background-color:bisque;float:right;min-height:400px;width:60%'></div></div>");
}
});
$insideDrop.droppable({
drop: function (event, ui) {
if (ui.draggable.attr("id") == "item1")
$("#insideDrop").append("<span id='button' style='background-color:#dc143c;padding: 10px; width: 50px'>BUTTON</span>");
if (ui.draggable.attr("id") == "item2")
$("#insideDrop").append("<img src='http://via.placeholder.com/50x50'>");
if (ui.draggable.attr("id") == "item3")
$("#insideDrop").append("<p style='background- color: #284B63; padding: 10px; width: 200px; color: white;'>Insert text here</p>");
console.log(ui.draggable.attr("id"));
}
});
});
I figured out a solution to the problem. instead of targeting a nested "droppable" container. i reused the same function and on hover made javascript return the current hovered object, and then append the item to that specific object as so:
var hoveredObj;
function getid(obj) {
hoveredObj = obj;
}
var $layouts = $("#layouts"),
$items = $("#items"),
$insideDrop = $("#insideDrop"),
$editor = $("#editor");
$("li", $layouts).draggable({
cancel: "button", // these elements won't initiate dragging
revert: "invalid", // when not dropped, the item will revert back to its initial position
containment: "document",
helper: "clone",
cursor: "move"
});
$("li", $items).draggable({
cancel: "button", // these elements won't initiate dragging
revert: "invalid", // when not dropped, the item will revert back to its initial position
containment: "document",
helper: "clone",
cursor: "move"
});
$editor.droppable({
//accept: "#list1 > li",
drop: function (event, ui) {
console.log(ui.draggable.attr("id"));
console.log($(this).attr("id"));
if (ui.draggable.attr("id") == "layout1")
$("#editor").append("<div class='layout1Outer' style='min-height:400px; margin-bottom: 15px;'><div class='layout1imageplaceholder' style='background-color:#8a2be2;height:150px'></div><div class='layout1content' id='insideDrop' onmouseover='getid(this)' style='background-color:bisque;min-height:250px'></div></div>");
if (ui.draggable.attr("id") == "layout2")
$("#editor").append("<div class='layout3Outer' style='min-height:400px; margin-bottom: 15px;'><div class='layout3imageplaceholder' style='background-color:#8a2be2;float:left;height:400px;width:40%'></div><div class='layout3content' style='background-color:bisque;float:right;min-height:400px;width:60%'></div></div>");
if (ui.draggable.attr("id") == "layout3")
$("#editor").append("<div class='layout2Outer' style='min-height:400px; margin-bottom: 15px;'><div class='layout2imageplaceholder' style='background-color:#8a2be2;float:right;height:400px;width:40%'></div><div class='layout2content' style='background-color:bisque;float:left;min-height:400px;width:60%'></div></div>");
if (ui.draggable.attr("id") == "item1")
$(hoveredObj).append("<span id='button' style='background-color:#dc143c;padding: 10px; width: 50px'>BUTTON</span>");
if (ui.draggable.attr("id") == "item2")
$(hoveredObj).append("<img src='http://via.placeholder.com/50x50'>");
if (ui.draggable.attr("id") == "item3")
$(hoveredObj).append("<p style='background- color: #284B63; padding: 10px; width: 200px; color: white;'>Insert text here</p>");
}
});

JQuery Drag and Drop positioning issues

I am having issues with drag and drop functionality and I'm hoping someone can help. The rules in a nutshell are:
the "stage" (.stage) of which there can be more than one can accept cloned .pageControl. It is the only class it can accept.
Once dropped on .stage, .pageControl becomes .pageControlDropped and can accept cloned .wfcControl. It is the only class it can accept.
Once .wfcControl is dropped, it is replaced with new html and becomes .wfcControlDropped.
My problems are:
When I drag cloned .pageControl to .stage, it jumps to a position on .stage that is not the position I'm dropping it. I can drag it back to where I want it but it needs to drop where I drop it. I tried CSS positioning but it seems to work on .pageControl. Once .pageControl -> .pageControlDropped, it jumps to another position. Also, its not a very fluid drag like in the examples
If I drag multiple .pageControls to .stage, any of them should accept .wfcControl. But it seems like only the first .pageControl (now .pageControlDropped) receives it. I can't get the second .pageControlDropped to receive it.
How do I get successive .pageControl to not overlay existing ones on .stage?
CSS:
<style type="text/css">
.stage { margin-left: -.3em; width: 500px; height: 550px; padding: 0.0em;}
.pageControl {height:15px; width:15px; background-color:#EAEEFF; border:1px solid blue;}
.pageControlDropped {height:450px; width:600px;background-color:#F9FAFF;border:1px solid blue;}
.wfcControl { }
.wfcControlDropped { }
</style>
JQuery:
$('.pageControl').draggable({
helper: 'clone',
snap: false,
containment: '.stage',
handle: '.wfcHandle',
stop: function (event, ui) {
var pos = $(ui.helper).offset();
$(this).css({
"left": pos.left,
"top": pos.top
});
}
});
$('.wfcControl').draggable({ helper: 'clone', containment: '.pageControlDropped' });
$('.stage').droppable({
accept: '.pageControl',
greedy: true,
drop: function (event, ui) {
$(this).append($(ui.helper).clone());
$('.stage .pageControl')
.removeClass('pageControl')
.addClass('pageControlDropped')
.resizable()
.draggable({
containment: '.stage',
handle: '.wfcHandle'
})
.droppable({
accept: '.wfcControl',
greedy: true,
drop: function (event, ui) {
switch (ui.helper[0].title) {
case "Play Greeting Control":
wfcControlDropped = wfcPlayGreetingControl
break;
case "Input Control":
wfcControlDropped = wfcInputControl
break;
}
$(this).append($(ui.helper).clone());
$('.pageControlDropped .wfcControl').replaceWith($(wfcControlDropped));
$('.pageControlDropped .wfcControlDropped')
.draggable({
containment: '.pageControlDropped'
})
}
}).clone(false)
return false;
}
});
Finally, the HTML:
<div id = "divPageControl" title = "Page Control" class="pageControl">
<table style = "width:100%" border = "0">
<tr>
<td colspan = "1" width = "100%"></td>
</tr>
</table>
</div>
<div id = "divInputControl" title = "Input Control" class="wfcControl" style="height:15px; width:15px; background-color:light green; border:1px solid green;">
<table style = "width:100%" border = "0">
<tr class = "wfcHandle">
<td colspan = "1" width = "100%"> </td>
</tr>
</table>
</div>
Thanks for any help on this.
This should get you WELL ON YOUR WAY:
HTML:
<div class="pageControl"></div>
<div class="wfcControl"></div>
<div class="stage"> STAGE</div>
<div class="stage"> STAGE</div>
JAVASCRIPT:
$('.pageControl,.wfcControl').draggable({
helper:"clone",
opacity:0.5
});
//=========================================
$('.stage').droppable(
{
tolerance: "fit",
greedy:true,
accept: ".pageControl",
drop: function(e,ui){
$(this).append(
$(ui.draggable).clone()
.css({
position:"absolute",
//IMPORTANT
top: e.clientY-e.offsetY,
left: e.clientX-e.offsetX
})
//note containment:parent => IMPORTANT
.draggable({containment:"parent",
snap:true,
snapMode:"outer",
//MY ATTEMPT TO STOP USERS FROM OVERLAPPING
snapTolerance:15
})
.removeClass("pageControl")
.addClass("pageControlDropped")
.resizable()
.droppable({
accept: ".wfcControl",
drop: function(ev,ui){
$(this).append(
$(ui.draggable).clone()
.css({
position:"absolute",
top:ev.clientY-ev.offsetY-$(this).offset().top,
left: ev.clientX-ev.offsetX - $(this).offset().left
})
//note containment:parent
.draggable({containment:"parent"})
.removeClass("wfcControl")
.addClass("wfcControlDropped")
);
}
})
);
}
}
);
DEMO:
http://jsbin.com/orepew
Let me know if you had any questions

Categories