HTML Drag/Drop API - Disappear after Drag - html

I'm using the HTML Drag/Drop API W3schools is suggesting (w3schools html drag/drop api)
I'm trying to make something like moving objects from 1 bag to another.
All is working fine so far except when I somehow misclick and drag 1 picture onto the other(instead into free space in the div).
Then the dropped picture is disappearing. When I check the html code, I can see that the dropped img went under the first img.
Probably because of the "child" element in the js code i guess. That is where I need help.
How do I prevent that so I can only drop the images into the divs but not into other images?
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));
}
#div1, #div2 {
float: left;
width: 100px;
height: 350px;
margin: 10px;
padding: 10px;
border: 1px solid black;
<!DOCTYPE HTML>
<html>
<head>
</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)">Bag1
<img src="https://www.w3schools.com/html/img_w3slogo.gif" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31">
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)">Bag2
<img src="https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png" draggable="true" ondragstart="drag(event)" id="drag2" width="88" height="31">
</div>
</body>
</html>

just found the answer...
change the drop function to:
function drop(ev, el) {
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
el.appendChild(document.getElementById(data));
}
and when you call the function:
<div id="div1" ondrop="drop(event, this)" ondragover="allowDrop(event)">
thats it. found the answer here: prevent drop inside a child element when drag & dropping with JS

Related

Dragging multiple html elements at once

I would like to be able to drag an image next to some text and have the text move with it, the problem is that I can either move the image or move the text not have one move the other my current code for that is:
<ol>
<div style="cursor: move; user-select: none;">
<img style="width: 50px;" src="hand.png" alt="drag">
<h3 style="float: right" contenteditable='true'>sample</h3>
</div>
<h3 contenteditable='true'>sample2</h3>
</ol>
how would I make it so that I can drag the image and have it move the text?
How to drag (and drop) an image back and forth between two elements:
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1, #div2 {
float: left;
width: 100px;
height: 35px;
margin: 10px;
padding: 10px;
border: 1px solid black;
}
</style>
<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>
</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>
i am not sure if this is what you are looking for if not, please provide an example of what you need
or you can refer to this link for dragging multiple items:
https://codepen.io/SitePoint/pen/gbdwjj

How to hover over text (later a link) and have image and text next to it show up

I have a simple webpage with "site map" on bottom that won't be implemented for weeks or months and am developing the rest as I go.
So, "Site Map" needs to be a link (I presume) with "href=" (?) where I can add a link later? Upon hover, I need text saying "coming soon" to show up, along with an image on both sides, i.e.
(before hover)
Site Map
(after hover)
Site Map Coming Soon
There should be a little space between the pic and text that pops up.
#my_map:hover:after {
margin-left: 20px;
color: green;
content: "(Coming Soon)";
}
<h1>Before and After Tag Example</h1>
<p id="my_map">Site Map</p>
<p>Go back to Main Menu</p>
<span> <img src="lightening_bolt" alt="bolt" height="20" width="20";> coming soon <img src="lightening_bolt" alt="bolt" height="20" width="20";> </span>
<p style "margin-top: 50px;">Hover over Site Map... </p>
Above isn't allowing for an image, just content= some text, and all the searching I've done to find some code ideas seem to be with other objectives...
You can add an image to the content of an :after pseudo element by using the url() attribute. If you want text as well as an image, you need to string these together without a space. If you want space between the image and the text, just be sure to include the spaces withing your text string. The snippet below shows an image placed before and after the string.
Note: the images take a second or two to load.
var myMap = document.getElementById("my_map2");
var comingSooon = document.getElementById("my_map2");
//
myMap.addEventListener("mouseover", function() {
cs.innerHTML = "<img src='https://picsum.photos/200' height='15' width='40' /> (Coming Soon) <img src='https://picsum.photos/200' height='15' width='40' />";
}, false);
//
myMap.addEventListener("mouseout", function() {
cs.innerHTML = "";
}, false);
#my_map:hover:after {
margin-left: 20px;
font-size: 20px;
color: green;
content: url("https://picsum.photos/20")" (Coming Soon) "url("https://picsum.photos/20");
}
<p id="my_map">Site Map</p>
<p>Site Map 2 <span id="cs"></span></p>
You could also just have the image already there and hide it until the anchor is hovered over:
#map-link {
display: inline-block;
}
#hidden-message {
display: none;
transition: display 1s linear;
}
#map-link:hover+#hidden-message {
display: block;
}
#cmg-soon-img {
margin: 0;
padding: 0;
height: 100px;
width: 100px;
}
<div id="my_map">
<p id="map-link">Site Map</p>
<div id="hidden-message">
<img id="cmg-soon-img" src="https://picsum.photos/20">
<p>
"Coming soon..."
</p>
</div>
</div>
Which would allow you to control the width and height of the image shown.
<!-- Here's what I got (hope answer my own question doesn't close thread...-->
<!DOCTYPE html>
<html>
<head>
<style>
#my_map {
margin-right: 30px;
font-size: 35px;
text-decoration: none;
}
</style>
</head>
<body>
<p>Site Map <span id="cs"></span></p>
<script>
var myMap = document.getElementById("my_map");
var comingSooon = document.getElementById("my_map");
myMap.addEventListener("mouseover", function() {cs.innerHTML = "<img src='https://picsum.photos/20' height='35' width='35' /> (Coming Soon) <img src='https://picsum.photos/20' height='35' width='35' />";}, false);
myMap.addEventListener("mouseout", function() {cs.innerHTML = "";}, false);
</script>
</body>
</html>
<!doctype html>
<html>
<head>
<style>
#soon:hover:after {
margin-left: 20px;
color: green;
content: "Soon";
}
</style>
</head>
<body>
<p id="soon" style="font-size: 25px; margin-left:5%;"> Site Map </p>
<p style="margin-bottom: 150px;"></p>
<!-- take out the image and it's broken... it shows what I'm trying to do... -->
<img src="lightening-bolt.jpg" alt="Lightening bolt"
height="42" width="42">
<script>
function myFunction() {
var x = document.getElementById("myDIV");
if (x.style.display === "inline") {
x.style.display = "none";
} else {
x.style.display = "inline";
}
}
</script>
<p style="display: inline" onmouseover="myFunction()"
onmouseleave="myFunction()">Click Me
</p>
<div id="myDIV">
<span><img src="lightening-bolt.jpg" alt="Lightening bolt"
height="42" width="42"> Text <img src="399-3991460_face-with-stuck-out-tongue-
eye.jpg" alt="Lightening bolt"
height="42" width="42"> </span>
</div>
</body>
</html>

