When new elements are created on the page, they are showing up as [object HTMLLIElement] instead being created as an li element, like I want it to.
Codepen link here so you can see what I am talking about https://codepen.io/jester070993/pen/bLOrQr
var h1 = document.querySelector("h1")
var lis = document.querySelectorAll("li")
var trashes = document.querySelectorAll("span")
var filterInput = document.querySelector("input")
var container = document.querySelector("#container")
var ul = document.querySelector("ul")
var i = document.querySelectorAll("i")
function goToTrash(event){
var thisElement = event.currentTarget;
thisElement.parentElement.remove()
}
function handleClick(event){
var thisElement = event.currentTarget;
thisElement.classList.toggle("completed")
}
//forEach loop
lis.forEach(function(li){
li.addEventListener("click", handleClick)
trashes.forEach(function(trash){
trash.addEventListener("click", goToTrash)
});
});
filterInput.addEventListener("keypress", function(event){
if(event.which === 13){
var todo = filterInput.value;
var newLi = document.createElement("li");
var element = newLi.appendChild(document.createTextNode(todo));
ul.appendChild(newLi);
filterInput.value = " ";
newLi.addEventListener("click", handleClick);
newLi.innerHTML = "<i class='far fa-trash-alt'></i>" + newLi; //This is the line that is creating a new element (li) except it is showing up as [object HTMLLIElement]
trashes.forEach(function(span){
span.addEventListener("click", goToTrash);
})
}
});
What am I doing wrong? Would I have to use .current or .currentTarget? Tried both of those and then it just returns "undefined" instead of [object HTMLLIElement]
Here is what I have tried. Maybe you can do it too. You can't just use '+' operator to add an HTMLObject (that is what you newLi is!). you have to use DOM API API to manupulate DOM.
var iconSpan = document.createElement("span")
var icon = document.createElement("i");
icon.classList.add("far");
icon.classList.add("fa-trash-alt");
iconSpan.append(icon);
newLi.prepend(iconSpan);
var h1 = document.querySelector("h1")
var lis = document.querySelectorAll("li")
var trashes = document.querySelectorAll("span")
var filterInput = document.querySelector("input")
var container = document.querySelector("#container")
var ul = document.querySelector("ul")
var i = document.querySelectorAll("i")
function goToTrash(event){
var thisElement = event.currentTarget;
thisElement.parentElement.remove()
}
function handleClick(event){
var thisElement = event.currentTarget;
thisElement.classList.toggle("completed")
}
//forEach loop
lis.forEach(function(li){
li.addEventListener("click", handleClick)
trashes.forEach(function(trash){
trash.addEventListener("click", goToTrash)
});
});
filterInput.addEventListener("keypress", function(event){
if(event.which === 13){
var todo = filterInput.value;
var newLi = document.createElement("li");
var element = newLi.appendChild(document.createTextNode(todo));
ul.appendChild(newLi);
filterInput.value = " ";
var iconSpan = document.createElement("span")
var icon = document.createElement("i");
icon.classList.add("far");
icon.classList.add("fa-trash-alt");
iconSpan.append(icon);
newLi.addEventListener("click", handleClick);
newLi.prepend(iconSpan);
trashes.forEach(function(span){
span.addEventListener("click", goToTrash);
})
}
});
#container {
text-align:center;
margin: 0 auto;
width: 360px;
margin-top: 50px;
background:#f7f7f7;
box-shadow: 2px 2px 3px magenta;
}
.completed {
text-decoration: line-through;
opacity: .4;
}
body {
background: linear-gradient(to right, yellow , orange);
}
li span {
visibility: hidden ;
width: 0;
}
span {
margin-right: 15px;
height: 40px;
margin-left: 10px;
color:coral;
text-align: center;
width: 400px
visibility: hidden;
}
li:hover span{
visibility: visible ;
width: 40px;
transition-timing-function: linear;
}
#plus{
float: right;
}
a{
color:white;
}
h1{
background: steelblue;
color: white;
margin: 0;
padding: 10px 20px;
text-transform: uppercase;
font-size: 30px;
font-weight: normal;
}
input {
width: 100%;
font-size: 18px;
background: #f7f7f7;
padding: 12px 12px 12px 16px;
box-sizing: border-box;
color: steelblue;
}
input:focus {
background:white;
border: 2px solid steelblue;
outline: none;
}
ul{
list-style: none;
margin: 0;
padding: 0;
text-align:left;
font-size: 16px;
}
body{
font-family: 'Krona One', sans-serif;
}
li {
background: white;
height: 34px;
line-height: 34px;
color: 664;
}
li:nth-child(2n){
background: #f7f7f7;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="practice.css">
<link href="https://fonts.googleapis.com/css?family=Krona+One" rel="stylesheet">
<script type="text/javascript" src="jquery/jquery-3.3.1.js"></script>
<script defer src="https://use.fontawesome.com/releases/v5.0.7/js/all.js"></script>
</head>
<body>
<div id="container">
<h1> To-do List <i class="fas fa-plus-circle" id="plus"></i> </h1>
<input type="text" placeholder="Add New Todo">
<ul>
<li><span><i class="far fa-trash-alt"></i>
</span> Walk dog </li>
<li><span><i class="far fa-trash-alt"></i>
</span> Buy white undershirts </li>
<li><span><i class="far fa-trash-alt"></i>
</span> Study JS </li>
<li><span><i class="far fa-trash-alt"></i>
</span> Wake up early</li>
</ul>
</div>
</body>
</html>
Probably this is just a typo. If you mean you want to display the text inputted beside the icon.
From:
var todo = filterInput.value;
var newLi = document.createElement("li");
var element = newLi.appendChild(document.createTextNode(todo));
ul.appendChild(newLi);
filterInput.value = " ";
newLi.addEventListener("click", handleClick);
newLi.innerHTML = "<i class='far fa-trash-alt'></i>" + newLi; //This is the line that is creating a new element (li) except it is showing up as [object HTMLLIElement]
trashes.forEach(function(span){
span.addEventListener("click", goToTrash);
})
To:
var todo = filterInput.value;
var newLi = document.createElement("li");
ul.appendChild(newLi);
filterInput.value = " ";
newLi.addEventListener("click", handleClick);
newLi.innerHTML = "<i class='far fa-trash-alt'></i>" + todo;
trashes.forEach(function(span){
span.addEventListener("click", goToTrash);
})
Related
Still learning so bear with me.
I am building a test project where I have a simple input that I show it on the same page as a list. (grocery or to do list project)
So when a user hits the ok button I create a new li inside a ul element. That goes ok.
I want to implement the following though: When the user clicks on the new element (li) I want to change the text decoration to line-though and show a trash icon where it will remove this li element by clicking on it.
I have managed to do that. The problem is that when the user clicks again on the new element (li) I get a second trash image.
I want help to succeed in this: when a user clicks on the element while it has text-decoration = line-through to hide or remove the trash icon and make text-decoration none again.
Here is a code pen for this project to check out. Just insert a new item on the list and then click twice on it: https://codepen.io/dourvas-ioannis/pen/MWVBjNZ
This is the function I am using when the user hits the add button to add a list item:
function addToList(){
let newListItem = document.createElement('li');
newListItem.textContent = userInput.value;
list.appendChild(newListItem);
userInput.value = "";
newListItem.addEventListener('click', function(){
this.style.textDecoration = 'line-through';
let itemButton = document.createElement('a');
itemButton.setAttribute('href', '#');
itemButton.classList.add('trash-image');
itemButton.innerHTML = '<i class="material-icons">delete</i><a/>';
itemButton.addEventListener("click", deleteOneItem);
this.appendChild(itemButton);
});
}
function deleteOneItem(){
this.parentNode.remove();
}
//select from DOM
let allItems = document.querySelector('#allItems');
let button = document.querySelector('#add-button');
let userInput = document.querySelector('#item');
let list = document.querySelector('#list');
let clear = document.querySelector('#clear-button');
//add event listener
button.addEventListener('click', addToList);
clear.addEventListener('click', clearAll);
//functions
function addToList() {
let newListItem = document.createElement('li');
newListItem.textContent = userInput.value;
list.appendChild(newListItem);
userInput.value = "";
newListItem.addEventListener('click', function() {
this.style.textDecoration = 'line-through';
let itemButton = document.createElement('a');
itemButton.setAttribute('href', '#');
itemButton.classList.add('trash-image');
itemButton.innerHTML = '<i class="material-icons">delete</i><a/>';
itemButton.addEventListener("click", deleteOneItem);
this.appendChild(itemButton);
});
}
function deleteOneItem() {
this.parentNode.remove();
}
function clearAll() {
list.innerHTML = "";
}
body {
font-size: 10px;
font-family: Arial, Helvetica, sans-serif;
margin: 0;
background-color: antiquewhite;
}
#container {
width: 80%;
margin: auto;
padding-top: 10px;
background-color: rgb(200, 225, 225);
color: rgb(52, 48, 48);
border-radius: 10px;
}
p {
font-size: 20px;
text-align: center;
padding: 30px, 0px, 5px, 0px;
}
#formdiv {
text-align: center;
}
#item {
size: 100px;
}
#clear {
margin-top: 60px;
text-align: center;
}
li {
list-style-type: none;
font-size: 3.2em;
padding: 0.5em;
margin: 1em;
background-color: lightyellow;
border-radius: 5px;
border: 1px solid grey;
}
.trash-image {
float: right;
margin: -2px 3px 3px 3px;
vertical-align: middle;
height: 4px;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<body>
<br> <br> <br>
<div id='container'>
<p>My list</p>
<br>
<div id="formdiv">
<label for="item">add this.. </label><br>
<input type="text" name="item" id="item">
<button id="add-button"> add </button>
</div>
<div id="allItems">
<ul id="list">
</ul>
</div>
<div id="clear">
<button id="clear-button"> Clear List </button><br> <br> <br>
</div>
</div>
Here's a quick example implementation of the approach I mentioned in the comments. I've just hacked it together quickly, so there's a small difference for the bin.
I've used an img (without a src) instead of a 'character' from the
font. I've styled the img to be 16x16 for the same reason. It also
makes it visible instead of being 0x0 pixels. I also set the cursor.
"use strict";
window.addEventListener('load', onLoad, false);
function onLoad(evt) {
document.querySelector('button').addEventListener('click', onAddBtnClicked, false);
}
function onAddBtnClicked(evt) {
let userText = document.querySelector('input').value;
let newLi = document.createElement('li');
newLi.textContent = userText;
newLi.addEventListener('click', onIncompleteItemClicked, false);
document.querySelector('ul').appendChild(newLi);
}
function onIncompleteItemClicked(evt) {
let clickedLi = this;
clickedLi.classList.toggle('itemComplete');
let binImg = document.createElement('img');
binImg.addEventListener('click', onBinIconClicked, false);
clickedLi.appendChild(binImg);
clickedLi.removeEventListener('click', onIncompleteItemClicked, false);
clickedLi.addEventListener('click', onCompletedItemClicked, false);
}
function onCompletedItemClicked(evt) {
let clickedLi = this;
clickedLi.classList.toggle('itemComplete');
let binImg = clickedLi.querySelector('img');
clickedLi.removeChild(binImg);
clickedLi.removeEventListener('click', onCompletedItemClicked, false);
clickedLi.addEventListener('click', onIncompleteItemClicked, false);
}
function onBinIconClicked(evt) {
let clickedBin = this;
let containingLi = clickedBin.parentNode;
containingLi.remove();
}
.itemComplete {
text-decoration: line-through;
}
li>img {
cursor: pointer;
width: 16px;
height: 16px;
}
<input value='blah-blah'></input><button>Add</button>
<ul></ul>
Add a variable indicating that the icon has been already added.
Check if icon is added on click
If yes - skip
If not - set icon
//select from DOM
let allItems = document.querySelector('#allItems');
let button = document.querySelector('#add-button');
let userInput = document.querySelector('#item');
let list = document.querySelector('#list');
let clear = document.querySelector('#clear-button');
//add event listener
button.addEventListener('click', addToList);
clear.addEventListener('click', clearAll);
//functions
function addToList() {
let newListItem = document.createElement('li');
newListItem.textContent = userInput.value;
list.appendChild(newListItem);
userInput.value = "";
// declare boolean variable
let hasTrashIcon = false
newListItem.addEventListener('click', function() {
// if has thrash icon skip
if (hasTrashIcon) return
// set has trash icon
hasTrashIcon = true
this.style.textDecoration = 'line-through';
let itemButton = document.createElement('a');
itemButton.setAttribute('href', '#');
itemButton.classList.add('trash-image');
itemButton.innerHTML = '<i class="material-icons">delete</i><a/>';
itemButton.addEventListener("click", deleteOneItem);
this.appendChild(itemButton);
});
}
function deleteOneItem() {
this.parentNode.remove();
}
function clearAll() {
list.innerHTML = "";
}
body {
font-size: 10px;
font-family: Arial, Helvetica, sans-serif;
margin: 0;
background-color: antiquewhite;
}
#container {
width: 80%;
margin: auto;
padding-top: 10px;
background-color: rgb(200, 225, 225);
color: rgb(52, 48, 48);
border-radius: 10px;
}
p {
font-size: 20px;
text-align: center;
padding: 30px, 0px, 5px, 0px;
}
#formdiv {
text-align: center;
}
#item {
size: 100px;
}
#clear {
margin-top: 60px;
text-align: center;
}
li {
list-style-type: none;
font-size: 3.2em;
padding: 0.5em;
margin: 1em;
background-color: lightyellow;
border-radius: 5px;
border: 1px solid grey;
}
.trash-image {
float: right;
margin: -2px 3px 3px 3px;
vertical-align: middle;
height: 4px;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<body>
<br> <br> <br>
<div id='container'>
<p>My list</p>
<br>
<div id="formdiv">
<label for="item">add this.. </label><br>
<input type="text" name="item" id="item">
<button id="add-button"> add </button>
</div>
<div id="allItems">
<ul id="list">
</ul>
</div>
<div id="clear">
<button id="clear-button"> Clear List </button><br> <br> <br>
</div>
</div>
I have tried to insert the data into the ToDo List and it is working but i am unable to edit the name and number field in the edit box of ToDo list.
And also the list is showing is not properly having padding and i tried to put padding in the list but whole list is shifting towards the left.
Also I tried with table concept in JavaScript but for that i need the loop and the database but i dont want to use the database or any other storage
var taskInput = document.getElementById("new-task");
var nameInput = document.getElementById("new-name");
var numberInput = document.getElementById("new-number");
var addButton = document.getElementsByTagName("button")[0];
var incompleteTask = document.getElementById("incomplete-tasks");
var completedTask = document.getElementById("completed-tasks");
var createNewTaskElement = function (taskString, nameString, numberString) {
var listItem = document.createElement("li");
var checkBox = document.createElement("input");
var label = document.createElement("label");
var label1 = document.createElement("label1");
var label2 = document.createElement("label2");
var editInput = document.createElement("input");
var editInput1 = document.createElement("input");
var editInput2 = document.createElement("input");
var editButton = document.createElement("button");
var deleteButton = document.createElement("button");
label.innerText = taskString;
label1.innerText = nameString;
label2.innerText = numberString;
checkBox.type = "checkbox";
editInput.type = "text";
editInput1.type = "text";
editInput2.type = "text";
editButton.innerText = "Edit";
editButton.className = "edit";
deleteButton.innerText = "Delete";
deleteButton.className = "delete";
listItem.appendChild(checkBox);
listItem.appendChild(label);
listItem.appendChild(editInput);
listItem.appendChild(label1);
listItem.appendChild(editInput1);
listItem.appendChild(label2);
listItem.appendChild(editInput2);
listItem.appendChild(editButton);
listItem.appendChild(deleteButton);
alert("You added '" + label.innerText + "' to the ToDO list");
return listItem;
}
var addTask = function () {
var listItem = createNewTaskElement(taskInput.value,nameInput.value,numberInput.value);
if (taskInput.value == "") {
alert("You must enter a task");
}
else if (nameInput.value == "") {
alert("You must enter a Name");
}
else if (numberInput.value == "") {
alert("You must enter a Phone Number");
} else {
incompleteTask.appendChild(listItem);
}
bindTaskEvents(listItem, taskCompleted);
taskInput.value = "";
nameInput.value = "";
numberInput.value = "";
}
var editTask = function () {
var listItem = this.parentNode;
var editInput = listItem.querySelector('input[type=text]');
var label = listItem.querySelector("label");
var containsClass = listItem.classList.contains("editMode");
if (containsClass) {
label.innerText = editInput.value;
alert("You edited " + label.innerText);
} else {
editInput.value = label.innerText;
}
listItem.classList.toggle("editMode");
}
var deleteTask = function () {
var listItem = this.parentNode;
var ul = listItem.parentNode;
alert("You deleted " + listItem.querySelector("label").innerText);
ul.removeChild(listItem);
}
var taskCompleted = function () {
var listItem = this.parentNode;
completedTask.appendChild(listItem);
bindTaskEvents(listItem, taskIncomplete);
alert("You completed " + listItem.querySelector("label").innerText);
}
var taskIncomplete = function () {
var listItem = this.parentNode;
incompleteTask.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
}
var bindTaskEvents = function (taskListItem, checkBoxEventHandler) {
var checkBox = taskListItem.querySelector("input[type=checkbox]");
var editButton = taskListItem.querySelector("button.edit");
var deleteButton = taskListItem.querySelector("button.delete");
editButton.onclick = editTask;
deleteButton.onclick = deleteTask;
checkBox.onchange = checkBoxEventHandler;
}
for (var i = 0; i < incompleteTask.children.length; i++) {
bindTaskEvents(incompleteTask.children[i], taskCompleted);
}
for (var i = 0; i < completedTask.children.length; i++) {
bindTaskEvents(completedTask.children[i], taskIncomplete);
}
var input = document.getElementById("new-number");
input.addEventListener("keypress", function (event) {
if (event.key === "Enter") {
addTask();
}
});
.container {
height: 525px;
width: 450px;
margin: 100px auto;
}
ul {
margin: 0;
padding: 0;
}
li * {
float: left;
}
li,
h3 {
clear: both;
list-style: none;
font-family: Arial, Helvetica, sans-serif;
}
input,button {
outline: none;
}
button {
background: none;
border: 0px;
color: #888;
font-size: 15px;
width: 60px;
margin: 10px 0 0;
font-family: Lato, sans-serif;
cursor: pointer;
}
button:hover {
color: #333;
}
h3, label[for='new-task'] {
color: #333;
font-weight: 700;
font-size: 15px;
border-bottom: 2px solid #333;
padding: 30px 0 10px;
margin: 0;
text-transform: uppercase;
}
input[type="text"] {
margin: 0;
font-size: 18px;
line-height: 18px;
height: 18px;
padding: 10px;
border: 1px solid #ddd;
background: #fff;
border-radius: 8px;
font-family: Lato, sans-serif;
color: #888;
margin-left: 50px;
}
input[type="text"]:focus {
color: #333;
}
label[for='new-task'] {
display: block;
margin: 0 0 20px;
}
input#new-task,#new-name,#new-number {
width: 260px;
margin-bottom: 10px;
}
input:focus{
outline: none;
box-shadow: 0px 0px 5px #61C5FA;
border-color: #5AB0DB;
}
input:hover {
border: 1px solid #999;
border-radius: 5px;
}
p>button:hover {
color: #0FC57C;
}
li {
overflow: hidden;
padding: 20px 0;
border-bottom: 1px solid #eee;
}
li>input[type="checkbox"] {
margin: 0 10px;
position: relative;
top: 15px;
}
li>label {
font-size: 18px;
line-height: 40px;
width: 190px;
padding: 0 0 0 11px;
}
li>input[type="text"] {
width: 180px;
}
#completed-tasks label {
text-decoration: line-through;
color: #888;
}
ul li input[type=text] {
display: none;
}
ul li.editMode input[type=text] {
display: block;
}
ul li.editMode label {
display: none;
}
th{
padding-right: 70px;
}
<!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">
<link rel="stylesheet" href="style.css" type="text/css">
<title>To DO List</title>
</head>
<body style="background-color: #ebeff0">
<div class="container">
<h3 style="text-align: center;">Add Task</h3>
<br>
<label>Add Task</label>
<input id="new-task" type="text" required><br>
<label>Name</label>
<input id="new-name" type="text" required><br>
<label>Phone Number</label>
<input id="new-number" type="text" required><br>
<h3 style="text-align: center;">Todo</h3>
<ul id="incomplete-tasks">
</ul>
<h3 style="text-align: center;">Completed Tasks</h3>
<ul id="completed-tasks">
</ul>
</div>
</body>
<script type="text/javascript" src="main.js"></script>
</html>
I have created the class and then edited the inputs
var taskInput = document.getElementById("new-task");
var nameInput = document.getElementById("new-name");
var numberInput = document.getElementById("new-number");
var addButton = document.getElementsByTagName("button")[0];
var incompleteTask = document.getElementById("incomplete-tasks");
var completedTask = document.getElementById("completed-tasks");
var createNewTaskElement = function (taskString, nameString, numberString) {
var listItem = document.createElement("li");
var checkBox = document.createElement("input");
var label = document.createElement("label");
var label1 = document.createElement("label");
var label2 = document.createElement("label");
var editInput = document.createElement("input");
var editInput1 = document.createElement("input");
var editInput2 = document.createElement("input");
var editButton = document.createElement("button");
var deleteButton = document.createElement("button");
label.innerText = taskString;
label1.innerText = nameString;
label2.innerText = numberString;
label.className = "task";
label1.className = "name";
label2.className = "number";
checkBox.type = "checkbox";
editInput.type = "text";
editInput1.type = "text";
editInput2.type = "text";
editInput.className = "edit";
editInput1.className = "edit1";
editInput2.className = "edit2";
editButton.innerText = "Edit";
editButton.className = "edit";
deleteButton.innerText = "Delete";
deleteButton.className = "delete";
listItem.appendChild(checkBox);
listItem.appendChild(label);
listItem.appendChild(editInput);
listItem.appendChild(label1);
listItem.appendChild(editInput1);
listItem.appendChild(label2);
listItem.appendChild(editInput2);
listItem.appendChild(editButton);
listItem.appendChild(deleteButton);
alert("You added '" + label.innerText + "' to the ToDO list");
return listItem;
}
var addTask = function () {
var listItem = createNewTaskElement(taskInput.value, nameInput.value, numberInput.value);
if (taskInput.value == "") {
alert("You must enter a task");
} else if (nameInput.value == "") {
alert("You must enter a Name");
} else if (numberInput.value == "") {
alert("You must enter a Phone Number");
} else {
incompleteTask.appendChild(listItem);
}
bindTaskEvents(listItem, taskCompleted);
taskInput.value = "";
nameInput.value = "";
numberInput.value = "";
}
var editTask = function () {
var listItem = this.parentNode;
var editInput = listItem.querySelector('.edit');
var editInput1 = listItem.querySelector('.edit1');
var editInput2 = listItem.querySelector('.edit2');
var label = listItem.querySelector(".task");
var label1 = listItem.querySelector(".name");
var label2 = listItem.querySelector(".number");
var containsClass = listItem.classList.contains("editMode");
if (containsClass) {
label.innerText = editInput.value;
label1.innerText = editInput1.value;
label2.innerText = editInput2.value;
alert("You edited " + label.innerText);
} else {
editInput.value = label.innerText;
editInput1.value = label1.innerText;
editInput2.value = label2.innerText;
}
listItem.classList.toggle("editMode");
}
var deleteTask = function () {
if (confirm("Are you sure you want to delete this task?") == true) {
var listItem = this.parentNode;
var ul = listItem.parentNode;
alert("You deleted " + listItem.querySelector("label").innerText);
} else {
alert("You cancelled the task");
}
ul.removeChild(listItem);
}
var taskCompleted = function () {
var listItem = this.parentNode;
if (confirm("Are you sure you want to mark this task as complete?") == true) {
completedTask.appendChild(listItem);
bindTaskEvents(listItem, taskIncomplete);
alert("You completed " + listItem.querySelector("label").innerText);
} else {
alert("You cancelled the task");
}
}
var taskIncomplete = function () {
var listItem = this.parentNode;
incompleteTask.appendChild(listItem);
bindTaskEvents(listItem, taskCompleted);
}
var bindTaskEvents = function (taskListItem, checkBoxEventHandler) {
var checkBox = taskListItem.querySelector("input[type=checkbox]");
var editButton = taskListItem.querySelector("button.edit");
var deleteButton = taskListItem.querySelector("button.delete");
editButton.onclick = editTask;
deleteButton.onclick = deleteTask;
checkBox.onchange = checkBoxEventHandler;
}
for (var i = 0; i < incompleteTask.children.length; i++) {
bindTaskEvents(incompleteTask.children[i], taskCompleted);
}
for (var i = 0; i < completedTask.children.length; i++) {
bindTaskEvents(completedTask.children[i], taskIncomplete);
}
var input = document.getElementById("new-number");
.container {
height: 525px;
width: 700px;
margin: 100px auto;
}
ul {
margin: 0;
padding: 0;
}
li * {
float: left;
}
li,
h3 {
clear: both;
list-style: none;
font-family: Arial, Helvetica, sans-serif;
}
input,button {
outline: none;
}
button {
background: none;
border: 0px;
color: #888;
font-size: 15px;
width: 60px;
margin: 10px 0 0;
font-family: Lato, sans-serif;
cursor: pointer;
}
button:hover {
color: #333;
}
h3, label[for='new-task'] {
color: #333;
font-weight: 700;
font-size: 15px;
border-bottom: 2px solid #333;
padding: 30px 0 10px;
margin: 0;
text-transform: uppercase;
}
input[type="text"] {
margin: 0;
font-size: 18px;
line-height: 18px;
height: 18px;
padding: 10px;
border: 1px solid #ddd;
background: #fff;
border-radius: 8px;
font-family: Lato, sans-serif;
color: #888;
margin-left: 50px;
}
input[type="text"]:focus {
color: #333;
}
label[for='new-task'] {
display: block;
margin: 0 0 20px;
}
input#new-task,#new-name,#new-number {
width: 260px;
margin-bottom: 10px;
}
input:focus{
outline: none;
box-shadow: 0px 0px 5px #61C5FA;
border-color: #5AB0DB;
}
input:hover {
border: 1px solid #999;
border-radius: 5px;
}
p>button:hover {
color: #0FC57C;
}
li {
overflow: hidden;
padding: 20px 0;
border-bottom: 1px solid #eee;
}
li>input[type="checkbox"] {
margin: 0 10px;
position: relative;
top: 15px;
}
li>label {
font-size: 18px;
line-height: 40px;
width: 100px;
padding: 0 0 0 11px;
}
li>input[type="text"] {
width: 100px;
}
li>button{
padding-left: 3px;
}
li>button:hover{
border: 1px solid black;
color: #c54f0f;
}
#completed-tasks label {
text-decoration: line-through;
color: #888;
}
ul li input[type=text] {
display: none;
}
ul li.editMode input[type=text] {
display: block;
}
ul li.editMode label {
display: none;
}
#AddBtn{
align-items: center;
border: 1px solid black !important;
background-color: white;
}
<!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">
<link rel="stylesheet" href="style.css" type="text/css">
<title>To DO List</title>
</head>
<body style="background-color: #ebeff0">
<div class="container">
<h3 style="text-align: center;">Add Task</h3>
<br>
<label>Add Task</label>
<input id="new-task" type="text" required><br>
<label style="padding-right: 05px;">Name</label>
<input id="new-name" type="text" required><br>
<label>Phone Number</label>
<input id="new-number" type="text" required><br>
<button id="AddBtn" onclick="addTask()">Add</button>
<h3 style="text-align: center;">Todo</h3>
<ul id="incomplete-tasks">
</ul>
<h3 style="text-align: center;">Completed Tasks</h3>
<ul id="completed-tasks">
</ul>
</div>
</body>
<script type="text/javascript" src="main.js"></script>
</html>
I created a to-do list so when you add something into the textbox and click the add button it adds it into the list which is shown below it. However, I want to quickly add a bunch of things and not tediously use my mouse to click the add button every time, that's why I have been trying to add in the function for when I press enter it will be added. But everything I've tried hasn't been working and yes I've read through and attempted to use code from other questions on stackoverflow which is why I've finally decided to ask this question.
Please help! [the end of the JavaScript part of the snippet is my most recent attempt]
// 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() {
var div = this.parentElement;
div.style.display = "none";
}
}
// 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";
}
}
window.addEventListener('keyup', function (e) {
if (e.keyCode === 13) {
var button = document.getElementById("myInput");
button.click();
}
}, false);
}
body {
background-color: #81B9E3;
font-family: 'Handlee', cursive;
}
h1 {
color: #2F90DA;
font-size: xxx-large;
font-family: 'Concert One', cursive;
}
a {
text-decoration: none;
color: #2F90DA;
}
p{
color: black;
}
body {
margin: 0;
min-width: 250px;
}
/* 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;
background: #7DB9FF;
font-size: 18px;
transition: 0.2s;
/* make the list items unselectable */
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
/* Set all odd list items to a different color (zebra-stripes) */
ul li:nth-child(odd) {
background: #93C5FF;
}
/* Darker background-color on hover */
ul li:hover {
background: #51CA4C;
}
/* When clicked on, add a background color and strike out text */
ul li.checked {
background: #9DF599;
color: #51CA4C;
text-decoration: line-through;
}
/* Add a "checked" mark when clicked on */
ul li.checked::before {
content: '';
position: absolute;
border-color: #51CA4C;
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: #2F90DA;
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;
}
/* Style the "Add" button */
.addBtn {
padding: 8.5px;
width: 25%;
background: #81B9E3;
color: #fff;
float: left;
text-align: center;
font-size: 16px;
cursor: pointer;
transition: 0.3s;
border-radius: 0;
}
.addBtn:hover {
background-color: #51CA4C;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>To Do List</title>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Actor&family=Luckiest+Guy&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Concert+One&family=Handlee&family=Actor&display=swap" rel="stylesheet">
<link href="todo.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div style="background-color: #DCEEF5; padding: 20px; text-align: center;">
<h1> 📖 To Do List 📖</h1>
<h2 style="margin-top: 0; margin-left: 20%; margin-right: 20%">Make your own to do list!</h2>
<h3>Type your task and click "Add". Once your task is completed, just click on the task to cross it off. Press the x button on the far right of a task to remove it.</h3>
<h4 style="margin-bottom: 3%;">Go back to Productify Home or Navigation</h4>
</div><br/>
</body>
<style>
</style>
</head>
<body>
<div id="myDIV" class="header">
<h2 style="margin:5px">📖 My To Do List 📖</h2>
<input type="text" id="myInput" placeholder="New Task...">
<span onclick="newElement()" class="addBtn">Add</span>
</div>
<ul id="myUL"></ul>
<script src="todo.js"></script>
</body>
</html>
You can probably get away with using the same handler for both the button and the input using a closure.
// Cache your elements
const input = document.querySelector('input');
const list = document.querySelector('div');
const button = document.querySelector('button');
// Pass in the input and list elements to the handler
// The handler returns a new function that will be used
// for both the button and input listeners
const handler = handleInput(input, list);
button.addEventListener('click', handler, false);
input.addEventListener('keyup', handler, false);
function handleInput(input, list) {
// Initialise the text in the input
let text = '';
// Add the text to the page, reset `text`,
// and reset the input value
function printLine(text) {
list.innerHTML += `<div>${text}</div>`;
text = '';
input.value = '';
}
// This is the listener
return function(e) {
const { code, target: { value, type } } = e;
// If the button is clicked call `printLine`
if (type === 'submit') printLine(text);
// If the input has changed
// If return has been pressed call printLine
// otherwise update the text value
if (type === 'text') {
if (code === 'Enter') {
printLine(text);
} else {
text = value;
}
}
}
}
<input />
<button>Add to list</button>
<div></div>
After appending </input> element to the list item , and appending a child element to it, the browser generates a invalid </input> tag. How can I prevent this from happening? In the element inspector the created elements are there, but I can't see them or select their content.
I've put the entire code here:
https://codepen.io/elenderg/pen/eYYJxqg
var Matricula = "<strong>PAM5913</strong><br>";
var Velocidade = "N0250";
var Origem ="SBHT ";
var Destino = "<strong>SBBE</strong><br>";
var Hora = "<strong>1600</strong>"
var Tipo = "E195M"
var Transponder = "6721";
var NÃvel = "F370";
var Rota = "DCT";
function CriaStrip(){
var Ul = document.getElementById('ul');
var Li = document.createElement('li');
Li.setAttribute("class", "cinza li");
var Input = document.createElement('input');
Input.setAttribute('name', 'painel');
Input.setAttribute("type","radio");
Input.setAttribute("id","input1");
var Label = document.createElement('label')
Label.htmlFor = 'input1';
var Div1 = document.createElement('div');
Div1.setAttribute("class", "lado-a-lado");
Div1.innerHTML = Matricula + Origem + Destino + Hora + Tipo;
var Div2 = document.createElement('div');
Div2.setAttribute("class", "dados");
Div2.innerHTML = Transponder + NÃvel + Rota + "<br><br>" + Velocidade;
Ul.appendChild(Li);
Li.appendChild(Input);
Input.appendChild(Label);
Label.appendChild(Div1);
Div1.appendChild(Div2);
}
.painel{
border: 4px solid rgb(0,0,255) ;
width: 50%;
background-color: black;
}
.cinza{
background-color: gray;
border-bottom: 1px solid silver;;
}
.ul{
margin:0px;
padding: 0px;
list-style: none;
}
.li{
border: 1px solid #ccc;
box-sizing: border-box;
position: relative;
height: 70px;
}
.li label{
bottom: 1px;
left: 1px;
right: 1px;
top: 1px;
display: block;
position: absolute;
}
input[type="radio"]{
display: none;
}
.lado-a-lado{
display: -webkit-box;
}
.dados{
padding-left: 3px;
}
.ul input:checked + label {
border-right: 8px solid white;
}
<div class="painel" onclick="CriaStrip()">
<ul class="ul" id="ul">
<li class="cinza li" id="li">
Click to create new items
</li>
</ul>
</div>
I just had to change how you're appending the label. You should append it to Li instead of Input
Ul.appendChild(Li);
Li.appendChild(Input);
Li.appendChild(Label); // From Input to Li
Label.appendChild(Div1);
Div1.appendChild(Div2);
I have to do some kind of ToDo list, where I have input and button to Add item to ul list. And now I done everything except compare every li item with input value. My question is how to compare every li content with value input to prevent duplicate items. Here is the code https://jsfiddle.net/qoLtxfaw/1/
// Variables
var ul = document.getElementById("taskList");
var task = document.getElementById("task");
var btn = document.querySelector('button');
var listItem = document.getElementsByTagName("LI");
// Append close btn to each list item
for (var i = 0; i < listItem.length; i++) {
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "js-close";
span.appendChild(txt);
listItem[i].appendChild(span);
}
// Click on a close button to hide the current list item
var close = document.getElementsByClassName("js-close");
for (var i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.className = 'js-hide';
}
}
// proveravati ima li ul odnosno liste, ukoliko ne proverimo a nema ceo kod ce prestati da se izvrsava
if (ul) {
ul.onmouseover = function(event) {
var target = event.target;
target.style.background = '#efebeb';
};
ul.onmouseout = function(event) {
var target = event.target;
target.style.background = '';
};
}
// Add item to list on btn
btn.addEventListener('click', addItem);
// Add item to list on enter
task.onkeyup = function(e) {
if (e.keyCode == 13) {
addItem();
}
};
// // Add item to list
function addItem() {
var li = document.createElement("li");
var inputValue = document.getElementById('task').value;
li.setAttribute('id', task.value);
li.appendChild(document.createTextNode(task.value));
// ul.appendChild(li);
// compare every li item with inputValue
if (inputValue) { //if input value is true and has some value
//go trough all li items
for (var i = 0; i < listItem.length; i++) {
// compare every li item with inputValue
}
// Duplicate values don't allow in list
if (!inputValue) {
alert("No empty values are allowed!");
li.className = 'js-btn-disable';
} else {
ul.appendChild(li);
}
document.getElementById("task").value = "";
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "js-close";
span.appendChild(txt);
li.appendChild(span);
for (var i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.className = 'js-hide';
}
}
}
}
#wrapper {
width: 500px;
margin: 0 auto;
background: #00bcd4;
border: 1px solid #f1f0f0;
padding-left: 10px;
font-size: 1.2em;
}
#wrapper #task {
background: transparent;
color: #ffffff;
font-size: 1.2em;
width: 80%;
height: 35px;
border: none;
border-bottom: 2px solid #ffffff;
outline: none;
margin: 15px 0 5px 0;
}
#wrapper #task ::-webkit-input-placeholder {
/* Chrome/Opera/Safari */
color: #ffffff;
}
#wrapper #task ::-moz-placeholder {
/* Firefox 19+ */
color: #ffffff;
}
#wrapper #task :-ms-input-placeholder {
/* IE 10+ */
color: #ffffff;
}
#wrapper #task :-moz-placeholder {
/* Firefox 18- */
color: #ffffff;
}
#wrapper button {
font-size: 1.2em;
border: 2px solid #ffffff;
background: transparent;
color: #ffffff;
padding: 5px 10px;
outline: none;
cursor: pointer;
}
#wrapper ul#taskList {
padding: 0;
background: #ffffff;
list-style-type: none;
text-align: left;
margin-bottom: 0;
margin-left: -10px;
}
#wrapper ul#taskList li {
padding: 10px;
position: relative;
cursor: pointer;
}
/* Style the close button */
.js-close {
position: absolute;
right: 0;
top: 0;
padding: 10px;
}
.js-close:hover {
color: #ffffff;
}
.js-hide {
display: none;
}
.js-background {
background: #efebeb;
}
.js-btn-disable {
opacity: 0.65;
cursor: not-allowed;
}
/*# sourceMappingURL=style.css.map */
<div id="wrapper">
<input type="text" id="task" />
<button>Add</button>
<ul id="taskList"></ul>
</div>
Have a look at this. I use firstChild and I moved the validation to the top of the function.
I use the inputValue after validating it but task everywhere else.
DRY - Don't Repeat Yourself
// Variables
var ul = document.getElementById("taskList");
var task = document.getElementById("task");
var btn = document.querySelector('button');
var listItem = document.getElementsByTagName("LI");
task.focus();
// Append close btn to each list item
for (var i = 0; i < listItem.length; i++) {
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "js-close";
span.appendChild(txt);
listItem[i].appendChild(span);
}
// Click on a close button to hide the current list item
var close = document.getElementsByClassName("js-close");
for (var i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.className = 'js-hide';
}
}
// proveravati ima li ul odnosno liste, ukoliko ne proverimo a nema ceo kod ce prestati da se izvrsava
if (ul) {
ul.onmouseover = function(event) {
var target = event.target;
target.style.background = '#efebeb';
};
ul.onmouseout = function(event) {
var target = event.target;
target.style.background = '';
};
}
// Add item to list on btn
btn.addEventListener('click', addItem);
// Add item to list on enter
task.onkeyup = function(e) {
if (e.keyCode == 13) {
addItem();
}
};
// // Add item to list
function addItem() {
var inputValue = task.value.trim();
task.value = "";
task.focus();
// Empty or Duplicate values don't allow in list
if (!inputValue) {
alert("No empty values are allowed!");
return
}
var listItem = document.querySelectorAll("#taskList li");
for (var i = 0; i < listItem.length; i++) {
if (inputValue == listItem[i].firstChild.textContent) {
alert("No duplicate values are allowed!");
return
}
}
var li = document.createElement("li");
li.setAttribute('id', inputValue);
li.appendChild(document.createTextNode(inputValue));
ul.appendChild(li);
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "js-close";
span.appendChild(txt);
li.appendChild(span);
for (var i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.className = 'js-hide';
}
}
}
#wrapper {
width: 500px;
margin: 0 auto;
background: #00bcd4;
border: 1px solid #f1f0f0;
padding-left: 10px;
font-size: 1.2em;
}
#wrapper #task {
background: transparent;
color: #ffffff;
font-size: 1.2em;
width: 80%;
height: 35px;
border: none;
border-bottom: 2px solid #ffffff;
outline: none;
margin: 15px 0 5px 0;
}
#wrapper #task ::-webkit-input-placeholder {
/* Chrome/Opera/Safari */
color: #ffffff;
}
#wrapper #task ::-moz-placeholder {
/* Firefox 19+ */
color: #ffffff;
}
#wrapper #task :-ms-input-placeholder {
/* IE 10+ */
color: #ffffff;
}
#wrapper #task :-moz-placeholder {
/* Firefox 18- */
color: #ffffff;
}
#wrapper button {
font-size: 1.2em;
border: 2px solid #ffffff;
background: transparent;
color: #ffffff;
padding: 5px 10px;
outline: none;
cursor: pointer;
}
#wrapper ul#taskList {
padding: 0;
background: #ffffff;
list-style-type: none;
text-align: left;
margin-bottom: 0;
margin-left: -10px;
}
#wrapper ul#taskList li {
padding: 10px;
position: relative;
cursor: pointer;
}
/* Style the close button */
.js-close {
position: absolute;
right: 0;
top: 0;
padding: 10px;
}
.js-close:hover {
color: #ffffff;
}
.js-hide {
display: none;
}
.js-background {
background: #efebeb;
}
.js-btn-disable {
opacity: 0.65;
cursor: not-allowed;
}
/*# sourceMappingURL=style.css.map */
<div id="wrapper">
<input type="text" id="task" />
<button>Add</button>
<ul id="taskList"></ul>
</div>