Create and Append new divs on button click with vanilla javascript - javascript

//hide element
function hide(x) {
var elems = document.getElementsByClassName(x);
for (var i = 0; i < elems.length; i += 1) {
elems[i].style.display = 'none';
}
}
//show element
function show(x) {
var elems = document.getElementsByClassName(x);
for (var i = 0; i < elems.length; i += 1) {
elems[i].style.display = 'block';
}
}
/* *************** listWrapper *************** */
var boardContainer = document.getElementsByClassName('board-container');
var newList = document.createElement('div'); //create new list-wrapper for holding lists
newList.className = 'new-list'; //assign id or class to div
newList.classList.add("list-wrapper"); //add another classname to the new-list div
//Check to see if a board-container exists and creates it if it does not exist and appends it to its parentNode
var boardContainerExist = true;
if (boardContainer === null) {
boardContainer = document.createElement('div');
boardContainer.class = 'board-container';
// adds the newly created element to the DOM
boardContainerExist = false;
}
for (var i = 0; i < boardContainer.length; i++) {
document.body.appendChild(newList); //add list-wrapper to the body/ or to the DOM
// document.getElementsByClassName("new-list") += "list-wrapper";
boardContainer[i].insertBefore(newList, boardContainer[i].childNodes[0]); //append new-list before the first-child
// document.getElementsByClassName('board-container')[0].appendChild(newList);
}
//create list-container
var listContainer = document.createElement('div');
listContainer.className = 'list-container';
//create list-head-container
var listHeadContainer = document.createElement('div');
listHeadContainer.className = 'list-head-container';
//create div to hold textarea
var textareaContainer = document.createElement('div');
textareaContainer.className = 'textarea-container';
//create textarea for lists
var textareaElement = document.createElement('textarea');
textareaElement.setAttribute("type", "text");
textareaElement.setAttribute("class", "textarea-title");
textareaElement.setAttribute("overflow", "break-word");
textareaElement.setAttribute("placeholder", "Enter list title...");
//create div container for ellipsis
//Note: The icon with three dots is called an ellipsis
var ellipsisContainer = document.createElement('div');
ellipsisContainer.className = 'ellipsis-container';
// create list to hold ellipsis
var ellipsisLink = document.createElement('a');
ellipsisLink.className = 'ellipsisLink';
ellipsisLink.setAttribute('href', '#');
ellipsisLink.innerHTML = '...';
//Add inner elements
newList.appendChild(listContainer); //add list-container inside new-list
listContainer.appendChild(listHeadContainer); //add list-head-container inside list-container
listHeadContainer.appendChild(textareaContainer); //add textarea container inside list-head-holder
textareaContainer.appendChild(textareaElement); //add textarea container inside textarea-container
textareaContainer.appendChild(ellipsisContainer); //add ellipsis container inside textarea-container
ellipsisContainer.appendChild(ellipsisLink); //add ellipsis link inside ellipsis container
var titleTaker = document.getElementsByClassName('list-input').value;
textareaElement.innerHTML = titleTaker;
body {
font-family: 'Roboto', sans-serif;
font-family: 'Open Sans', sans-serif;
color: rgb(12, 57, 83);
}
/* *************** boardWrapper *************** */
.board-wrapper {
position: relative;
/* flex-grow: 1; */
font-size: 14px;
}
.board-container {
display: flex;
flex-direction: row;
background-color: transparent;
}
.list-wrapper.first-wrapper {
width: 280px;
background-color: rgb(237, 239, 240);
border-radius: 3px;
/*** for rounded corners ***/
height: auto;
margin-left: 10px;
}
.list-wrapper {
width: 280px;
background-color: rgb(237, 239, 240);
border-radius: 3px;
/*** for rounded corners ***/
}
div.list-wrapper:first-child {
display: none;
margin-left: 5px;
}
.list-content {
height: 900px;
}
.list-content {
background-color: blue;
height: 100px;
width: 280px;
}
form {
/* padding: 5px; */
display: flex;
flex-direction: column;
}
a.list-links {
text-decoration: none;
color: rgb(255, 255, 255);
padding: 10px 20px 10px 5px;
background-color: rgba(0, 0, 0, 0.3);
border-radius: 3px;
}
a.list-links:hover {
background-color: rgba(0, 0, 0, 0.5);
}
span.add-another-list {
display: none;
}
.fa-plus {
font-size: 14px;
}
span.link-selector {
padding: 10px;
/* background-color: rgba(0,0,0,0.3); */
}
.add-list-button-container {
padding-top: 5px;
padding-bottom: 2px;
}
input[type=text].list-input {
display: block;
background-color: rgb(255, 255, 255);
border: 1px solid rgb(127, 170, 199);
border-radius: 3px;
height: 30px;
margin: 5px;
box-shadow: 0 0 0 1px rgb(127, 170, 199);
font-size: 14px;
padding-left: 10px;
display: none;
}
.add-list-button-container {
margin: 0 5px 5px;
display: none;
}
input[type=submit].list-input-button {
color: rgb(255, 255, 255);
background-color: #5aac44;
box-shadow: 0 1px 0 0 #3f6f21;
background-color: rgb(90, 172, 68);
box-shadow: 0 1px 2px 0 rgb(46, 73, 39);
border: none;
font-size: 14px;
height: 30px;
padding-left: 14px;
padding-right: 14px;
margin-right: 10px;
font-weight: 700;
}
.fa-times {
color: rgb(131, 140, 145);
font-size: 18px;
}
.textarea-container {
display: flex;
flex-direction: row;
}
textarea {
display: block;
word-wrap: break-word;
overflow: hidden;
padding: 5px 10px;
background-color: rgb(255, 255, 255);
border: 1px solid rgb(127, 170, 199);
border-radius: 3px;
font-size: 14px;
outline: none;
/* Removes the blue glow from around textarea */
resize: none;
/* Removes resize handle */
}
.textarea-title {
box-shadow: 0 0 0 1px rgb(127, 170, 199);
height: 20px;
max-height: 120px;
margin-top: 6px;
margin-left: 10px;
/* clear: right !important; */
}
.ellipsis-container {
margin-top: 6px;
margin-left: 47px;
border-radius: 3px;
}
.ellipsis-container:hover {
background-color: rgba(214, 218, 220, 0.8);
}
.ellipsis-container a.ellipsisLink {
font-size: 21px;
padding-left: 10px;
padding-right: 10px;
display: block;
text-align: center;
/* width: 16px; */
line-height: 20px;
text-decoration: none;
color: rgb(131, 140, 145);
}
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie-edge">
<title></title>
<!-- Link to CSS -->
<link rel="stylesheet" type="text/css" href="css/styles.css">
<!-- Link to Font-Awesome 5 -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
<!--Link to google fonts - Roboto and Open sans (400, 400 italics, 700 bold, 700 italics)-->
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i|Roboto" rel="stylesheet">
</head>
<body>
<!-- *************** boardWrapper *************** -->
<div class="board-wrapper">
<div class="board-container">
<!-- New lists are being created dynamically via javascript and are being placed here -->
<div class="list-wrapper first-wrapper">
<form onsubmit="return show('list-wrapper');">
<a class="list-links" href="#" onclick="hide('list-links'); show('list-input'); show('add-list-button-container'); ">
<span class="link-selector">
<span class="plus-icon"><i class="fas fa-plus"></i></span>
<span class="add-list">Add list</span>
<span class="add-another-list">Add another list</span>
</span>
</a>
<input type="text" class="list-input" required minlength="1" autocomplete="off" maxlength="500" placeholder="Enter list title...">
<div class="add-list-button-container">
<input class="list-input-button" type="submit" value="Add List" required minlength="1" maxlength="500" placeholder="Enter list title...">
<a class="list-close-button" href="#"><i class="fas fa-times"></i></a>
</div>
</form>
<!-- end of form -->
<!-- list content -->
</div>
<!-- end of list-wrapper -->
</div>
<!-- end of board-container -->
</div>
<!-- end of board-wrapper -->
<!-- Link to JavaScript -->
<script src="js/scripts.js"></script>
</body>
</html>
ther answers but none really covers all my issues.
So here's what I want to do
I'm working on a project to clone Trello using only HTML, CSS and vanilla JavaScript. I'm fairly new to javaScript and I'm trying to create multiple lists and I started by creating dynamic lists.
Here's what should happen:
1. A new list (which is really a div with a textarea) should be added (to the left side of the screen) each time the user writes text into the input field and clicks on the ***Add a list*** button.
2. The input that the user adds should be transferred over to new list as a title heading for that list. This title should be editable (meaning the user should be able to change the title text whenever he/she wants to.
Here are the issues I'm having:
1. The current code only allows me to add one single list.
2. I'm also not able to transfer text from the input field to the new list (in the textarea) --- what is now being transferred is the word 'undefined'.
3. Also, the list and buttons disappear after it has been clicked
It was suggested that I use unique IDs for the list but I just don't know how to do that as yet.
Link to the code on Codepen: https://codepen.io/Joanc/pen/MZjJvy
Really appreciate and looking forward to your help
//hide element
function hide(x) {
var elems = document.getElementsByClassName(x);
for (var i = 0; i < elems.length; i += 1) {
elems[i].style.display = 'none';
}
}
//show element
function show(x) {
var elems = document.getElementsByClassName(x);
for (var i = 0; i < elems.length; i += 1) {
elems[i].style.display = 'block';
}
}
/* *************** listWrapper *************** */
var boardContainer = document.getElementById('board-container');
var newList = document.createElement('div'); //create new list-wrapper for holding lists
newList.className = 'new-list'; //assign id or class to div
newList.classList.add("list-wrapper"); //add another classname to the new-list div
document.body.appendChild(newList); //add list-wrapper to the body/ or to the DOM
var boardContainer = document.getElementById('board-container');
boardContainer.insertBefore(newList, boardContainer.childNodes[0]); //append new-list before the first-child
//
//create list-container
var listContainer = document.createElement('div');
listContainer.className = 'list-container';
//create list-head-container
var listHeadContainer = document.createElement('div');
listHeadContainer.className = 'list-head-container';
//create div to hold textarea
var textareaContainer = document.createElement('div');
textareaContainer.className = 'textarea-container';
//create textarea for lists
var textareaElement = document.createElement('textarea');
textareaElement.setAttribute("type", "text");
textareaElement.setAttribute("class", "textarea-title");
textareaElement.setAttribute("overflow", "break-word");
textareaElement.setAttribute("placeholder", "Enter list title...");
//create div container for ellipsis
//Note: The icon with three dots is called an ellipsis
var ellipsisContainer = document.createElement('div');
ellipsisContainer.className = 'ellipsis-container';
// create list to hold ellipsis
var ellipsisLink = document.createElement('a');
ellipsisLink.className = 'ellipsisLink';
ellipsisLink.setAttribute('href', '#');
ellipsisLink.innerHTML = '...';
//Add inner elements
newList.appendChild(listContainer); //add list-container inside new-list
listContainer.appendChild(listHeadContainer); //add list-head-container inside list-container
listHeadContainer.appendChild(textareaContainer); //add textarea container inside list-head-holder
textareaContainer.appendChild(textareaElement); //add textarea container inside textarea-container
textareaContainer.appendChild(ellipsisContainer); //add ellipsis container inside textarea-container
ellipsisContainer.appendChild(ellipsisLink); //add ellipsis link inside ellipsis container
//grabbing user input and assigning it to title textarea
var titleTaker = document.getElementsByClassName('list-input').value;
textareaElement.innerHTML = titleTaker;
body {
font-family: 'Roboto', sans-serif;
font-family: 'Open Sans', sans-serif;
color: rgb(12, 57, 83);
}
/* *************** boardWrapper *************** */
.board-wrapper {
position: relative;
/* flex-grow: 1; */
font-size: 14px;
}
#board-container {
display: flex;
flex-direction: row;
}
.list-wrapper.first-wrapper {
width: 280px;
background-color: rgb(237, 239, 240);
border-radius: 3px;
/*** for rounded corners ***/
height: auto;
margin-left: 10px;
}
.list-wrapper {
width: 280px;
background-color: rgb(237, 239, 240);
border-radius: 3px;
/*** for rounded corners ***/
}
div.list-wrapper:first-child {
display: none;
margin-left: 5px;
}
.list-content {
height: 900px;
}
#board-container {
background-color: transparent;
}
.list-content {
background-color: blue;
height: 100px;
width: 280px;
}
form {
/* padding: 5px; */
display: flex;
flex-direction: column;
}
a.list-links {
text-decoration: none;
color: rgb(255, 255, 255);
padding: 10px 20px 10px 5px;
background-color: rgba(0, 0, 0, 0.3);
border-radius: 3px;
}
a.list-links:hover {
background-color: rgba(0, 0, 0, 0.5);
}
span.add-another-list {
display: none;
}
.fa-plus {
font-size: 14px;
}
span.link-selector {
padding: 10px;
/* background-color: rgba(0,0,0,0.3); */
}
.add-list-button-container {
padding-top: 5px;
padding-bottom: 2px;
}
input[type=text].list-input {
display: block;
background-color: rgb(255, 255, 255);
border: 1px solid rgb(127, 170, 199);
border-radius: 3px;
height: 30px;
margin: 5px;
box-shadow: 0 0 0 1px rgb(127, 170, 199);
font-size: 14px;
padding-left: 10px;
display: none;
}
.add-list-button-container {
margin: 0 5px 5px;
display: none;
}
input[type=submit].list-input-button {
color: rgb(255, 255, 255);
background-color: #5aac44;
box-shadow: 0 1px 0 0 #3f6f21;
background-color: rgb(90, 172, 68);
box-shadow: 0 1px 2px 0 rgb(46, 73, 39);
border: none;
font-size: 14px;
height: 30px;
padding-left: 14px;
padding-right: 14px;
margin-right: 10px;
font-weight: 700;
}
.fa-times {
color: rgb(131, 140, 145);
font-size: 18px;
}
.textarea-container {
display: flex;
flex-direction: row;
}
textarea {
display: block;
word-wrap: break-word;
overflow: hidden;
padding: 5px 10px;
background-color: rgb(255, 255, 255);
border: 1px solid rgb(127, 170, 199);
border-radius: 3px;
font-size: 14px;
outline: none;
/* Removes the blue glow from around textarea */
resize: none;
/* Removes resize handle */
}
.textarea-title {
box-shadow: 0 0 0 1px rgb(127, 170, 199);
height: 20px;
max-height: 120px;
margin-top: 6px;
margin-left: 10px;
/* clear: right !important; */
}
.ellipsis-container {
margin-top: 6px;
margin-left: 47px;
border-radius: 3px;
}
.ellipsis-container:hover {
background-color: rgba(214, 218, 220, 0.8);
}
.ellipsis-container a.ellipsisLink {
font-size: 21px;
padding-left: 10px;
padding-right: 10px;
display: block;
text-align: center;
/* width: 16px; */
line-height: 20px;
text-decoration: none;
color: rgb(131, 140, 145);
}
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie-edge">
<title></title>
<!-- Link to CSS -->
<link rel="stylesheet" type="text/css" href="css/styles.css">
<!-- Link to Font-Awesome 5 -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
<!--Link to google fonts - Roboto and Open sans (400, 400 italics, 700 bold, 700 italics)-->
<link href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i|Roboto" rel="stylesheet">
</head>
<body>
<!-- *************** boardWrapper *************** -->
<div class="board-wrapper">
<div id="board-container">
<div class="list-wrapper first-wrapper">
<form onsubmit="return show('list-wrapper');">
<a class="list-links" href="#" onclick="hide('list-links'); show('list-input'); show('add-list-button-container'); ">
<span class="link-selector">
<span class="plus-icon"><i class="fas fa-plus"></i></span>
<span class="add-list">Add list</span>
<span class="add-another-list">Add another list</span>
</span>
</a>
<input type="text" class="list-input" required minlength="1" autocomplete="off" maxlength="500" placeholder="Enter list title...">
<div class="add-list-button-container">
<input class="list-input-button" type="submit" value="Add List" required minlength="1" maxlength="500" placeholder="Enter list title...">
<a class="list-close-button" href="#"><i class="fas fa-times"></i></a>
</div>
</form>
<!-- end of form -->
<!-- list content -->
</div>
<!-- end of list-wrapper -->
</div>
<!-- end of board-container -->
</div>
<!-- end of board-wrapper -->
<!-- Link to JavaScript -->
<script src="js/scripts.js"></script>
</body>
</html>

