Webapps can be useful for data collection/ingestion. If the mechanism to collect and store data is easy to use, lot of useful data can be amassed for data processing. One easy to way to move data from one location to another is the Drag and drop functionality on webapps.
In this post, I show three examples for how to move and store HTML element data and files using JavaScript drag and drop programming.
Example 0: Drag and drop an HTML element
<!DOCTYPE html>
<html>
<head></head>
<body>
<h1>Example 0: Drag and Drop HTML text/elements</h1>
<div id="HTML_text" draggable="true" class="dragElement">HTML text</div>
<br><br>
<div id="dropArea" class="dropArea"> Drop for Example 0 & 1</div>
<style>
.dropArea { height: 200px;
width: 200px;
border-radius: 15px;
border: 0.25px solid black;
background-color: #7084c4;
}
.HTML_text { cursor: move; }
</style>
<script>
var example;
var other_data_related_to_dragEvent = {};
var html_element_drag_list_metaData = [];
// ----------------------------------------------------
// Drag functionality: Example 0
// ----------------------------------------------------
document.getElementById("HTML_text").addEventListener("dragstart", processEvent_drag_example0, false);
// document.getElementById("HTML_text").addEventListener("dragend", processEvent_drag_example0, false); // to stop
function processEvent_drag_example0(event) {
example = 0;
event.dataTransfer.setData('text/plain', event.target.id);
}
// ----------------------------------------------------
// ----------------------------------------------------
// Drop functionality: Example 0 and 1
// ----------------------------------------------------
document.getElementById("dropArea").addEventListener("drop", processEvent_drop, false);
document.getElementById("dropArea").addEventListener("dragover", processEvent_dragover, false);
function processEvent_drop(event) {
// Stop defaults and allow drop events
event.preventDefault();
// Detects files dragged from pc
html_element_drag_list_metaData.push(event.dataTransfer.files);
console.log('html_element_drag_list_metaData: ', html_element_drag_list_metaData);
// Detects html elements dragged from the html page
const data = event.dataTransfer.getData('text/plain');
console.log('data: ', data);
if (data.length != 0) {
// find the draggable element based on the data
const dragElement = document.getElementById(data);
console.log('dragElement: ', dragElement);
// Append the draggable element
event.target.appendChild(dragElement);
}
}
function processEvent_dragover(event) {
// Stop defaults and allow drop events
event.preventDefault();
}
// -------------------------------------------------
</script>
</body>
</html>
Before dragging and dropping the HTML text (HTML text) to the purple dropArea
After dragging and dropping the HTML text (HTML text) to the purple dropArea
In example 0, the HTML text element was actually moved into the drop area. The id of the div for HTML text appeared in the variable data, thus one can keep track of the element ids inside the dropArea. This example is useful for organizing/storing existing html written on a webapp, but in most data ingestion situation one wants to organize/store data from different places.
Example 1: a file upload is represented as a draggable HTML element/emoji
This example is a cross between dragging an HTML element and dragging a file. One can select a file using the Browse button; drag a file to the browse button or click on the browse button to select a file. Then an emoji appears after the file has been selected, the appearance of the emoji represents the file in terms of an HTML element. The HTML element emoji, representative of a file, can then be dragged to the dropArea for data ingestion/storage.
<!DOCTYPE html>
<html>
<head></head>
<body>
<h1>Example 1: Click button create drag and drop elements</h1>
<input type="file" id="upload_file" accept="audio/*" style="display:block" multiple>
<div id="file_name" style="display:none"></div>
<div id="base64_string" style="display:none"></div>
<div id="base64_string_icon" draggable="true" class="dragElement" style="display:none">📄</div>
<br><br>
<div id="dropArea" class="dropArea"> Drop for Example 0 & 1</div>
<style>
.dropArea { height: 200px;
width: 200px;
border-radius: 15px;
border: 0.25px solid black;
background-color: #7084c4;
}
.HTML_text { cursor: move; }
</style>
<script>
var example;
var other_data_related_to_dragEvent = {};
var html_element_drag_list_metaData = [];
// ----------------------------------------------------
// Drag functionality: Example 1
// ----------------------------------------------------
// The eventlistener needs to be always running, to detect which file the user selected with browse
document.getElementById("upload_file").addEventListener("change", previewInput_drop, false);
async function previewInput_drop(event) {
// Take the first file
const file = event.target.files[0]; // first file in the list of selected files, better for selecting multiple files at one time
// console.log("file :", file);
document.getElementById("file_name").innerHTML = file.name;
// ---------------------
const reader = new FileReader();
reader.onload = async function(e){
document.getElementById("base64_string").innerHTML = e.target.result;
document.getElementById("base64_string_icon").style.display = "block";
}
reader.readAsDataURL(file);
}
document.getElementById("base64_string_icon").addEventListener("dragstart", processEvent_drag_example1, false);
function processEvent_drag_example1(event) {
example = 1;
event.dataTransfer.setData('text/plain', event.target.id);
}
// ----------------------------------------------------
// ----------------------------------------------------
// Drop functionality: Example 0 and 1
// ----------------------------------------------------
document.getElementById("dropArea").addEventListener("drop", processEvent_drop, false);
document.getElementById("dropArea").addEventListener("dragover", processEvent_dragover, false);
function processEvent_drop(event) {
// Stop defaults and allow drop events
event.preventDefault();
// Detects files dragged from pc
html_element_drag_list_metaData.push(event.dataTransfer.files);
console.log('html_element_drag_list_metaData: ', html_element_drag_list_metaData);
// Detects html elements dragged from the html page
const data = event.dataTransfer.getData('text/plain');
console.log('data: ', data);
if (data.length != 0) {
// find the draggable element based on the data
const dragElement = document.getElementById(data);
console.log('dragElement: ', dragElement);
// Append the draggable element
event.target.appendChild(dragElement);
}
}
function processEvent_dragover(event) {
// Stop defaults and allow drop events
event.preventDefault();
}
// -------------------------------------------------
</script>
</body>
</html>
Before selecting a file
Dragged a file to the browse button
Dragged the representative file emoji to the dropArea
Example 2: Drag and drop an HTML element
In this example, one can efficiently drag multiple files to the dropArea at one time.
<!DOCTYPE html>
<html>
<head></head>
<body>
<h1>Example 2: Drag and drop files</h1>
<input type="file" id="upload_file_dragdrop" style="display:block" class="dropArea1" multiple>
<br><br>
<button id="use_moved_data" onclick="use_moved_data()">use_moved_data</button>
<!-- ---------------------------------------- -->
<!-- CSS -->
<style>
.dropArea1 { height: 200px;
width: 200px;
border-radius: 15px;
border: 0.25px solid black;
background-color: #56b06e;
}
</style>
<!-- ---------------------------------------- -->
<script>
var other_data_related_to_dragEvent = {};
var html_element_drag_list_metaData = [];
// ----------------------------------------------------
// Drag and Drop functionality: Example 2
// ----------------------------------------------------
document.getElementById("upload_file_dragdrop").addEventListener("change", previewInput, false);
async function previewInput(event) {
// For multiple files
const allFiles = event.target.files;
// console.log("allFiles :", allFiles);
var i = 0;
while (i < allFiles.length) {
const file = allFiles[i];
// console.log("file :", file);
await obtain_fileInfo(file)
.then(base64str => { other_data_related_to_dragEvent[file.name] = base64str; })
.catch(error => console.error(error));
i = i + 1;
}
// ---------------------
}
async function obtain_fileInfo(file) {
var base64_string = await new Promise((resolve) => {
const reader = new FileReader();
reader.onload = async function(e){
resolve(e.target.result); // inside resolve is the value that the function returns
};
reader.readAsDataURL(file);
});
return base64_string;
}
// ----------------------------------------------------
async function use_moved_data() {
console.log('html_element_drag_list_metaData: ', html_element_drag_list_metaData);
console.log('other_data_related_to_dragEvent: ', other_data_related_to_dragEvent);
}
</script>
</body>
</html>
Before dragging files into the dropArea
After dragging files into the dropArea and pushing the use_moved_data button
We can see an the base64 string data of the three files that were dragged into the dropArea! The base64 string data can then be saved as a blob object and transferred to across the Internet.
I hope these ways to drag and drop HTML elements and files helps someone.
Happy Practicing! 👋
💻 GitHub | 🌷 Practicing Datscy @ Dev.to | 🌳 Practicing Datscy @ Medium
References
- How to Create Drag and Drop Functionality in JavaScript: A Step-by-Step Tutorial: https://medium.com/@future_fanatic/how-to-create-drag-and-drop-functionality-in-javascript-a-step-by-step-tutorial-8ea236ef9416
- Read files in JavaScript: https://web.dev/articles/read-files
Top comments (0)