drag-drop to multiple elemnts issue - javascript

I'm trying to implement a drag-drop scenario.
A problem that I'm having is that I need to drop an element on an outer div but the event fires on the inner div.
Here is a codepen to demonstrate my problem:
http://codepen.io/anon/pen/KdvboR
<html>
<head>
<style>
.dropDiv {
height: 100px;
width: 200px;
border: 1px solid black;
}
.innerDiv {
height: 100px;
width: 100px;
border-right: 1px solid black;
}
.drag {
border: 1px solid green;
}
.drop {
border: 1px solid red;
}
</style>
</head>
<body>
<span id="text" draggable="true" ondragstart="drag(event)" ondragend="dragend(event)" class="">Drag Text</span>
<br>
<br>
To Here:
<div class="dropDiv" ondrop="drop(event)" ondragenter="dragenter(event)" ondragleave="dragleave(event)" ondragover="allowDrop(event)">
<div class="innerDiv"></div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
$(ev.target).addClass('drag');
ev.dataTransfer.setData('text', ev.target.id);
}
function dragenter(ev) {
$(ev.target).addClass('drop');
}
function dragleave(ev) {
$(ev.target).removeClass('drop');
}
function dragend(ev) {
$(ev.target).removeClass('drag');
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData('text');
ev.target.appendChild(document.getElementById(data));
$(ev.target).removeClass('drop');
}
</script>
</body>
</html>
I need that whenever the dragged element is in the outer div the border will be red. but when the mouse is over the inner div, only the inner div's border is red.
Any suggestions?
Thanks.

Go through this example
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Droppable - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
#draggable { width: 100px; height: 100px; padding: 0.5em; float: left; margin: 10px 10px 10px 0; }
#droppable { width: 150px; height: 150px; padding: 0.5em; float: left; margin: 10px; }
</style>
<script>
$(function() {
$( "#draggable" ).draggable();
$( "#droppable" ).droppable({
drop: function( event, ui ) {
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
}
});
});
</script>
</head>
<body>
<div id="draggable" class="ui-widget-content">
<p>Drag me to my target</p>
</div>
<div id="droppable" class="ui-widget-header">
<p>Drop here</p>
</div>
</body>
</html>

You are only one div on your container. remove container and try
<div class="innerDiv" ondrop="drop(event)" ondragenter="dragenter(event)" ondragleave="dragleave(event)" ondragover="allowDrop(event)"></div>
<div class="innerDiv" ondrop="drop(event)" ondragenter="dragenter(event)" ondragleave="dragleave(event)" ondragover="allowDrop(event)"></div>
.innerDiv {
height: 100px;
width: 100px;
border: 1px solid;
float:left;
}

Thanks everybody,
eventually, I solved it by checking if the event coords are in the outer div.

Related

How to prevent dragging(moving) element outside droppable div? (Vanila JS only)

function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
if (ev.target.id === "div1") {
console.log("Running Stop Drop");
document.getElementById("img1").setAttribute("draggable", false);
}
}
// shuffle
function shuffle() {
var container = document.getElementById("images");
var elementsArray = Array.prototype.slice.call(container.getElementsByClassName('grid-item'));
elementsArray.forEach(function (element) {
container.removeChild(element);
})
shuffleArray(elementsArray);
elementsArray.forEach(function (element) {
container.appendChild(element);
})
}
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
body {
background:#6b6b69;
color:white;
}
.info {
position:relative;
font-family:Arial;
margin:10px;
text-align:center;
border-radius:5px;
font-size:15px;
}
#title {
font-size:20px;
}
#rest2 {
font-size:13px;
}
#text div {
position:relative;
height: 200px;
width: 200px;
border: 1px dashed gray;
display: inline-block;
margin: 0;
}
#text {
display: grid;
grid-template-columns: auto auto;
width: 0%;
}
#images { display: grid;
grid-template-columns: auto auto;
width: 0%
}
img {
border: #6b6b69 2px solid;
height: 200px;
width: 200px;
}
#drag4,
#drag5,
#drag6,
#drag7,
#drag8,
#drag9,
#drag10,
#drag11,
#drag12 {
height: 200px;
width: 200px;
display: inline-block;
}
#drag4 {
background: linear-gradient(to bottom right, orange, orange, yellow);
}
#drag5 {
background: linear-gradient(to right, red, orange);
}
#drag6 {
background: linear-gradient(red, orange);
}
#drag7 {
background: linear-gradient(to bottom right, red, red, orange);
}
#drag8 {
background:yellow;
}
#drag9 {
background: linear-gradient(orange, yellow);
}
#drag10 {
background: linear-gradient(to right, orange, yellow);
}
#drag11 {
background: linear-gradient(red, orange);
}
#drag12 {
background: linear-gradient(to right, red,orange);
}
.puzzle{display: inline-block;}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<div class="info">
<div id="title">PUZZLE</div>
<div id="rest">Drag and drop the colored pieces on the puzzle below. (better images are on their way) </div>
<div id="rest2">You can put multiple pieces in the same area but you can't interchange them, only the last one you
put will be accessible.</div>
</div>
<div class="puzzle">
<div style="float:left;" id="images">
<img class="grid-item" id="img1" src="img/puzz1.jpg" alt="" draggable="true" ondragstart="drag(event)">
<img class="grid-item" id="img2" src="img/puzz2.jpg" alt="" draggable="true" ondragstart="drag(event)">
<img class="grid-item" id="img3" src="img/puzz3.jpg" alt="" draggable="true" ondragstart="drag(event)">
<img class="grid-item" id="img4" src="img/puzz4.jpg" alt="" draggable="true" ondragstart="drag(event)">
</div>
<div style="float: right" id="text">
<div class="grid-item2" id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="grid-item2" id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="grid-item2" id="div3" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<div class="grid-item2" id="div4" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</div>
</div><br><br>
<button onclick="shuffle()">
START
</button>
<div class="info">
<p>Congratulations if you finished!<p>
</div>
<script src="dragdrop3.js"></script>
</body>
</html>
I am building kind of a puzzle game with a drag and drop elements, I have 4 draggable images on the left and 4 empty divs on the right, similar drag and drop event to this w3Shchool example I posted here.
My question is how to prevent image to leave div2 on the right once it is dropped inside? I want it to be permanent, not draggable just locked once is dropped.
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
}
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1, #div2 {
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
</style>
</head>
<body>
<h2>Drag and Drop</h2>
<p>Drag the image back and forth between the two div elements.</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="img_w3slogo.gif" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31">
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</body>
</html>
Here is a very crude way of doing it (IMO), but it works.
Explanation: ondrop complete I make the img element un-dropable.
document.getElementById("drag1").setAttribute("draggable", false);
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
if(ev.target.id === "div2"){
console.log("Running Stop Drop");
document.getElementById("drag1").setAttribute("draggable", false);
}
}
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1, #div2 {
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
</style>
</head>
<body>
<h2>Drag and Drop</h2>
<p>Drag the image back and forth between the two div elements.</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<img src="img_w3slogo.gif" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31">
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</body>
</html>

