Problem with dragging and dropping elements in JS - javascript

Im trying to do some dragging and dropping on elements that is being created with the click of a button.
I have read a lot of post and watched at couple of videos, but i cant really find a solution.
I know i got a problem with the looping of the elements that is being created. Thats why i packed it in its own function so that it should run after its created.
I also think that the type i am trying to append is wrong here. thats why i made a little function to see the type.
I should mention that i am new to JS and just trying to build some to learn. I hope that you guys can help by posting a solution or maybe give me some hints. I might have missed some theory , as i am shelftaught.
Here is my code.
Its not made 100 mobile friendly! Look for a big round green button with a + for adding elements to the rows in the snippet! :-)
const btn = document.querySelector('#btn');
const workRow = document.querySelector('.workrow');
const workRows = document.querySelectorAll('.workrow');
const workTasks = document.querySelectorAll('.workrowtask');
const typeOf = () => {
console.log(typeof workTasks)
};
btn.addEventListener('click', () => {
makePost();
loopTasks();
typeOf();
});
document.addEventListener('click', delPost);
function makePost() {
const div = document.createElement('div');
const textnode = document.createTextNode('Hello World');
div.appendChild(textnode);
div.setAttribute('draggable', true);
div.className = ('workrowtask');
const delbtn = document.createElement('button');
const textnodebtn = document.createTextNode('-');
delbtn.appendChild(textnodebtn);
delbtn.className = ('worktaskdelbtn');
div.appendChild(delbtn);
workRow.appendChild(div);
};
function delPost(e) {
if(e.target && e.target.className === 'worktaskdelbtn') {
e.target.parentNode.remove();
};
};
function loopTasks() {
for (let t = 0; t < workTasks.length; t++) {
const task = workTasks[t]
task.addEventListener('dragstart', (e) => {
e.preventDefault();
console.log('dragstart')
});
task.addEventListener('dragend', (e) => {
e.preventDefault()
console.log('dragend')
});
}};
for (let r = 0; r < workRows.length; r++) {
const rows = workRows[r]
rows.addEventListener('dragover', (e) => {
e.preventDefault();
console.log('dragover');
});
rows.addEventListener('dragenter', (e) => {
e.preventDefault();
console.log('dragenter');
});
rows.addEventListener('drop', (e) => {
e.preventDefault();
console.log('drop');
rows.appendChild(workTasks)
});
};
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background-color: #393939;
}
.header {
background-color: #00D189;
text-transform: uppercase;
color: white;
text-align: center;
width: 100%;
padding: 20px 0px;
}
.worksection {
width: 100%;
margin-top: 50px;
display: flex;
justify-content: space-evenly;
}
.workrow {
width: 300px;
background-color:white;
height: 600px;
border-radius: 30px 30px 0px 0px;
overflow: scroll;
}
.workheader {
width: 300px;
padding: 20px 0px;
border-radius: 30px 30px 0px 0px;
background-color: #00D189;
color: white;
text-align: center;
}
.buttonwrapper {
display: flex;
justify-content: flex-end;
}
.buttonwrapper button {
border-radius: 50%;
background-color: #00D189;
height: 50px;
width: 50px;
border: none;
color: white;
font-size: 30px;
margin: 30px 15px 0px 0px;
cursor: pointer;
outline: none;
}
.workrowtask {
width: 100%;
background-color: gray;
padding: 10px 0px;
margin-top: 10px;
display: flex;
flex-wrap: nowrap;
justify-content: space-around;
}
.worktaskdelbtn {
background-color: red;
color: white;
height: 15px;
width: 15px;
border-radius: 50%;
border: none;
cursor: pointer;
outline: none;
}
#media only screen and (max-width: 1214px) {
.worksection {
flex-flow: column;
align-items: center;
}
.workrow {
margin-bottom: 50px;
}
.worksection {
position: relative;
}
.buttonwrapper {
position: absolute;
left: 30px;
bottom: 300px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Drag&droptodo</title>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<header class="header">
<h1>The Drag&Drop2Do</h1>
</header>
<section class="worksection">
<div class="workrow">
<div class="workheader">
<p>Dagens opgaver</p>
</div>
</div>
<div class="workrow">
<div class="workheader">
<p>Færdige opgaver</p>
</div>
</div>
<div class="workrow">
<div class="workheader">
<p>Udskudte opgaver</p>
</div>
</div>
<div class="workrow">
<div class="workheader">
<p>Afsluttet opgaver</p>
</div>
</div>
</section>
<div class="buttonwrapper">
<button id="btn">+</button>
</div>
<script src="./javascript/script.js"></script>
</body>
</html>

Your issue is in this:
rows.addEventListener('drop', (e) => {
................
rows.appendChild(workTasks)
});
workTasks is empty.
On dragenter event you can set an attribute to the element and use it in the drop:
rows.addEventListener('drop', function (e) {
e.preventDefault();
var currTarsk = document.querySelector('.workrowtask[isdragging="true"]');
currTarsk.removeAttribute('isdragging')
rows.appendChild(currTarsk);
});
The snippet:
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background-color: #393939;
}
.header {
background-color: #00D189;
text-transform: uppercase;
color: white;
text-align: center;
width: 100%;
padding: 20px 0px;
}
.worksection {
width: 100%;
margin-top: 50px;
display: flex;
justify-content: space-evenly;
}
.workrow {
width: 300px;
background-color: white;
height: 600px;
border-radius: 30px 30px 0px 0px;
overflow: scroll;
}
.workheader {
width: 300px;
padding: 20px 0px;
border-radius: 30px 30px 0px 0px;
background-color: #00D189;
color: white;
text-align: center;
}
.buttonwrapper {
display: flex;
justify-content: flex-end;
}
.buttonwrapper button {
border-radius: 50%;
background-color: #00D189;
height: 50px;
width: 50px;
border: none;
color: white;
font-size: 30px;
margin: 30px 15px 0px 0px;
cursor: pointer;
outline: none;
}
.workrowtask {
width: 100%;
background-color: gray;
padding: 10px 0px;
margin-top: 10px;
display: flex;
flex-wrap: nowrap;
justify-content: space-around;
}
.worktaskdelbtn {
background-color: red;
color: white;
height: 15px;
width: 15px;
border-radius: 50%;
border: none;
cursor: pointer;
outline: none;
}
#media only screen and (max-width: 1214px) {
.worksection {
flex-flow: column;
align-items: center;
}
.workrow {
margin-bottom: 50px;
}
.worksection {
position: relative;
}
.buttonwrapper {
position: absolute;
left: 30px;
bottom: 300px;
}
}
<header class="header">
<h1>The Drag&Drop2Do</h1>
</header>
<section class="worksection">
<div class="workrow">
<div class="workheader">
<p>Dagens opgaver</p>
</div>
</div>
<div class="workrow">
<div class="workheader">
<p>Færdige opgaver</p>
</div>
</div>
<div class="workrow">
<div class="workheader">
<p>Udskudte opgaver</p>
</div>
</div>
<div class="workrow">
<div class="workheader">
<p>Afsluttet opgaver</p>
</div>
</div>
</section>
<div class="buttonwrapper">
<button id="btn">+</button>
</div>
<script>
const btn = document.querySelector('#btn');
const workRow = document.querySelector('.workrow');
const workRows = document.querySelectorAll('.workrow');
const workTasks = document.querySelectorAll('.workrowtask');
const typeOf = function () {
console.log(typeof workTasks)
};
btn.addEventListener('click', function () {
makePost();
loopTasks();
//typeOf();
});
document.addEventListener('click', delPost);
function makePost() {
const div = document.createElement('div');
const textnode = document.createTextNode('Hello World');
div.appendChild(textnode);
div.setAttribute('draggable', true);
div.className = ('workrowtask');
const delbtn = document.createElement('button');
const textnodebtn = document.createTextNode('-');
delbtn.appendChild(textnodebtn);
delbtn.className = ('worktaskdelbtn');
div.appendChild(delbtn);
workRow.appendChild(div);
};
function delPost(e) {
if (e.target && e.target.className === 'worktaskdelbtn') {
e.target.parentNode.remove();
};
};
function loopTasks() {
for (let t = 0; t < workTasks.length; t++) {
const task = workTasks[t]
task.addEventListener('dragstart', function (e) {
e.preventDefault();
});
task.addEventListener('dragend', function (e) {
e.preventDefault()
});
}
};
for (let r = 0; r < workRows.length; r++) {
const rows = workRows[r]
rows.addEventListener('dragover', function (e) {
e.preventDefault();
});
rows.addEventListener('dragenter', function (e) {
e.preventDefault();
e.target.setAttribute('isdragging', true);
});
rows.addEventListener('drop', function (e) {
e.preventDefault();
var currTarsk = document.querySelector('.workrowtask[isdragging="true"]');
currTarsk.removeAttribute('isdragging')
rows.appendChild(currTarsk);
});
};
</script>