HTML5 Drag and Drop for a "fill in the blanks"

I want to create a "drag and drop" for a "fill the gaps" style question, then submit this data through a HTML form.
Example:
I have looked at a few ways of doing this, such as dragging and dropping images - not what I want, or dragging and dropping elements* on a page but I can't figure out how I can make this in to a form input.
Apologies for the W3 Schools link, I know they are not liked around here
Modifying the example you linked gives you:
<!DOCTYPE HTML>
<html>
<head>
<style>
.draggable {background-color:#00ff00;margin:5px;padding:3px;}
#div1,#div2 {display:inline-block;min-width:25px;min-height:10px;border-style:solid;border-width:0px;border-bottom-width:2px;}
</style>
<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.parentNode.replaceChild(document.getElementById(data), ev.target);
document.getElementById(data).className = "";
}
</script>
</head>
<body>
<span class="draggable" id="drag1" draggable="true" ondragstart="drag(event)">drag</span>
<span class="draggable" id="drag2" draggable="true" ondragstart="drag(event)">drop</span>
<br />
This is a sample
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
and
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
sentence.
</body>
</html>
Here's a fiddle of it to play with.

drag and drop with words

How could i modify the next code, to do a drag and drop of words?
in such a way that when I select a word of the sentence, I can drag
http://jsbin.com/ejenub/1/edit
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
#div1 {width:350px;height:70px;padding:10px;border:1px solid #aaaaaa;}
#div2 {width:350px;height:70px;padding:10px;border:1px solid #aaaaaa;}
</style>
<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>
</head>
<body>
verbs
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
adjetives
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<div id="drag1" draggable="true" ondragstart="drag(event)">I play the guitar</div>
<div id="drag2" draggable="true" ondragstart="drag(event)">The piano is black</div
</body>
</html>
All words should be wrapped in span or another nodes, here working example without modifying source html ;) http://jsbin.com/ejenub/3
You need to wrap each word in a HTML element such as <span>. Here's a modified version of your sample, which shows the dragging and dropping of words.
I upgraded this:
You can no longer drag words inside of other words, instead they fall in front of them within the container.
CSS automatically capitalizes the first word, puts a space between words, and a period at the end.
In this example, you're moving words within or between two sentences.
https://jsbin.com/hayizegisi/edit?html,output
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
.container {width:350px;height:70px;padding:10px;border:1px solid #aaaaaa;}
span {cursor: grabbing;}
span::before {content:" "}
span:first-child {text-transform:capitalize}
span:first-child:before {content:""}
span:last-child:after {content:"."}
</style>
<script>
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev)
{
console.log(ev)
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
if (ev.target.classList.contains('container')) {
var container = ev.target;
container.appendChild(document.getElementById(data));
} else {
container = ev.target.parentElement;
container.insertBefore(document.getElementById(data), ev.target);
}
}
/* function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}*/
</script>
</head>
<body>
<div class='container' ondrop="drop(event)" ondragover="allowDrop(event)">
<span id="word1" draggable="true" ondragstart="drag(event)">I</span>
<span id="word2" draggable="true" ondragstart="drag(event)">play</span>
<span id="word3" draggable="true" ondragstart="drag(event)">the</span>
<span id="word4" draggable="true" ondragstart="drag(event)">guitar</span>
</div>
<div class='container' ondrop="drop(event)" ondragover="allowDrop(event)">
<span id="word5" draggable="true" ondragstart="drag(event)">the</span>
<span id="word6" draggable="true" ondragstart="drag(event)">piano</span>
<span id="word7" draggable="true" ondragstart="drag(event)">is</span>
<span id="word8" draggable="true" ondragstart="drag(event)">black</span>
</div>
</body>
</html>