Disable jQuery draggable in child element

I am using jQuery draggable. I have added draggable function to main div. Now in all the child elements it's also draggable. How can I disable dragging inside child div if parent is draggable?
$(function() {
$("#draggable").draggable();
});
#draggable {
width: 150px;
height: 150px;
padding: 0.5em;
border: black solid 2px;
}
.noDrag {
width: 100px;
height: 50px;
border: blue solid 2px;
}
<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 id="draggable" class="ui-widget-content">
<p>Drag me around</p>
<div class='noDrag'>No Drag</div>
</div>
To fix this use the cancel property, and provide it a selector to match the element you want to disable the drag behaviour on, like this:
$(function() {
$("#draggable").draggable({
cancel: '.noDrag'
});
});
#draggable {
width: 150px;
height: 150px;
padding: 0.5em;
border: black solid 2px;
}
.noDrag {
width: 100px;
height: 50px;
border: blue solid 2px;
}
<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 id="draggable" class="ui-widget-content">
<p>Drag me around</p>
<div class="noDrag">No Drag</div>
</div>
you can use cancel or disableselection() like suggest in jQuery-ui documentation https://jqueryui.com/draggable/#handle
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Draggable - Handles</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
#draggable, #draggable2 { width: 100px; height: 100px; padding: 0.5em; float: left; margin: 0 10px 10px 0; }
#draggable p { cursor: move; }
</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() {
$( "#draggable" ).draggable({ handle: "p" });
$( "#draggable2" ).draggable({ cancel: "p.ui-widget-header" });
$( "div, p" ).disableSelection();
} );
</script>
</head>
<body>
<div id="draggable" class="ui-widget-content">
<p class="ui-widget-header">I can be dragged only by this handle</p>
</div>
<div id="draggable2" class="ui-widget-content">
<p>You can drag me around…</p>
<p class="ui-widget-header">…but you can't drag me by this handle.</p>
</div>
</body>
</html>

Start drag outside draggable div using jQuery UI

I've using the first example by this code: http://jqueryui.com/draggable/#handle like this:
$(function() {
$("#draggable").draggable({
handle: "p"
});
});
#draggable {
width: 100px;
height: 100px;
padding: 0.5em;
float: left;
margin: 0 10px 10px 0;
}
#draggable p {
cursor: move;
}
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<div id="draggable" class="ui-widget-content">
<p class="ui-widget-header">I can be dragged only by this handle</p>
</div>
I would to start touch outside "draggable handle" and activate it when mouse passing over it.
I try to explain better with an image:
Is it possibile? How can I do this?

Put words in the right order to make a sentence with drag and drop