Try this:
function allowDrop(allowDropEvent) {
allowDropEvent.target.style.color = 'blue';
allowDropEvent.preventDefault();
}
function drag(dragEvent) {
dragEvent.dataTransfer.setData('text', dragEvent.target.id);
dragEvent.target.style.color = 'green';
}
function drop(dropEvent) {
dropEvent.preventDefault();
var data = dropEvent.dataTransfer.getData('text');
dropEvent.target.appendChild(document.getElementById(data));
document.getElementById('drag').style.color = 'black';
}
.container {
display: grid;
width: 200px;
height: 100px;
}
#div1 {
grid-row: 1;
grid-column: 1;
border: 1px solid #aaa;
width: 100px;
height: 100px;
padding: 10px;
}
#div2 {
grid-row: 1;
grid-column: 2;
border: 1px solid #aaa;
width: 100px;
height: 100px;
padding: 10px;
}
<div class="container">
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<span id="drag" draggable="true" ondragstart="drag(event)">Drag me to the other box</span>
</div>
<div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
</div>
A simple example of the use of the HTML Drag and Drop API.
You can also check out the MDN Web Docs for:
HTML Drag and Drop API reference
JavaScript reference
If this doesn't help, please tell me.

I've removed unnecessary parts from your JavaScript code. Also changed CSS and HTML just for simplifying the answer.
Note: I removed overflow:scroll, because it looks weird in your example.
Here is working example:
const btn = document.querySelector('#btn');
const workRow = document.querySelector('.workrow');
const workRows = document.querySelectorAll('.workrow');
let counter = 0;
btn.addEventListener('click', () => {
makePost();
});
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");
if (ev.target.className == 'workrow') {
ev.target.appendChild(document.getElementById(data));
}
}
function makePost() {
const div = document.createElement('div');
const textnode = document.createTextNode('Hello World ' + counter);
div.id = 'helloWorld' + counter;
counter++;
div.appendChild(textnode);
div.setAttribute('draggable', true);
div.className = 'workrowtask';
const delbtn = document.createElement('button');
const textnodebtn = document.createTextNode('-');
delbtn.appendChild(textnodebtn);
delbtn.className = 'worktaskdelbtn';
div.appendChild(delbtn);
delbtn.addEventListener('click', delPost);
div.addEventListener('dragstart', drag);
workRow.appendChild(div);
}
function delPost(e) {
if (e.target && e.target.className === 'worktaskdelbtn') {
e.target.parentNode.remove();
}
}
for (let r = 0; r < workRows.length; r++) {
const row = workRows[r]
row.addEventListener('dragover', allowDrop);
row.addEventListener('dragenter', allowDrop);
row.addEventListener('drop', drop);
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background-color: #393939;
}
.header {
background-color: #00D189;
text-transform: uppercase;
color: white;
text-align: center;
width: 100%;
padding: 20px 0px;
display: none;
/*!!!*/
}
.worksection {
width: 100%;
/*margin-top: 50px;*/
display: flex;
justify-content: space-evenly;
}
.workrow {
width: 200px;
background-color: white;
height: 300px;
border-radius: 30px 30px 0px 0px;
overflow: hidden;
}
.workheader {
width: 200px;
padding: 20px 0px;
border-radius: 30px 30px 0px 0px;
background-color: #00D189;
color: white;
text-align: center;
}
.buttonwrapper {
display: flex;
justify-content: flex-end;
}
.buttonwrapper button {
border-radius: 50%;
background-color: #00D189;
height: 50px;
width: 50px;
border: none;
color: white;
font-size: 30px;
/*margin: 30px 15px 0px 0px;*/
cursor: pointer;
outline: none;
}
.workrowtask {
width: 100%;
background-color: gray;
padding: 10px 0px;
margin-top: 10px;
display: flex;
flex-wrap: nowrap;
justify-content: space-around;
}
.worktaskdelbtn {
background-color: red;
color: white;
height: 15px;
width: 15px;
border-radius: 50%;
border: none;
cursor: pointer;
outline: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Drag&droptodo</title>
</head>
<body>
<header class="header">
<h1>The Drag&Drop2Do</h1>
</header>
<section class="worksection">
<div class="workrow">
<div class="workheader">
<p>Dagens opgaver</p>
</div>
</div>
<div class="workrow">
<div class="workheader">
<p>Færdige opgaver</p>
</div>
</div>
<div class="workrow">
<div class="workheader">
<p>Udskudte opgaver</p>
</div>
</div>
</section>
<div class="buttonwrapper">
<button id="btn">+</button>
</div>
</body>
</html>

Related

I return nothing ondrop how to fix it?

When iam dropping my div with an image inside i get nothing and after i am trying to get it ID i get null of course. But how can i get info from a div with image and append row with it?
Code here or check codepen:
https://codepen.io/13reathcode/pen/NWBmZpb
'use strict';
let queuedImagesArray = [],
queuedForm = document.querySelector('#queued-form'),
queuedDiv = document.querySelector('.queued-div'),
inputDiv = document.querySelector('.input-div'),
input = document.querySelector('.input-div input');
const colors = ['#FF7F7F', '#FFBF7F', '#FFDF7F', '#BFFF7F', '#7FFF7F', '#7FBFFF', '#7F7FFF'],
rows = document.querySelectorAll('.content__row'),
cards = document.querySelectorAll('.content__card'),
addCard = document.getElementById('addCard');
// Queued Images
const onDragStart = (event) => {
console.log('Dragging');
event.dataTransfer.setData('id', event.target.id);
setTimeout(() => {
event.target.style.visibility = 'hidden';
}, 100);
};
const onDragEnd = (event) => {
console.log('Ended dragging');
event.target.style.visibility = 'visible';
};
const displayQueuedImages = () => {
let images = '';
queuedImagesArray.forEach((image, index) => {
images += `
<div class="image" draggable="true" id="${(Date.now() + '').slice(-10) + index}">
<img width='100' height='100' style="pointerEvents:none;" id="${index}" ondragstart="onDragStart" ondragend="onDragEnd"
src="${URL.createObjectURL(image)}" alt="image" />
<span style="color:black;font-size:2rem" onclick="deleteQueuedImage(${index})">×</span>
</div>
`;
});
queuedDiv.innerHTML = images;
};
const deleteQueuedImage = (index) => {
queuedImagesArray.splice(index, 1);
displayQueuedImages();
};
input.addEventListener('change', () => {
const files = input.files;
for (let i = 0; i < files.length; i++) {
queuedImagesArray.push(files[i]);
}
queuedForm.reset();
displayQueuedImages();
});
inputDiv.addEventListener('drop', (e) => {
e.preventDefault();
const files = e.dataTransfer.files;
for (let i = 0; i < files.length; i++) {
if (!files[i].type.match('image')) return;
if (queuedImagesArray.every((image) => image.name !== files[i].name))
queuedImagesArray.push(files[i]);
}
displayQueuedImages();
});
const onDrag = (event) => {
event.preventDefault();
};
// Problem here
const onDrop = (event) => {
event.preventDefault();
const draggedCardId = event.dataTransfer.getData('id'); // nothing
const draggedCard = document.getElementById(draggedCardId); // null
event.target.appendChild(draggedCard);
};
rows.forEach((row, index) => {
const label = row.querySelector('.content__label');
label.style.backgroundColor = colors[index];
row.ondragover = onDrag;
row.ondrop = onDrop;
});
<main>
<section class="section" id="section--1">
<div class="section__title">
<h2 class="section__description">Tier list app</h2>
<h3 class="section__text">Start dragging to move cards</h3>
</div>
<div class="content" id="content">
<div class="content__row">
<div class="content__label">S (The best)</div>
</div>
<div class="content__row">
<div class="content__label">A (Great)</div>
</div>
<div class="content__row">
<div class="content__label">B (Good)</div>
</div>
<div class="content__row">
<div class="content__label">C (Mediocre)</div>
</div>
<div class="content__row">
<div class="content__label">D (Bad)</div>
</div>
<div class="content__row">
<div class="content__label">E (Horrible)</div>
</div>
<!-- <div class="content__row">
<div class="content__label">F (Worst^_^)</div>
</div> -->
</div>
</section>
<form id="queued-form">
<div class="queued-div"></div>
</form>
<div class="input-div">
<p>Drag & drop images here or <span class="browse">Browse</span></p>
<input
type="file"
class="file"
multiple="multiple"
accept="image/png, image/jpeg, image/jpg"
/>
</div>
</main>
* {
margin: 0;
padding: 0;
box-sizing: inherit;
}
html {
font-size: 62.5%; // 10px = 1rem
box-sizing: border-box;
}
body {
font-family: 'Open Sans', sans-serif;
font-weight: 300;
color: #555;
line-height: 1.5;
}
.input-div {
width: 70%;
height: 200px;
border-radius: 5px;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
margin: 5rem auto;
border: 2px dotted black;
background-color: white;
position: relative;
.browse {
color: black;
font-weight: bold;
}
}
.file {
width: 100%;
height: 100%;
position: absolute;
opacity: 0;
cursor: pointer;
}
.queued-div {
width: 70%;
min-height: 200px;
display: flex;
margin: 5rem auto;
justify-content: flex-start;
flex-wrap: wrap;
gap: 0.5rem;
position: relative;
border-radius: 5px;
border: 2px dotted black;
background-color: white;
.image {
height: 10rem;
border-radius: 5px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.15);
overflow: hidden;
position: relative;
&:nth-child(4n) {
margin-right: 0;
}
img {
height: 100%;
width: 100%;
}
span {
position: absolute;
top: -4px;
right: 4px;
cursor: pointer;
font-size: 22px;
color: white;
&:hover {
opacity: 0.8;
}
}
}
}
#mixin center {
display: flex;
justify-content: center;
align-items: center;
}
// SECTIONS
.section {
padding: 1.8rem 3rem;
&__title {
max-width: 80rem;
margin: 0 auto 2rem auto;
text-align: center;
text-transform: uppercase;
}
&__description {
color: lightgreen;
font-size: 1.8rem;
}
&__text {
font-size: 2.5rem;
}
&__button {
font-size: 2rem;
text-transform: uppercase;
text-decoration: none;
padding: 1rem 2rem;
display: inline-block;
border-radius: 3rem;
position: relative;
background-color: lightgreen;
color: #fff;
border: none;
cursor: pointer;
}
}
// CONTENT
.content {
width: 70vw;
min-height: 10vh;
padding: 0rem;
box-sizing: content-box;
border: 3px solid #000;
display: flex;
flex-wrap: wrap;
flex-direction: column;
margin: 0 auto;
&__row {
width: 100%;
box-sizing: content-box;
flex-wrap: wrap;
height: 8.5rem;
background-color: #1a1a17;
display: flex;
&:not(:last-child) {
border-bottom: 2px solid #000;
}
}
&__label {
font-size: 2rem;
font-weight: 400;
height: 100%;
width: 15rem;
background-color: #555;
color: #333;
border-right: 3px solid #000;
#include center;
}
&__card {
#include center;
&:focus,
&:active {
cursor: pointer;
}
}
}
When i was adding images one by one everything was fine but when i changed button to input zone i can't get anything from new images.
There is a small issue in how you create your img elements: the ondragstart and ondragend event handlers aren't being assigned properly.
Currently, your img elements look something like:
<img id="0" ondragstart="onDragStart" ondragend="onDragEnd" src=... />
However, setting ondragstart to equal onDragStart doesn't actually invoke the function when the event is fired. Same with ondragend and onDragEnd. To do so, you have to actually invoke the functions with onDragStart(event) and onDragEnd(event).
This is because every HTML event handler attribute is implicitly wrapped in:
(event) => { /** the attribute value */ }
In other words, currently, your handlers are equivalent to:
(event) => { onDragStart }
// and
(event) => { onDragEnd }
instead of
(event) => { onDragStart(event) }
// and
(event) => { onDragEnd(event) }
which is given by
<img id="0" ondragstart="onDragStart(event)" ondragend="onDragEnd(event)" src=... />
So the fix is simply to fix the img generation code to:
images += `
<div class="image" draggable="true" id="${(Date.now() + '').slice(-10) + index}">
<img width='100' height='100' id="${index}"
ondragstart="onDragStart(event)" ondragend="onDragEnd(event)"
src="${URL.createObjectURL(image)}" alt="image" />
<span style="color: black; font-size: 2rem"
onclick="deleteQueuedImage(${index})">×</span>
</div>`;