Joan, because the javascript needed to be changed substantially I have created a simpler version of the code you are working on. With comments to call out how the functions would work. I hope it helps though.
// This method creates a single work item on the board and assigns click methods.
var createNewWorkItem = function(itemContainer) {
if(itemContainer && (typeof itemContainer.appendChild !== undefined)) {
var workItemActionPanel = document.createElement('div');
workItemActionPanel.setAttribute('class', 'work-item-panel' );
workItemActionPanel.onclick = closeWorkItemActionPanel;
var workItem = document.createElement('div');
workItem.setAttribute( 'class', 'work-item' );
workItem.onclick = showWorkItemActionPanel;
workItem.appendChild(workItemActionPanel);
itemContainer.appendChild(workItem);
}
};
// This is called when user clicks the action panel, closes it and calls to create
// a new work item
var closeWorkItemActionPanel = function(e) {
e.currentTarget.style.display = 'none';
var board = document.getElementById("workBoard");
createNewWorkItem(board);
e.stopPropagation() ;
};
// This is called when user clicks on a work item and shows the action panel
var showWorkItemActionPanel = function(e) {
var actionPanel = e.currentTarget.childNodes[0];
if(actionPanel.className !== 'work-item-panel') {
e.currentTarget.childNodes.forEach(node => {
if(node.className == 'work-item-panel') actionPanel = node;
});
}
actionPanel.style.display = 'inline-block';
};
// Initialize when the document has loaded.
(function(){
var board = document.getElementById("workBoard");
createNewWorkItem(board);
})();
.work-board {
background-color: aqua;
height: 500px;
border: 3px solid blue;
border-radius: 5px;
}
.work-item {
margin: 5px;
display: inline-block;
width: 50px;
height: 50px;
background-color: coral;
border-radius: 5px;
}
.work-item-panel {
margin: 5px;
height: 40px;
width: 40px;
display: none;
background-color: red;
}
<div id="workBoard" class="work-board">
</div>
I am using repl to write this, you can fork and play here: https://repl.it/#PaulThomas1/PTSimpleWorkBoardSample