I've read the answers to this question and I came up with an exercise I wanted to test.
There is an educational quiz where you have to put the words in the right order.
<html>
<head>
<style type="text/css">
body {background-color: black;}
#div3 {margin-left: 0px;width:720px;height:200px;padding:50px;border:1px solid #aaaaaa;
background-color: LightBlue;}
span { margin: 20px; padding: 20px; background-color:#FFFF88; font-size: 50px;border: 0px solid;
border-radius: 25px;box-shadow: 5px 5px 5px grey;}
#quiz {margin-left: 0px;width:720px;height:200px;padding:40px;border:1px solid #aaaaaa;
background-color: #FFFF88;}
#quiz1 {border-radius: 0px;-webkit-touch-callout: none;-webkit-user-select: none;
-khtml-user-select: none;-moz-user-select: moz-none;-ms-user-select: none;user-select: none;}
</style>
</head>
<body>
<div id="div3" ondrop="drop(event)" ondragover="allowDrop(event)">
<span id="word1" draggable="true" ondragstart="drag(event)">the</span>
<span id="word2" draggable="true" ondragstart="drag(event)">piano</span>
<span id="word3" draggable="true" ondragstart="drag(event)">play</span>
<span id="word4" draggable="true" ondragstart="drag(event)">I</span>
</div>
<script>
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</body>
</html>
code online:
http://jsfiddle.net/gmouzakitis/C2f4P/5/
Known Bugs
- Drag & drop of a word before first word is not possible
- When you drag and drop a word near or over another word they become like one
draggable object. I dont want that.
Is there another way to do it, using other javascript framework like angular.js, jQuery, other?
Note: The original question was "When you drag and drop a word near or over another word they become like one draggable". Since then the OP has changed the question so please see below (after the break) where I address the current question.
Here is how you could do it. I just needed to adjust your JavaScript slightly: http://jsbin.com/borexihi/1/edit?js,output
function allowDrop(ev) {
ev.preventDefault();
}
function drag(ev) {
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev) {
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
var currentText = $(ev.target).text();
$(ev.target).text($('#' + data).text() + ' ' + currentText);
$('#' + data).remove();
}
Note: my solution does use jQuery
Answer for the current question: The question has changed so the following is my answer to the updated version, which asks "how to put the words given in the correct order".
Reordering items is a bit more tricky, which is why I would recommend using a library such as jQuery UI's sortable.
I've created a JSBin for you that incorporates your code with the library: http://jsbin.com/giqoxitu/1/edit?html,css,js,output. Here is the code:
HTML:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<ul id="sortable" class="div3">
<li id="word1" class="ui-state-default">The</li>
<li id="word2" class="ui-state-default">piano</li>
<li id="word3" class="ui-state-default">play</li>
<li id="word4" class="ui-state-default">I</li>
</ul>
</body>
</html>
CSS:
body {background-color: black;}
#sortable {
list-style-type: none;
margin: 0;
padding: 0;
}
#sortable li {
margin: 3px 3px 3px 0;
padding: 1px;
float: left;
width: 145px;
height: 90px;
font-size: 4em;
text-align: center;
}
.div3 {
margin-left: 0px;
height:200px;
padding:50px;
border:1px solid #aaaaaa;
background-color: LightBlue;
}
li {
margin: 20px;
padding: 20px;
border: 0px solid;
border-radius: 25px;
box-shadow: 5px 5px 5px grey;
}
JavaScript:
$(function() {
$( "#sortable" ).sortable();
$( "#sortable" ).disableSelection();
});

how to get the value of the image when drop from the droppable area?

i have a drag and drop code here from jquery i wanted to get the value of the image then insert it to the database and when the image is remove from the droppable area then update and remove the image value.. how can i do it?
here's the code....
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Droppable - Default functionality</title>
<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">
<script src="js/jquery-1.4.4.js"></script>
<script src="js/jquery.ui.core.js"></script>
<script src="js/jquery.ui.widget.js"></script>
<script src="js/jquery.ui.mouse.js"></script>
<script src="js/jquery.ui.draggable.js"></script>
<script src="js/jquery.ui.droppable.js"></script>
<link rel="stylesheet" href="js/demos.css">
<style>
#comment { width: 100px; height: 100px; padding: 0.5em; float: left; margin: 10px 10px 10px 0; }
#draggable1 { width: 100px; height: 100px; padding: 0.5em; float: left; margin: 10px 10px 10px 0; }
#droppable { width: 500px; height: 200px; padding: 0.5em; float: left; margin: 10px; background: silver;}
</style>
<script>
$(function() {
$( "#comment" ).draggable();
$( "#draggable1" ).draggable();
$( "#droppable" ).droppable({
drop: function( event, ui ) {
$( this )
.find( "p" )
.html("Dropped!")
},
out: function(event, ui) {
$(this)
.find( "p" )
.html("Drop Node Here!");
}
});
});
</script>
</head>
<body>
<div class="demo">
<div id="comment" class="ui-widget-content">
<img src="images/signup.png" id="1">
</div>
<div id="draggable1" class="ui-widget-content">
<img src="images/signup.png" id="2">
</div>
<div id="droppable" class="ui-widget-header">
<p>Drop Node here</p>
<?php
$comment = "#comment";
$drop = "#droppable";
$dropped = "dropped";
require_once("includes/connection.php");
require_once("includes/close.php");
?>
</div>
</div><!-- End demo -->
</body>
</html>
Off the top of my head something like this should give you the src of the image
drop: function( event, ui ) {
var image_src = $(ui).attr('src');

Categories

Resources