This last step on my Note app... When I click on view more modal window is created, but the wrong one

'use strict';
// Select all elements needed for this task (querySelector)
const form = document.querySelector('.form');
const input = document.querySelector('.input__text');
let container = document.querySelector('.notes-container');
const button = document.querySelector('.btn');
const noteDiv = document.querySelector('.note');
let modal = document.querySelector('.modal');
const overlay = document.querySelector('.overlay');
const btnClose = document.querySelectorAll('.close-modal');
const btnView = document.querySelector('.btn-view');
let noteCount = 0;
// Create function that reads when the button is clicked on form
form.addEventListener('submit', function (e) {
e.preventDefault();
// if input filed is empty note will not be added!
if (!input.value == '') {
// Every time i click on button, notCount is incremented by one. Then that count i store and use to count number of note
if (button.click) noteCount++;
// Creating div element where notes will go
const divNotes = document.createElement('div');
// Adding class to that div element
divNotes.classList.add('note');
// Inserting HTML content into created div
const createdNote = (divNotes.innerHTML += `
<h4 class="note__heading">Note ${noteCount}</h4>
<p class="note__text">${input.value}</p>
<button class="btn btn-view">View Detail</button>
`);
container.appendChild(divNotes);
//
container.addEventListener('click', function (e) {
if (!e.target.classList.contains('btn-view')) {
return;
}
modal.classList.remove('hidden');
overlay.classList.remove('hidden');
modal.innerHTML = `<h4 class="note__heading">Note ${noteCount}</h4>
<p class="note__text">${input.value}</p>
<button class="close-modal">X</button>
`;
});
modal.addEventListener('click', function (e) {
if (!e.target.classList.contains('close-modal')) {
return;
}
modal.classList.add('hidden');
overlay.classList.add('hidden');
});
}
});
html {
margin: 0;
padding: 0;
font-family: 'Courier New', Courier, monospace;
box-sizing: border-box;
}
body {
display: grid;
place-items: center;
}
.container__app {
text-align: center;
}
h1 {
font-size: 4rem;
font-weight: 100;
}
h3 {
font-size: 2rem;
color: green;
margin-top: -40px;
}
.input__text {
width: 1310px;
height: 50px;
margin-bottom: 15px;
padding: 10px;
font-size: 16px;
resize: none;
}
label {
bottom: 36px;
padding: 3px;
vertical-align: top;
font-size: 25px;
font-weight: 600;
}
.btn-green {
color: white;
background-color: green;
width: 100px;
height: 35px;
border-radius: 5px;
border: none;
}
.btn-span {
margin-top: 15px;
}
.btn-green:active {
transform: translateY(4px);
}
.notes-container {
margin: auto;
padding: 25px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
grid-gap: 1.5rem;
}
.note {
border: 1px solid gray;
padding-bottom: 18px;
margin-top: 15px;
}
.note__text {
overflow: hidden;
max-height: 7rem;
-webkit-box-orient: vertical;
display: -webkit-box;
text-overflow: ellipsis;
-webkit-line-clamp: 4;
word-wrap: break-word;
padding: 0 20px 4px 20px;
}
h4 {
font-size: 25px;
}
p {
font-size: 20px;
}
.btn-view {
color: white;
background-color: rgb(24, 113, 197);
width: 100px;
height: 35px;
border-radius: 5px;
border: none;
}
.btn-view:active {
transform: translateY(4px);
}
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 70%;
border-radius: 5px;
background-color: white;
padding: 6rem;
box-shadow: 0 3rem 5rem rgba(0 0 0 0.3);
z-index: 10;
}
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(3px);
z-index: 5;
}
.hidden {
display: none;
}
.close-modal {
position: absolute;
top: 1.2rem;
right: 2rem;
font-size: 2rem;
color: #333;
cursor: pointer;
border: none;
background: none;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Note Taker App</title>
<link rel="stylesheet" href="style.css" />
<script src="script.js" defer></script>
</head>
<body>
<div class="container__app">
<h1>Note Taker</h1>
<h3>Add a new note:</h3>
<div class="input__field">
<form class="form">
<label class="input__text-name">Note: </label>
<textarea
rows="5"
cols=""
class="input__text"
placeholder="Write your note here"
></textarea>
<label for="submit"></label><br />
<button class="btn btn-green" type="submit">Add Note</button>
</form>
</div>
<div class="modal hidden">
<button class="close-modal">X</button>
</div>
<div class="overlay hidden"></div>
<div class="notes-container">
<!-- <div class="note">
<h4 class="note__heading">Note1</h4>
<p class="note__text">
MY note text
</p>
<div class="note__btn">
<button class="btn btn-view">View Detail</button>
</div>
</div> -->
</div>
</div>
</body>
</html>
Im new to programming, please help. I finished almost everything except last step. This is the problem: when I press button view more (it should create modal window related to that note and button). Thing is that everything is working fine when you press buttons in order (like note1, note2, note3), but if you press 6th button and then the first one, only last element will be created. If someone can explain me how this works. https://codepen.io/Niksani/pen/GROXGyN
const form = document.querySelector('.form');
const input = document.querySelector('.input__text');
let container = document.querySelector('.notes-container');
const button = document.querySelector('.btn');
const noteDiv = document.querySelector('.note');
let modal = document.querySelector('.modal');
const overlay = document.querySelector('.overlay');
const btnClose = document.querySelectorAll('.close-modal');
const btnView = document.querySelector('.btn-view');
let noteCount = 0;
form.addEventListener('submit', function (e) {
e.preventDefault();
if (!input.value == '') {
and use to count number of note
if (button.click) noteCount++;
const divNotes = document.createElement('div');
divNotes.classList.add('note');
const createdNote = (divNotes.innerHTML += `
<h4 class="note__heading">Note ${noteCount}</h4>
<p class="note__text">${input.value}</p>
<button class="btn btn-view">View Detail</button>
`);
container.appendChild(divNotes);
//
container.addEventListener('click', function (e) {
if (!e.target.classList.contains('btn-view')) {
return;
}
modal.classList.remove('hidden');
overlay.classList.remove('hidden');
modal.innerHTML = `<h4 class="note__heading">Note ${noteCount}</h4>
<p class="note__text">${input.value}</p>
<button class="close-modal">X</button>
`;
});
modal.addEventListener('click', function (e) {
if (!e.target.classList.contains('close-modal')) {
return;
}
modal.classList.add('hidden');
overlay.classList.add('hidden');
});
}
});
'use strict';
// Select all elements needed for this task (querySelector)
const form = document.querySelector('.form');
const input = document.querySelector('.input__text');
let container = document.querySelector('.notes-container');
const button = document.querySelector('.btn');
const noteDiv = document.querySelector('.note');
let modal = document.querySelector('.modal');
const overlay = document.querySelector('.overlay');
const btnClose = document.querySelectorAll('.close-modal');
const btnView = document.querySelector('.btn-view');
let noteCount = 0;
// Create function that reads when the button is clicked on form
form.addEventListener('submit', function (e) {
e.preventDefault();
// if input filed is empty note will not be added!
if (!input.value == '') {
// Every time i click on button, notCount is incremented by one. Then that count i store and use to count number of note
if (button.click) noteCount++;
// Creating div element where notes will go
const divNotes = document.createElement('div');
// Adding class to that div element
divNotes.classList.add('note');
// Inserting HTML content into created div
const createdNote = (divNotes.innerHTML += `
<h4 class="note__heading">Note ${noteCount}</h4>
<p id='note${noteCount}' class="note__text">${input.value}</p>
<button class="btn btn-view" value='${noteCount}'>View Detail</button>
`);
container.appendChild(divNotes);
//
container.addEventListener('click', function (e) {
if (!e.target.classList.contains('btn-view')) {
return;
}
let showNote = '';
showNote = e.target.value;
let noteText = document.getElementById(`note${showNote}`).innerHTML;
modal.classList.remove('hidden');
overlay.classList.remove('hidden');
modal.innerHTML = `<h4 class="note__heading">Note ${showNote}</h4>
<p class="note__text">${noteText}</p>
<button class="close-modal">X</button>
`;
});
modal.addEventListener('click', function (e) {
if (!e.target.classList.contains('close-modal')) {
return;
}
modal.classList.add('hidden');
overlay.classList.add('hidden');
});
}
});
html {
margin: 0;
padding: 0;
font-family: 'Courier New', Courier, monospace;
box-sizing: border-box;
}
body {
display: grid;
place-items: center;
}
.container__app {
text-align: center;
}
h1 {
font-size: 4rem;
font-weight: 100;
}
h3 {
font-size: 2rem;
color: green;
margin-top: -40px;
}
.input__text {
width: 1310px;
height: 50px;
margin-bottom: 15px;
padding: 10px;
font-size: 16px;
resize: none;
}
label {
bottom: 36px;
padding: 3px;
vertical-align: top;
font-size: 25px;
font-weight: 600;
}
.btn-green {
color: white;
background-color: green;
width: 100px;
height: 35px;
border-radius: 5px;
border: none;
}
.btn-span {
margin-top: 15px;
}
.btn-green:active {
transform: translateY(4px);
}
.notes-container {
margin: auto;
padding: 25px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
grid-gap: 1.5rem;
}
.note {
border: 1px solid gray;
padding-bottom: 18px;
margin-top: 15px;
}
.note__text {
overflow: hidden;
max-height: 7rem;
-webkit-box-orient: vertical;
display: -webkit-box;
text-overflow: ellipsis;
-webkit-line-clamp: 4;
word-wrap: break-word;
padding: 0 20px 4px 20px;
}
h4 {
font-size: 25px;
}
p {
font-size: 20px;
}
.btn-view {
color: white;
background-color: rgb(24, 113, 197);
width: 100px;
height: 35px;
border-radius: 5px;
border: none;
}
.btn-view:active {
transform: translateY(4px);
}
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 70%;
border-radius: 5px;
background-color: white;
padding: 6rem;
box-shadow: 0 3rem 5rem rgba(0 0 0 0.3);
z-index: 10;
}
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.6);
backdrop-filter: blur(3px);
z-index: 5;
}
.hidden {
display: none;
}
.close-modal {
position: absolute;
top: 1.2rem;
right: 2rem;
font-size: 2rem;
color: #333;
cursor: pointer;
border: none;
background: none;
}
<div class="container__app">
<h1>Note Taker</h1>
<h3>Add a new note:</h3>
<div class="input__field">
<form class="form">
<label class="input__text-name">Note: </label>
<textarea
rows="5"
cols=""
class="input__text"
placeholder="Write your note here"
></textarea>
<label for="submit"></label><br />
<button class="btn btn-green" type="submit">Add Note</button>
</form>
</div>
<div class="modal hidden">
<button class="close-modal">X</button>
</div>
<div class="overlay hidden"></div>
<div class="notes-container">
<!-- <div class="note">
<h4 class="note__heading">Note1</h4>
<p class="note__text">
MY note text
</p>
<div class="note__btn">
<button class="btn btn-view">View Detail</button>
</div>
</div> -->
</div>
</div>
check out the new event listener for your btn.click event...I am determining which note to show by getting the button value attribute that was added to the string literal....I am using that value to get the text of the note by giving the p an id and referencing that....I believe this gives you what you are looking for