Related

How can i remove the user input added paragraph automatically after 2 seconds in javascript?

i just learned how to create a to-do list in java script and as a personal project i wanted to use the information i learned in to-do app making by creating a tell your secret website which like the
const mytext = document.getElementById('mytext');
const btn = document.getElementById('btn');
const items = document.getElementById('items');
btn.addEventListener('click', function(e){
e.preventDefault();
const paragraph = document.createElement('p');
paragraph.classList.add("item");
paragraph.innerText = mytext.value;
items.appendChild(paragraph);
mytext.value = '';
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: rgb(231, 237, 241);
}
main {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 10%;
font-family: "Source Sans Pro", sans-serif;
}
h2 {
color: rgb(71, 80, 102);
font-size: 40px;
margin-bottom: 30px;
}
.myform {
display: flex;
justify-content: center;
align-items: center;
}
#btn {
margin-left: 10px;
width: 40px;
height: 100px;
white-space: pre-line;
text-align: center;
font-size: 15px;
font-weight: 600;
border: none;
border-radius: 10px;
cursor: pointer;
box-shadow: 2px 2px rgb(184, 182, 182);
color: rgb(35, 70, 136);
}
#btn:active {
color: rgb(48, 95, 182);
box-shadow: 0 0 2px grey;
}
#mytext {
background-color: aliceblue;
border-radius: 10px;
border: none;
padding: 7px;
box-shadow: 1px 1px rgb(200, 207, 212);
outline: none;
}
.items {
border-radius: 5px;
font-family: cursive;
color: rgb(61, 61, 60);
width: 400px;
display: flex;
justify-content: center;
margin-top: 10px;
padding: 5px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=MedievalSharp&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght#200;300;400;600;700;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./styles.css">
<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>Document</title>
</head>
<body>
<main>
<h2>Write Your Secret</h2>
<div class="container">
<form class="myform" action="">
<textarea name="text" id="mytext" cols="30" rows="10" placeholder="Write Whatever You Wish"></textarea>
<button id="btn">S
h
a
r
e</button>
</form>
<div class="items" id="items"></div>
</div>
</main>
<script src="./app.js"></script>
</body>
</html>
to-do app user writes something in the box (his/her secret) and the secret is displayed on the screen but
this is what i need:
i need the displayed paragraph to be removed automatically after 2 second like the secret vanishes 2 second after you write it.even better if it vanishes slowly like the ink vanishes in harry potter movie in tom riddle diary but that's not important i just want to remove the secret after 2 seconds first and then worry about the style that it vanishes.
With the simple addition of this code:
setTimeout(() => paragraph.classList.add("hidden"), 2000)
Which adds the class "hidden" after 2 seconds it will do what you want. You could make class hidden do anything, such as just set the visibility to hidden but you can also do transition effects like the one you deswcribe:
.hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
If using a transition like above you can also add this line to remove the element when the transition completes
paragraph.addEventListener('transitionend',() => paragraph.remove())
Live example below
const mytext = document.getElementById('mytext');
const btn = document.getElementById('btn');
const items = document.getElementById('items');
btn.addEventListener('click', function(e){
e.preventDefault();
const paragraph = document.createElement('p');
paragraph.classList.add("item");
paragraph.innerText = mytext.value;
items.appendChild(paragraph);
mytext.value = '';
paragraph.addEventListener('transitionend',() => paragraph.remove())
setTimeout(() => paragraph.classList.add("hidden"), 2000)
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: rgb(231, 237, 241);
}
main {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 10%;
font-family: "Source Sans Pro", sans-serif;
}
h2 {
color: rgb(71, 80, 102);
font-size: 40px;
margin-bottom: 30px;
}
.myform {
display: flex;
justify-content: center;
align-items: center;
}
#btn {
margin-left: 10px;
width: 40px;
height: 100px;
white-space: pre-line;
text-align: center;
font-size: 15px;
font-weight: 600;
border: none;
border-radius: 10px;
cursor: pointer;
box-shadow: 2px 2px rgb(184, 182, 182);
color: rgb(35, 70, 136);
}
#btn:active {
color: rgb(48, 95, 182);
box-shadow: 0 0 2px grey;
}
#mytext {
background-color: aliceblue;
border-radius: 10px;
border: none;
padding: 7px;
box-shadow: 1px 1px rgb(200, 207, 212);
outline: none;
}
.items {
border-radius: 5px;
font-family: cursive;
color: rgb(61, 61, 60);
width: 400px;
display: flex;
justify-content: center;
margin-top: 10px;
padding: 5px;
}
.hidden {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
<main>
<h2>Write Your Secret</h2>
<div class="container">
<form class="myform" action="">
<textarea name="text" id="mytext" cols="30" rows="10" placeholder="Write Whatever You Wish"></textarea>
<button id="btn">S
h
a
r
e</button>
</form>
<div class="items" id="items"></div>
</div>
</main>
const btn = document.getElementById('btn');
const items = document.getElementById('items');
const clearInput = () => {
setInterval(function(){mytext.value = ''; }, 2000);
}
btn.addEventListener('click', function(e){
e.preventDefault();
const paragraph = document.createElement('p');
paragraph.classList.add("item");
paragraph.innerText = mytext.value;
items.appendChild(paragraph);
mytext.value = '';
});
clearInput()

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>

Delete button doesn't show up on some of the tasks on the todo list

I made a todo app, but you can't delete some of the items. I tried a lot of stuff, but it doesn't work. Can you help me understand the reason for the errors? I'm also trying to figure out a way to increase the character limit.
html:
<!DOCTYPE html>
<!-- Created By Zarif Sefat -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SideQuests | Simple Todo App</title>
<link rel="stylesheet" href="style.css">
<script src="https://kit.fontawesome.com/a076d05399.js"></script>
<link rel="icon" href="images/icon.png">
</head>
<body>
<h1 class="logo-or-something"><i class="fas fa-check-square"></i> SideQuests</h1>
<div class="wrapper">
<header>SIDE QUESTS</header>
<div class="inputField">
<input type="text" placeholder="Add your new side quest">
<button><i class="fas fa-plus"></i></button>
</div>
<ul class="todoList">
<!-- data are comes from local storage -->
</ul>
<div class="footer">
<span>You have <span class="pendingTasks"></span> pending side quests</span>
<button>Clear All</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
css:
#import url('https://fonts.googleapis.com/css2?family=Poppins:wght#200;300;400;500;600;700&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
::selection{
color: #ffff;
background: rgb(142, 73, 232);
}
body{
width: 100%;
height: 100vh;
padding: 10px;
background: linear-gradient(to bottom, #68EACC 0%, #497BE8 100%);
}
.wrapper{
background: #fff;
max-width: 400px;
width: 100%;
margin: 120px auto;
padding: 25px;
border-radius: 5px;
box-shadow: 0px 10px 15px rgba(0,0,0,0.1);
}
.wrapper header{
font-size: 30px;
font-weight: 600;
}
.wrapper .inputField{
margin: 20px 0;
width: 100%;
display: flex;
height: 45px;
}
.inputField input{
width: 85%;
height: 100%;
outline: none;
border-radius: 3px;
border: 1px solid #ccc;
font-size: 17px;
padding-left: 15px;
transition: all 0.3s ease;
}
.inputField input:focus{
border-color: #8E49E8;
}
.inputField button{
width: 50px;
height: 100%;
border: none;
color: #fff;
margin-left: 5px;
font-size: 21px;
outline: none;
background: #8E49E8;
cursor: pointer;
border-radius: 3px;
opacity: 0.6;
pointer-events: none;
transition: all 0.3s ease;
}
.inputField button:hover,
.footer button:hover{
background: #721ce3;
}
.inputField button.active{
opacity: 1;
pointer-events: auto;
}
.wrapper .todoList{
max-height: 250px;
overflow-y: auto;
}
.todoList li{
position: relative;
list-style: none;
height: 45px;
line-height: 45px;
margin-bottom: 8px;
background: #f2f2f2;
border-radius: 3px;
padding: 0 15px;
cursor: default;
overflow: hidden;
}
.todoList li .icon{
position: absolute;
right: -45px;
background: #e74c3c;
width: 45px;
text-align: center;
color: #fff;
border-radius: 0 3px 3px 0;
cursor: pointer;
transition: all 0.2s ease;
}
.todoList li:hover .icon{
right: 0px;
}
.wrapper .footer{
display: flex;
width: 100%;
margin-top: 20px;
align-items: center;
justify-content: space-between;
}
.footer button{
padding: 6px 10px;
border-radius: 3px;
border: none;
outline: none;
color: #fff;
font-weight: 400;
font-size: 16px;
margin-left: 5px;
background: #8E49E8;
cursor: pointer;
user-select: none;
opacity: 0.6;
pointer-events: none;
transition: all 0.3s ease;
}
.footer button.active{
opacity: 1;
pointer-events: auto;
}
.logo-or-something {
color: rgb(142, 73, 232);
}
js:
// getting all required elements
const inputBox = document.querySelector(".inputField input");
const addBtn = document.querySelector(".inputField button");
const todoList = document.querySelector(".todoList");
const deleteAllBtn = document.querySelector(".footer button");
// onkeyup event
inputBox.onkeyup = ()=>{
let userEnteredValue = inputBox.value; //getting user entered value
if(userEnteredValue.trim() != 0){ //if the user value isn't only spaces
addBtn.classList.add("active"); //active the add button
}else{
addBtn.classList.remove("active"); //unactive the add button
}
}
showTasks(); //calling showTask function
addBtn.onclick = ()=>{ //when user click on plus icon button
let userEnteredValue = inputBox.value; //getting input field value
let getLocalStorageData = localStorage.getItem("New Todo"); //getting localstorage
if(getLocalStorageData == null){ //if localstorage has no data
listArray = []; //create a blank array
}else{
listArray = JSON.parse(getLocalStorageData); //transforming json string into a js object
}
listArray.push(userEnteredValue); //pushing or adding new value in array
localStorage.setItem("New Todo", JSON.stringify(listArray)); //transforming js object into a json string
showTasks(); //calling showTask function
addBtn.classList.remove("active"); //unactive the add button once the task added
}
function showTasks(){
let getLocalStorageData = localStorage.getItem("New Todo");
if(getLocalStorageData == null){
listArray = [];
}else{
listArray = JSON.parse(getLocalStorageData);
}
const pendingTasksNumb = document.querySelector(".pendingTasks");
pendingTasksNumb.textContent = listArray.length; //passing the array length in pendingtask
if(listArray.length > 0){ //if array length is greater than 0
deleteAllBtn.classList.add("active"); //active the delete button
}else{
deleteAllBtn.classList.remove("active"); //unactive the delete button
}
let newLiTag = "";
listArray.forEach((element, index) => {
newLiTag += `<li>${element}<span class="icon" onclick="deleteTask(${index})"><i class="fas fa-trash"></i></span></li>`;
});
todoList.innerHTML = newLiTag; //adding new li tag inside ul tag
inputBox.value = ""; //once task added leave the input field blank
}
// delete task function
function deleteTask(index){
let getLocalStorageData = localStorage.getItem("New Todo");
listArray = JSON.parse(getLocalStorageData);
listArray.splice(index, 1); //delete or remove the li
localStorage.setItem("New Todo", JSON.stringify(listArray));
showTasks(); //call the showTasks function
}
// delete all tasks function
deleteAllBtn.onclick = ()=>{
listArray = []; //empty the array
localStorage.setItem("New Todo", JSON.stringify(listArray)); //set the item in localstorage
showTasks(); //call the showTasks function
}
If you remove this from your css:
.todoList li{
overflow: hidden;
}
And you will enter a long input, you will see where the problem is. It's not that the button doesn't show up, but it's where it shows up.
When your div is too long, the button won't appear in the same line, but lower, causing you to not see it.
To solve this problem, you could add this (the overflow hidden was already there):
.todoList li{
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
Setting hoverflow:hidden won't allow you to scroll, but the entire text would still be there. The other two lines will make the css cut the text when there's no more space. And this will make your button appear in the right place.

How to search text from a ul and display results in real time?

I'm trying to be able to search for text inside the listed tasks and display right away as soon as a user types in the input box. I got a snippet of code from w3schools and tried to work it into my current JS file but can't seem to get it to work. Perhaps someone can get me on the right track and tell me what I did wrong.
//Define UI Variables
const form = document.querySelector('#task-form');
const taskList = document.querySelector('.task-list');
const clearTaskButton = document.querySelector('.clear-tasks-btn');
const taskFilter = document.querySelector('#task-filter');
const inputBox = document.querySelector('#input-box');
const addTaskButton = document.querySelector('.add-task-btn');
// Load event listeners
loadEventListeners();
// Function to load event listeners
function loadEventListeners() {
form.addEventListener('submit', addTask);
taskList.addEventListener('click', removeTask);
clearTaskButton.addEventListener('click', clearTasks);
taskFilter.addEventListener('oninput', filterTasks);
}
//Add Task
function addTask(e) {
if (inputBox.value === '') {
alert('Please add a task!');
}
//Create li element
const liTag = document.createElement('li');
liTag.className = 'task-item';
//Append input from input box into li element
liTag.appendChild(document.createTextNode(inputBox.value));
// Create new link element with a class of "delete-item"
const linkTag = document.createElement('a');
linkTag.className = 'delete-item';
// Add icon HTML
linkTag.innerHTML = '<i class="fas fa-times"></i>';
// Append link to li
liTag.appendChild(linkTag);
// Append li to ul
taskList.appendChild(liTag);
// Clear input
inputBox.value = '';
e.preventDefault();
}
//Remove Tasks
function removeTask(e) {
if (e.target.parentElement.classList.contains('delete-item')) {
e.target.parentNode.parentNode.remove();
}
}
//Clear Tasks
function clearTasks(e) {
//Alert if there are no tasks (li) inside the task list (ul)
if (taskList.childNodes.length < 1) {
alert('No tasks to clear!');
}
else {
taskList.innerHTML = '';
}
}
//Filter Tasks
function filterTasks(e) {
var filter, liTag, a, i, txtValue;
filter = taskFilter.value.toUpperCase();
liTag = taskList.getElementsByTagName('li');
for (i = 0; i < liTag.length; i++) {
a = liTag[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
liTag[i].style.display = "";
} else {
liTag[i].style.display = "none";
}
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Lato', sans-serif;
}
/* ====HEADING==== */
h1 {
font-size: 1.2rem;
font-weight: 400;
margin-bottom: 20px;
text-transform: uppercase;
letter-spacing: 4px;
}
h2 {
font-size: 1.2rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 4px;
margin-bottom: 5px;
}
h3 {
font-size: 14px;
font-weight: 400;
color: #808080;
margin-bottom: 10px;
}
.grid {
display: flex;
flex-direction: column;
margin-top: 10px;
}
.add-task,
.tasks {
width: 75%;
padding: 15px 15px;
}
/* Styles for smaller screens BEGIN */
#media only screen and (max-width: 600px) {
.add-task,
.tasks {
width: 90%;
}
}
/* Styles for smaller screens END */
.add-task,
.tasks {
margin: auto;
border: 0.5px solid #E6E6E6;
-webkit-box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15);
-moz-box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15);
box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15);
margin-bottom: 20px;
}
#input-box,
#task-filter {
margin-bottom: 20px;
width: 100%;
background: transparent;
border: none;
border-bottom: 1px solid #9E9E9E;
}
::-webkit-input-placeholder { /* WebKit, Blink, Edge */
color: black;
}
/* ====BUTTONS==== */
.add-task-btn,
.clear-tasks-btn {
padding: 10px 20px;
border: 0;
color: white;
text-transform: uppercase;
text-decoration: none;
font-size: 1rem;
}
.add-task-btn {
background: #00A081;
border: 0px solid #000000;
-webkit-appearance: none;
}
.clear-tasks-btn {
background: black;
}
/* ====LIST OF TASKS==== */
.tasks {
background: white;
margin: 10px auto;
padding-bottom: 20px;
-webkit-box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15);
-moz-box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15);
box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15);
}
.task-list {
list-style-type: none;
width: 100%;
margin-bottom: 20px;
}
.task-list li {
border: 1px solid #E0E0E0;
padding: 10px 20px 10px 20px;
display: flex;
justify-content: space-between;
}
/* ===REMOVE TOP BORDER OF SECOND - FIFTH LI */
.task-list li:nth-child(n+2):nth-child(-n+5) {
border-top: 0px;
}
/* ===ICONS=== */
.fas:hover {
color: #26A69A;
}
<!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">
<title>Task List</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" integrity="sha384-gfdkjb5BdAXd+lj+gudLWI+BXq4IuLW5IT+brZEZsLFm++aCMlF1V92rMkPaX4PP"
crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet">
<link rel="stylesheet" href="assets/css/tasklist.css" </head> <body>
<div class="grid">
<div class="add-task">
<h1>Task List</h1>
<form id="task-form">
<label for="input">New Task</label>
<input type="text" name="input" id="input-box">
<input type="submit" value="Add Task" class="add-task-btn">
</form>
</div>
<div class="tasks">
<h2>Tasks</h2>
<form id="insert-form">
<input type="text" name="insert" placeholder="Search for tasks.." id="task-filter">
</form>
<ul class="task-list"></ul>
Clear Tasks
</div>
</div>
<script src="assets/js/tasklist.js"></script>
</body>
</html>
Just replace this code taskFilter.addEventListener('oninput', filterTasks);
to this one taskFilter.addEventListener('keyup', filterTasks);, please do refer here for the list of available events for DOM in Javascript.
The event name is "input", not "oninput".
Also your filter is wrong, the text is inside the <li> instead of <a>.
you can check the event name list here https://developer.mozilla.org/en-US/docs/Web/Events
//Define UI Variables
const form = document.querySelector('#task-form');
const taskList = document.querySelector('.task-list');
const clearTaskButton = document.querySelector('.clear-tasks-btn');
const taskFilter = document.querySelector('#task-filter');
const inputBox = document.querySelector('#input-box');
const addTaskButton = document.querySelector('.add-task-btn');
// Load event listeners
loadEventListeners();
// Function to load event listeners
function loadEventListeners() {
form.addEventListener('submit', addTask);
taskList.addEventListener('click', removeTask);
clearTaskButton.addEventListener('click', clearTasks);
taskFilter.addEventListener('input', filterTasks);
}
//Add Task
function addTask(e) {
if (inputBox.value === '') {
alert('Please add a task!');
}
//Create li element
const liTag = document.createElement('li');
liTag.className = 'task-item';
//Append input from input box into li element
liTag.appendChild(document.createTextNode(inputBox.value));
// Create new link element with a class of "delete-item"
const linkTag = document.createElement('a');
linkTag.className = 'delete-item';
// Add icon HTML
linkTag.innerHTML = '<i class="fas fa-times"></i>';
// Append link to li
liTag.appendChild(linkTag);
// Append li to ul
taskList.appendChild(liTag);
// Clear input
inputBox.value = '';
e.preventDefault();
}
//Remove Tasks
function removeTask(e) {
if (e.target.parentElement.classList.contains('delete-item')) {
e.target.parentNode.parentNode.remove();
}
}
//Clear Tasks
function clearTasks(e) {
//Alert if there are no tasks (li) inside the task list (ul)
if (taskList.childNodes.length < 1) {
alert('No tasks to clear!');
}
else {
taskList.innerHTML = '';
}
}
//Filter Tasks
function filterTasks(e) {
var filter, liTag, a, i, txtValue;
filter = taskFilter.value.toUpperCase();
liTag = taskList.getElementsByTagName('li');
for (i = 0; i < liTag.length; i++) {
txtValue = liTag[i].textContent || liTag[i].innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
liTag[i].style.display = "";
} else {
liTag[i].style.display = "none";
}
}
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Lato', sans-serif;
}
/* ====HEADING==== */
h1 {
font-size: 1.2rem;
font-weight: 400;
margin-bottom: 20px;
text-transform: uppercase;
letter-spacing: 4px;
}
h2 {
font-size: 1.2rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 4px;
margin-bottom: 5px;
}
h3 {
font-size: 14px;
font-weight: 400;
color: #808080;
margin-bottom: 10px;
}
.grid {
display: flex;
flex-direction: column;
margin-top: 10px;
}
.add-task,
.tasks {
width: 75%;
padding: 15px 15px;
}
/* Styles for smaller screens BEGIN */
#media only screen and (max-width: 600px) {
.add-task,
.tasks {
width: 90%;
}
}
/* Styles for smaller screens END */
.add-task,
.tasks {
margin: auto;
border: 0.5px solid #E6E6E6;
-webkit-box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15);
-moz-box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15);
box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15);
margin-bottom: 20px;
}
#input-box,
#task-filter {
margin-bottom: 20px;
width: 100%;
background: transparent;
border: none;
border-bottom: 1px solid #9E9E9E;
}
::-webkit-input-placeholder { /* WebKit, Blink, Edge */
color: black;
}
/* ====BUTTONS==== */
.add-task-btn,
.clear-tasks-btn {
padding: 10px 20px;
border: 0;
color: white;
text-transform: uppercase;
text-decoration: none;
font-size: 1rem;
}
.add-task-btn {
background: #00A081;
border: 0px solid #000000;
-webkit-appearance: none;
}
.clear-tasks-btn {
background: black;
}
/* ====LIST OF TASKS==== */
.tasks {
background: white;
margin: 10px auto;
padding-bottom: 20px;
-webkit-box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15);
-moz-box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15);
box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.15);
}
.task-list {
list-style-type: none;
width: 100%;
margin-bottom: 20px;
}
.task-list li {
border: 1px solid #E0E0E0;
padding: 10px 20px 10px 20px;
display: flex;
justify-content: space-between;
}
/* ===REMOVE TOP BORDER OF SECOND - FIFTH LI */
.task-list li:nth-child(n+2):nth-child(-n+5) {
border-top: 0px;
}
/* ===ICONS=== */
.fas:hover {
color: #26A69A;
}
<!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">
<title>Task List</title>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" integrity="sha384-gfdkjb5BdAXd+lj+gudLWI+BXq4IuLW5IT+brZEZsLFm++aCMlF1V92rMkPaX4PP"
crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Lato:400,700" rel="stylesheet">
<link rel="stylesheet" href="assets/css/tasklist.css" </head> <body>
<div class="grid">
<div class="add-task">
<h1>Task List</h1>
<form id="task-form">
<label for="input">New Task</label>
<input type="text" name="input" id="input-box">
<input type="submit" value="Add Task" class="add-task-btn">
</form>
</div>
<div class="tasks">
<h2>Tasks</h2>
<form id="insert-form">
<input type="text" name="insert" placeholder="Search for tasks.." id="task-filter">
</form>
<ul class="task-list"></ul>
Clear Tasks
</div>
</div>
<script src="assets/js/tasklist.js"></script>
</body>
</html>

Categories

Resources