How to make UL Tabs with only HTML CSS

Trying to figure out how to do this. I have the style but I'd like something to happen after I click the tabs. I would like the div with the tab class names to show and hide when i click the tabs. I'm assuming how that would work. Right now when I click the tabs nothing happens.
Here's my HTML
<style type="text/css">
ul.tabs {
display: table;
list-style-type: none;
margin: 0;
padding: 0;
}
ul.tabs>li {
float: left;
padding: 10px;
background-color: lightgray;
}
ul.tabs>li:hover {
background-color: lightgray;
}
ul.tabs>li.selected {
background-color: lightgray;
}
div.content {
border: 1px solid black;
}
ul { overflow: auto; }
div.content { clear: both; }
</style>
<body>
<ul class="tabs">
<li>Description</li>
<li>Specs</li>
</ul>
<div class="pane">
<div class="tab1">
<div><h2>Hello</h2></div>
<div />
<div>Hello hello hello.</div>
<div />
<div>Goodbye goodbye, goodbye</div>
<div />
<div />
</div>
<div class="tab2" style="display:none;">
<div><h2>Hello2</h2></div>
<div />
<div>Hello2 hello2 hello2.</div>
<div />
<div>Goodbye2 goodbye2, goodbye2</div>
<div />
</div>
</div>
<div class="content">
This should really appear on a new line.
</div>
</body>
Standard answer: you can't. There is no way to do this with purely HTML/CSS2, unfortunately. We can make drop-downs in CSS with the :hover psuedo-class, but there's no equivalent for clicks. Look into one of these Javascript-based solutions.
Secret answer: CSS3 [kind of] supports this. But you have to create radio buttons [weird], and it's not supported in IE7/8. If you dare...
And if you don't mind using Javascript, here's a quick solution. Reformatted your HTML, first of all. No need to put <h2>s in <div>s, and use <br /> for breaks—that's what it's there for. Also, I changed the tab <div>s to use id's instead of classes. If you have unique identifiers for an element, use id.
<ul class="tabs">
<li>Description</li>
<li>Specs</li>
</ul>
<div class="pane">
<div id="tab1">
<h2>Hello</h2>
<p>Hello hello hello.</p>
<p>Goodbye goodbye, goodbye</p>
</div>
<div id="tab2" style="display:none;">
<h2>Hello2</h2>
<p>Hello2 hello2 hello2.</p>
<p>Goodbye2 goodbye2, goodbye2</p>
</div>
</div>
<div class="content">This should really appear on a new line.</div>
Didn't touch your CSS.
For Javascript, I recommend using jQuery. It really simplifies things.
All you need are these lines of code:
$(document).ready(function() {
$("ul.tabs a").click(function() {
$(".pane div").hide();
$($(this).attr("href")).show();
});
})
Basically, once the page is ready [has loaded], look for every link that's a child of a tabs ul. Attach a function that runs each time this link is clicked. When said link is clicked, hide all the tabs in the .pane div. Then, use the link's href to find the proper tab div and show it.
fiddle: http://jsfiddle.net/uFALn/18/
Because of the floated <li> elements your <ul> element is zero height.
Try adding ul { overflow: auto; } and div.content { clear: both; } to your CSS
Thanks benesch. It helped me too.
One can also add return false to prevent that jerky jump to the anchor. For instance:
$("ul.tabs a").click(function() {
$(".pane div").hide();
$($(this).attr("href")).show();
return false;
});