copy button is working always only for the latest link

I need some advice.
After loading a new line, the copy button for other lines does not work for me. It always copies only the first link, even if I click on another button.
Thank for any advice.
Hi, I need some advice.
After loading a new line, the copy button for other lines does not work for me. It always copies only the first link, even if I click on another button.
Thank for any advice.
const container = document.querySelector(".container");
const inputField = container.querySelector("input");
var button = container.querySelector("button");
const showData = document.querySelector(".showData");
button.addEventListener("click", () =>{
const linkInput = inputField.value;
// console.log(linkInput);
fetch(`https://api.shrtco.de/v2/shorten?url=${linkInput}`)
.then(res => res.json())
.then(data =>{
// console.log(data)
inputField.value = "";
var apiData = `
<div class="data">
<h5>${data.result.short_link}</h5>
<button onclick="copyButton()" class="button__copy">Copy</button>
</div>
`;
showData.insertAdjacentHTML('afterbegin', apiData);
})
});
// Copy to clipboard
const element = document.querySelector(".link__item__button");
function copyButton() {
const cb = navigator.clipboard;
const shortLink = document.querySelector('.link__item__short');
cb.writeText(shortLink.innerText);
}
*{
font-family: sans-serif;
box-sizing: border-box;
margin: 0;
padding: 0;
}
.container{
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
input{
width: 200px;
height: 50px;
border-radius: 1rem;
margin-top: 1rem;
text-align: center;
border: 3px solid blue;
}
button{
width: 200px;
height: 50px;
border-radius: 1rem;
border: 0;
outline: 0;
margin-top: 1rem;
cursor: pointer;
}
.showData {
margin: 30px 0 0 0;
line-height: 3;
}
.data{
display: flex;
align-items: center;
margin-top: 10px;
}
.data .button__copy{
width: 100px;
height: 40px;
background: lightblue;
margin: 0 0 0 1rem;
}
<header>
<div class="container">
<h1>Short URL Generator</h1>
<input type="text" placeholder="paste your long link here">
<button>Create a Link</button>
<div class="showData">
</div>
</div>
</header>
The copy function does not work here in code snippet or on online sites with an iframe because of safety policy.
If you create a page without one, works fine. I checked.
const container = document.querySelector(".container");
const inputField = container.querySelector("input");
const button = container.querySelector("button");
const showData = document.querySelector(".showData");
button.addEventListener("click", () =>{
const linkInput = inputField.value;
fetch(`https://api.shrtco.de/v2/shorten?url=${linkInput}`)
.then(res => res.json())
.then(data =>{
inputField.value = "";
const shortLink = data.result.short_link
const id = shortLink.substring(shortLink.lastIndexOf('/') + 1)
const apiData = `
<div class="data">
<h5 id="${id}">${shortLink}</h5>
<button onclick="copyButton('${id}')" class="button__copy">Copy</button>
</div>
`;
showData.insertAdjacentHTML('afterbegin', apiData);
})
});
function copyButton(id) {
const shortLink = document.querySelector('#' + id);
navigator.clipboard.writeText(shortLink.innerText).then(() => {
console.log('Async: Copying to clipboard was successful!');
}, (err) => {
console.error('Async: Could not copy text: ', err);
});
}
*{
font-family: sans-serif;
box-sizing: border-box;
margin: 0;
padding: 0;
}
.container{
width: 100%;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
input{
width: 200px;
height: 50px;
border-radius: 1rem;
margin-top: 1rem;
text-align: center;
border: 3px solid blue;
}
button{
width: 200px;
height: 50px;
border-radius: 1rem;
border: 0;
outline: 0;
margin-top: 1rem;
cursor: pointer;
}
.showData {
margin: 30px 0 0 0;
line-height: 3;
}
.data{
display: flex;
align-items: center;
margin-top: 10px;
}
.data .button__copy{
width: 100px;
height: 40px;
background: lightblue;
margin: 0 0 0 1rem;
}
<div class="container">
<h1>Short URL Generator</h1>
<input type="text" placeholder="paste your long link here">
<button>Create a Link</button>
<div class="showData"></div>
</div>

I'm making a flashcard using JS and i encounteres a problem when i click the save button the card appears but after that there is problem?

I am making an flashcard using javascript and everything is working fine but when I press the save button to save the card there is error. it should display the question and after a click event it should show the answer of that card clicked but there is an error. also my browser storing also doesn't work.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: , sans-serif;
font-size: 1rem;
background: #092d4a;
}
button {
padding: 8px;
outline: none;
cursor: pointer;
border: 1px solid #092d4a;
border-radius: 5px;
}
button:hover {
background-color: #092d4a;
color: white;
}
.container {
width: 95%;
margin: auto;
}
.nav {
display: flex;
justify-content: space-between;
width: 100%;
margin: auto;
padding: 20px 0;
}
.nav button {
font-family: inherit;
}
.create-card {
display: none;
width: 380px;
margin: auto;
padding: 20px;
margin-top: 10px;
border-radius: 5px;
background: whitesmoke;
box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.5);
}
.create-card textarea {
width: 100%;
border-radius: 5px;
font-family: inherit;
border: 2px solid #092d4a;
}
.create-card button {
width: fit-content;
border: 2px solid #092d4a;
}
.flashcards {
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: wrap;
width: 100%;
margin: auto;
margin-top: 20px;
padding: 0px 17px;
}
.flashcard {
width: 370px;
height: 200px;
word-wrap: break-word;
margin: 15px;
background: #fff;
/* box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.9); */
box-shadow: 0px 2px 4px 0px rgba(255, 255, 255, 0.5);
}
.flashcard h2 {
font-size: 1rem;
}
#media(max-width:768px) {
.flashcard {
margin: auto;
}
.flashcard {
margin-top: 15px;
margin-bottom: 15px;
}
}
#media(max-width:480px) {
.create-card {
width: 100%;
}
.flashcard {
width: 100%;
}
}
<header>
<div class="container">
<div class="nav">
<h1> Saved Flashcards</h1>
<button class="btn1">Add New Card</button>
</div>
</div>
</header>
<div class="container">
<div class="create-card">
<p>
<h2 style="color: black;text-align: center;">Create Flashcard</h2>
</p>
<p>
<label for="text">Question</label><br>
<textarea id="question" placeholder="please enter your question here....."></textarea>
</p>
<p>
<label for="text">Answer</label><br>
<textarea id="answer" placeholder="please place your answer here...."></textarea>
</p>
<br>
<div>
<button class="btn2" onclick="saveFlashcard()">Save</button>
<button class="btn3">Close</button>
</div>
</div>
</div>
<div class="container">
<div class="flashcards" id="flashcards"></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="brain.js">
const flashcards = document.getElementsByClassName("flashcards")[0];
const createCard = document.getElementsByClassName("create-card")[0];
const question = document.getElementById("question");
const answer = document.getElementById("answer");
// if (localStorage.getItem("stored") == null) {
// localStorage.setItem("stored", [])
// };
// var test = JSON.parse(localStorage.getItem("stored"));
// var div = document.createElement("div");
// var h2_question = document.createElement("h2");
// var h2_answer = document.createElement("h2");
// div.className = "flashcard";
// h2_question.setAttribute("style", "border-top:1px solid blue; padding:15px; margin-top:30px");
// h2_question.innerHTML = localStorage.getItem("test");
// h2_answer.setAttribute("style", "text-align:center; display:none; color:Blue");
// h2_answer.innerHTML = localStorage.getItem("test");
// div.appendChild(h2_question);
// div.appendChild(h2_answer);
// flashcards.insertAdjacentElement("beforeend", div);
$(".btn1").on("click", function() {
$(".create-card").show();
});
$(".btn3").on("click", function() {
$(".create-card").hide();
});
function saveFlashcard() {
var div = document.createElement("div");
var h2_question = document.createElement("h2");
var h2_answer = document.createElement("h2");
div.className = "flashcard";
h2_question.setAttribute("style", "border-top:1px solid blue; padding:15px; margin-top:30px");
h2_question.innerHTML = question.value;
h2_answer.setAttribute("style", "text-align:center; display:none; color:Blue");
h2_answer.innerHTML = answer.value;
// $(".div").on("click", function() {
// $(".h2_question").show();
// });
div.appendChild(h2_question);
div.appendChild(h2_answer);
$("div").on("click", function() {
if (h2_answer.style.display == "none") {
h2_answer.style.display = "block";
} else {
h2_answer.style.display = "none";
}
});
div.addEventListener("dblclick", function() {
div.remove();
});
flashcards.insertAdjacentElement("beforeend", div);
question.value = '';
answer.value = '';
// var test = JSON.parse(localStorage.getItem("stored"));
// test.push(JSON.stringify([question.value, answer.value]));
};
</script>

JavaScript not working properly in a To-Do List Project

So I'm working on this simple project. It's a To-Do List. Every task has to buttons, namely, done and delete (These are images). And there are two divisions, one will store the pending tasks and the other will stored the completed tasks.
I want that when the user clicks on the done button (tick image) the task should be removed from the "Pending Tasks" division and shifted to the "Completed Tasks" division. I tried to add this functionality by adding an event listener to the images. The event listens for a single click. But the code is not working properly. For the first task, I've to click twice to remove it. The same is the case with other tasks as well. Which means every single task is added twice to the "Completed Tasks" division.
Also, I've added functionality to add new tasks. But the buttons (images) don't work on these new tasks. Basically, event listening is not working on them. Kindly help with the issue. I've added the code below.
(I've not added any functionality for deletion)
var completedTasks = document.querySelector(".Completed-Tasks");
var pendingTasks = document.querySelector(".Pending-Tasks");
var addTaskButton = document.querySelector(".Add-Task-Button");
var doneButtons = document.querySelectorAll(".Tick");
var deleteButtons = document.querySelectorAll(".Cross");
doneButtons.forEach(checkClickEvent);
console.log(doneButtons.length);
function checkClickEvent(button, index) {
button.addEventListener("click", function() {
let task = button.parentNode.parentNode;
pendingTasks.removeChild(pendingTasks.childNodes[index]);
let doneTaskHTML = `<div class="Task Done"><p class="Task-Text">${task.children[0].textContent}</p><div class="Task-Operations"><img src="./Cross.png" alt="Delete" class="Operation"></div></div>`;
completedTasks.insertAdjacentHTML("beforeend", doneTaskHTML);
});
}
addTaskButton.addEventListener("click", function(event) {
event.preventDefault();
let newTaskText = document.querySelector(".Add-Task-Input");
if (newTaskText.value != "") {
let newTaskHTML = `<div class="Task"><p class="Task-Text">${newTaskText.value}</p><div class="Task-Operations"><img src="./Tick.png" alt="Done" class="Operation Tick"><img src="./Cross.png" alt="Delete" class="Operation Cross"></div></div>`;
pendingTasks.insertAdjacentHTML("beforeend", newTaskHTML);
newTaskText.value = "";
}
});
#import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
font-family: "Poppins";
}
body {
background: #EDF2F4;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
min-height: 100vh;
}
.Header {
background: #2B2D42;
color: #FFFFFF;
max-width: 500px;
width: 100%;
padding: 15px;
margin-bottom: 20px;
}
.Heading {
font-size: 25px;
text-align: center;
}
.Tasks-Space {
background: #8D99AE;
max-width: 500px;
width: 100%;
padding: 15px;
position: relative;
}
.Add-Task {
position: relative;
width: 100%;
}
.Add-Task-Input {
outline: none;
border: none;
padding: 5px 10px;
width: 100%;
font-size: 16px;
}
.Add-Task-Button {
outline: none;
border: none;
width: 100%;
padding: 5px 10px;
margin-top: 15px;
font-size: 16px;
cursor: pointer;
background: #D90429;
color: #FFFFFF;
}
.Add-Task-Button:hover {
background: #EF233C;
color: #FFFFFF;
}
.Tasks-Space-Heading {
margin-top: 15px;
padding: 5px 10px;
background: #2B2D42;
color: #FFFFFF;
}
.Pending-Tasks {
margin-top: 15px;
}
.Completed-Tasks {
margin-top: 15px;
}
.Task {
background: #FFFFFF;
padding: 5px 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
.Task-Operations {
display: flex;
align-items: center;
}
.Operation {
height: 20px;
margin-left: 10px;
cursor: pointer;
}
.Done {
text-decoration: line-through;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>To-Do List</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="Header">
<p class="Heading">TO-DO LIST</p>
</div>
<div class="Tasks-Space">
<div class="Add-Task">
<input type="text" placeholder="Enter your task here" class="Add-Task-Input">
<button class="Add-Task-Button">Add Task</button>
</div>
<p class="Tasks-Space-Heading">Pending Tasks</p>
<div class="Pending-Tasks">
<div class="Task">
<p class="Task-Text">Make a pie</p>
<div class="Task-Operations">
<img src="./Tick.png" alt="Done" class="Operation Tick">
<img src="./Cross.png" alt="Delete" class="Operation Cross">
</div>
</div>
<div class="Task">
<p class="Task-Text">Play Minecraft</p>
<div class="Task-Operations">
<img src="./Tick.png" alt="Done" class="Operation Tick">
<img src="./Cross.png" alt="Delete" class="Operation Cross">
</div>
</div>
</div>
<p class="Tasks-Space-Heading">Completed Tasks</p>
<div class="Completed-Tasks"></div>
</div>
<script src="./main.js"></script>
</body>
</html>
Instead of pendingTasks.removeChild(pendingTasks.childNodes[index]); do task.remove(); since you already have the node that you want to remove. here is the reference to remove() function.
Also added document.querySelectorAll(".Tick").forEach(checkClickEvent); in add task click handler. This should add event listener to newly added tasks as well.
Edited
The solution did work but there was a slight problem. When we are adding event listeners to the new tasks using document.querySelectorAll(".Tick").forEach(checkClickEvent);, multiple event listeners are getting added to the existing tasks. To avoid this simply reinitialize the HTML inside the division. This can be done using pendingTasks.innerHTML = pendingTasks.innerHTML;. This code will remove all the existing event listeners on any element inside the division. Note that this code has to be used before adding event listeners again.
var completedTasks = document.querySelector(".Completed-Tasks");
var pendingTasks = document.querySelector(".Pending-Tasks");
var addTaskButton = document.querySelector(".Add-Task-Button");
var doneButtons = document.querySelectorAll(".Tick");
var deleteButtons = document.querySelectorAll(".Cross");
doneButtons.forEach(checkClickEvent);
console.log(doneButtons.length);
function checkClickEvent(button, index) {
button.addEventListener("click", function() {
let task = button.parentNode.parentNode;
task.remove();
let doneTaskHTML = `<div class="Task Done"><p class="Task-Text">${task.children[0].textContent}</p><div class="Task-Operations"><img src="./Cross.png" alt="Delete" class="Operation"></div></div>`;
completedTasks.insertAdjacentHTML("beforeend", doneTaskHTML);
});
}
addTaskButton.addEventListener("click", function(event) {
event.preventDefault();
let newTaskText = document.querySelector(".Add-Task-Input");
if (newTaskText.value != "") {
let newTaskHTML = `<div class="Task"><p class="Task-Text">${newTaskText.value}</p><div class="Task-Operations"><img src="./Tick.png" alt="Done" class="Operation Tick"><img src="./Cross.png" alt="Delete" class="Operation Cross"></div></div>`;
pendingTasks.insertAdjacentHTML("beforeend", newTaskHTML);
newTaskText.value = "";
pendingTasks.innerHTML = pendingTasks.innerHTML; // Re-initialize
document.querySelectorAll(".Tick").forEach(checkClickEvent); // Adding event listeners again
}
});
#import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
font-family: "Poppins";
}
body {
background: #EDF2F4;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
min-height: 100vh;
}
.Header {
background: #2B2D42;
color: #FFFFFF;
max-width: 500px;
width: 100%;
padding: 15px;
margin-bottom: 20px;
}
.Heading {
font-size: 25px;
text-align: center;
}
.Tasks-Space {
background: #8D99AE;
max-width: 500px;
width: 100%;
padding: 15px;
position: relative;
}
.Add-Task {
position: relative;
width: 100%;
}
.Add-Task-Input {
outline: none;
border: none;
padding: 5px 10px;
width: 100%;
font-size: 16px;
}
.Add-Task-Button {
outline: none;
border: none;
width: 100%;
padding: 5px 10px;
margin-top: 15px;
font-size: 16px;
cursor: pointer;
background: #D90429;
color: #FFFFFF;
}
.Add-Task-Button:hover {
background: #EF233C;
color: #FFFFFF;
}
.Tasks-Space-Heading {
margin-top: 15px;
padding: 5px 10px;
background: #2B2D42;
color: #FFFFFF;
}
.Pending-Tasks {
margin-top: 15px;
}
.Completed-Tasks {
margin-top: 15px;
}
.Task {
background: #FFFFFF;
padding: 5px 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
.Task-Operations {
display: flex;
align-items: center;
}
.Operation {
height: 20px;
margin-left: 10px;
cursor: pointer;
}
.Done {
text-decoration: line-through;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>To-Do List</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="Header">
<p class="Heading">TO-DO LIST</p>
</div>
<div class="Tasks-Space">
<div class="Add-Task">
<input type="text" placeholder="Enter your task here" class="Add-Task-Input">
<button class="Add-Task-Button">Add Task</button>
</div>
<p class="Tasks-Space-Heading">Pending Tasks</p>
<div class="Pending-Tasks">
<div class="Task">
<p class="Task-Text">Make a pie</p>
<div class="Task-Operations">
<img src="./Tick.png" alt="Done" class="Operation Tick">
<img src="./Cross.png" alt="Delete" class="Operation Cross">
</div>
</div>
<div class="Task">
<p class="Task-Text">Play Minecraft</p>
<div class="Task-Operations">
<img src="./Tick.png" alt="Done" class="Operation Tick">
<img src="./Cross.png" alt="Delete" class="Operation Cross">
</div>
</div>
</div>
<p class="Tasks-Space-Heading">Completed Tasks</p>
<div class="Completed-Tasks"></div>
</div>
<script src="./main.js"></script>
</body>
</html>
Try using this code
// Create a "close" button and append it to each list item
var myNodelist = document.getElementsByTagName("LI");
var i;
for (i = 0; i < myNodelist.length; i++) {
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
myNodelist[i].appendChild(span);
}
// Click on a close button to hide the current list item
var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
close[i].onclick = function(data) {
var div = this.parentElement;
div.style.display = "none";
var data = div.innerText;
var list = document.getElementById("list");;
var firstname = div.value;
var entry = document.createElement('li');
entry.appendChild(document.createTextNode(data));
list.appendChild(entry);
}
}
// Add a "checked" symbol when clicking on a list item
var list = document.querySelector('ul');
list.addEventListener('click', function(ev) {
if (ev.target.tagName === 'LI') {
ev.target.classList.toggle('checked');
}
}, false);
// Create a new list item when clicking on the "Add" button
function newElement() {
var li = document.createElement("li");
var inputValue = document.getElementById("myInput").value;
var t = document.createTextNode(inputValue);
li.appendChild(t);
if (inputValue === '') {
alert("You must write something!");
} else {
document.getElementById("myUL").appendChild(li);
}
document.getElementById("myInput").value = "";
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
li.appendChild(span);
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
}
}
}
body {
margin: 0;
min-width: 250px;
font-family: arial;
}
/* Include the padding and border in an element's total width and height */
* {
box-sizing: border-box;
}
/* Remove margins and padding from the list */
ul {
margin: 0;
padding: 0;
}
/* Style the list items */
ul li {
cursor: pointer;
position: relative;
padding: 12px 8px 12px 40px;
list-style-type: none;
font-size: 18px;
transition: 0.2s;
border-bottom: 1px solid #eee;
margin-top: -1px;
/* make the list items unselectable */
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* When clicked on, add a background color and strike out text */
ul li.checked {
background: #888;
color: #fff;
text-decoration: line-through;
}
/* Add a "checked" mark when clicked on */
ul li.checked::before {
content: '';
position: absolute;
border-color: #fff;
border-style: solid;
border-width: 0 2px 2px 0;
top: 10px;
left: 16px;
transform: rotate(45deg);
height: 15px;
width: 7px;
}
/* Style the close button */
.close {
position: absolute;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.close:hover {
background-color: #f44336;
color: white;
}
/* Style the header */
.header {
background-color: #f44336;
padding: 30px 40px;
color: white;
text-align: center;
}
/* Clear floats after the header */
.header:after {
content: "";
display: table;
clear: both;
}
/* Style the input */
input {
margin: 0;
border: none;
border-radius: 0;
width: 75%;
padding: 10px;
float: left;
font-size: 16px;
}
input[type=text] {
outline: 0;
background: #eee;
border: 0;
transition: all .2s;
}
input[type=text]:focus {
background: #fff;
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);}
/* Style the "Add" button */
.addBtn {
padding: 10px;
width: 25%;
background: #d9d9d9;
color: #555;
float: left;
text-align: center;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
border-radius: 0;
}
.addBtn:hover {
background-color: #bbb;
}
<script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
<div id="myDIV" class="header">
<h2 style="margin:5px">My To Do List</h2>
<input type="text" id="myInput" placeholder="Title..." autocomplete="off">
<span onclick="newElement()" class="addBtn">Add</span>
</div>
<ul id="myUL">
<li>Hit the gym</li>
<li>Pay bills</li>
<li>Meet George</li>
<li>Buy eggs</li>
<li>Read a book</li>
<li>Organize office</li>
</ul>
<p style="padding-left: 30px;">Completed Tasks</p>
<ul id="list"></ul>

Categories

Resources