I am trying to create a To Do list and am having troubles strikingthrough a created To Do item. A "Click if Completed" button appears on the right side of the created to-do item which, when clicked, should strikeout the text. I am pretty sure it is an issue with the (e.target.newToDo.innerText.strike())
Do I need to create a variable for the newToDo.innerText? Am I still able to create one since I have created (newToDo.innerText = input.value) in the function earlier?
Just want to say that the people on this website are amazing and have helped a ton. Thank you in advance!
const form = document.querySelector('#addToDo');
const input = document.querySelector('#theToDo');
const todolist = document.querySelector('#todolist');
form.addEventListener('submit',function(e){
e.preventDefault();
const newToDo = document.createElement('li');
const removeBtn = document.createElement('button');
const completeBtn = document.createElement('button');
newToDo.innerText = input.value;
removeBtn.innerText = 'Click to Remove';
completeBtn.innerText = 'Click if Completed';
newToDo.appendChild(completeBtn);
newToDo.appendChild(removeBtn);
input.value = '';
todolist.appendChild(newToDo);
completeBtn.addEventListener("click", function(e){
e.target.newToDo.innerText.strike();
})
removeBtn.addEventListener("click", function(e){
e.target.parentElement.remove();
})
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>To Do List:</h1>
<ul id="todolist">
</ul>
<form action="" id="addToDo" name="addToDo">
<input type="text" id="theToDo"
name="addToDo"
placeholder="Add to the list here">
<button type="submit">Submit</button>
</form>
<script src=Test.js></script>
</body>
</html>
Why wasn't your code working
Your code wasn't working because of e.target.newToDo.innerText.strike() this does not target the li (parent element) and you need to set the innerText to the striked innerText or it will not show.
Why you should not use strike()
It is not good practice to edit styles within JS and the <strike> tag is not supported in HTML5.
Instead, create a CSS class like this:
.strike {
text-decoration: line-through;
}
Then append the .strike class to the HTML element.
Solution
const form = document.querySelector('#addToDo');
const input = document.querySelector('#theToDo');
const todolist = document.querySelector('#todolist');
form.addEventListener('submit',function(e){
e.preventDefault()
todolist.innerHTML += `<li>
<span>${input.value}</span>
<button onclick="strikeItem(this)">strike</button>
<button onclick="removeItem(this)">remove</button>
</li>`
})
function strikeItem(ele) {
const itemTextEle = ele.parentElement.querySelector('span')
itemTextEle.innerHTML = itemTextEle.innerText.strike()
}
function removeItem(ele) {
ele.parentElement.remove()
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>To Do List:</h1>
<ul id="todolist">
</ul>
<form action="" id="addToDo" name="addToDo">
<input type="text" id="theToDo"
name="addToDo"
placeholder="Add to the list here">
<button type="submit">Submit</button>
</form>
<script src=Test.js></script>
</body>
</html>
This is a bit easier to read and is less code to write.
This solution uses the strike() function to show you how to use it I would try appending a class instead.
Append your newToDo to todolist and change the innerHtml on click function call:
const form = document.querySelector('#addToDo');
const input = document.querySelector('#theToDo');
const todolist = document.querySelector('#todolist');
form.addEventListener('submit', function(e) {
e.preventDefault();
const newToDo = document.createElement('li');
const removeBtn = document.createElement('button');
const completeBtn = document.createElement('button');
newToDo.id = 'new_todo';
newToDo.innerText = input.value;
removeBtn.innerText = 'Click to Remove';
completeBtn.innerText = 'Click if Completed';
todolist.append(newToDo);
todolist.appendChild(completeBtn);
todolist.appendChild(removeBtn);
input.value = '';
completeBtn.addEventListener("click", function(e) {
var todo = document.querySelector('#new_todo');
var todoText = '<del>' + todo.innerText + '</del>';
todo.innerHTML = todoText;
})
removeBtn.addEventListener("click", function(e) {
e.target.parentElement.remove();
})
})
see the working fiddle here: https://jsfiddle.net/khushboo097/uak3f5s2/20/
const form = document.querySelector('#addToDo');
const input = document.querySelector('#theToDo');
const todolist = document.querySelector('#todolist');
form.addEventListener('submit',function(e){
e.preventDefault();
const newToDo = document.createElement('li');
const removeBtn = document.createElement('button');
const completeBtn = document.createElement('button');
newToDo.innerText = input.value;
removeBtn.innerText = 'Click to Remove';
completeBtn.innerText = 'Click if Completed';
newToDo.appendChild(completeBtn);
newToDo.appendChild(removeBtn);
input.value = '';
todolist.appendChild(newToDo);
completeBtn.addEventListener("click", function(e){
e.target.parentElement.style.textDecoration="line-through";
})
removeBtn.addEventListener("click", function(e){
e.target.parentElement.remove();
})
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>To Do List:</h1>
<ul id="todolist">
</ul>
<form action="" id="addToDo" name="addToDo">
<input type="text" id="theToDo"
name="addToDo"
placeholder="Add to the list here">
<button type="submit">Submit</button>
</form>
<script src=Test.js></script>
</body>
</html>
Do it like this:
const form = document.querySelector('#addToDo');
const input = document.querySelector('#theToDo');
const todolist = document.querySelector('#todolist');
form.addEventListener('submit', function(e) {
e.preventDefault();
const newToDo = document.createElement('li');
const newToDoName = document.createElement('span');
const removeBtn = document.createElement('button');
const completeBtn = document.createElement('button');
newToDoName.innerText = input.value;
removeBtn.innerText = 'Click to Remove';
completeBtn.innerText = 'Click if Completed';
newToDo.appendChild(newToDoName);
newToDo.appendChild(completeBtn);
newToDo.appendChild(removeBtn);
input.value = '';
todolist.appendChild(newToDo);
completeBtn.addEventListener("click", function(e) {
newToDo.innerHTML = newToDoName.innerText.strike();
})
removeBtn.addEventListener("click", function(e) {
e.target.parentElement.remove();
})
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1>To Do List:</h1>
<ul id="todolist">
</ul>
<form action="" id="addToDo" name="addToDo">
<input type="text" id="theToDo" name="addToDo" placeholder="Add to the list here">
<button type="submit">Submit</button>
</form>
<script src=Test.js></script>
</body>
</html>
Related
I have the following function to determine the status of whether a book was read or not in my project each time a new book is added to the library. The issue I am running into is that every time I add a new book, all the books "Status" are updated to the status of the new book.
PROBLEM CODE
const titleInput = document.querySelector('#title');
const authorInput = document.querySelector('#author');
const pagesInput = document.querySelector('#pages');
const genreInput = document.querySelector('#genre');
let readInput;
function readStatus() {
const readRadioBtn = document.querySelector('input[name="read"]');
if (readRadioBtn.checked) {
return 'read';
}
return 'unread';
}
// function to add book to myLibrary array//
function addBook() {
const newBook = new Book(
titleInput.value,
authorInput.value,
pagesInput.value,
genreInput.value,
readInput = readStatus()
);
myLibrary.push(newBook);
}
I have tried to declare the readInput variable inside addBook() before newBook, but then a new book card does not get added at all. The form gets reset upon submission as well. I am attaching my full HTML and JavaScript code below for more clarity on what I am trying to get done. I apologize if it is unorganized as I am still new to coding. I also really appreciate any advice and tips on how I can structure and write my code better.
CODE
// OPENING AND CLOSING MODAL//
const addBookBtn = document.querySelector('.add');
const closeModalBtn = document.querySelector('.close-btn');
const overlay = document.querySelector('.overlay');
const modal = document.querySelector('.modal');
function openModal() {
modal.classList.add('active');
overlay.classList.add('active');
}
function closeModal() {
modal.classList.remove('active');
overlay.classList.remove('active');
}
addBookBtn.addEventListener('click', () => {
openModal();
});
closeModalBtn.addEventListener('click', () => {
closeModal();
});
// CREATING NEW BOOK CARDS//
const myLibrary = [];
// constructor function//
function Book(title, author, pages, genre, read) {
(this.title = title),
(this.author = author),
(this.pages = pages),
(this.genre = genre),
(this.read = read);
}
// need to fix//
function readStatus() {
if (document.querySelector('input[name="read"]').value === 'yes') {
return 'read';
}
if (document.querySelector('input[name="read"]').value === 'no') {
return 'unread';
}
}
const titleInput = document.querySelector('#title');
const authorInput = document.querySelector('#author');
const pagesInput = document.querySelector('#pages');
const genreInput = document.querySelector('#genre');
let readInput;
// function to add book to myLibrary array//
function addBook() {
readInput = readStatus();
const newBook = new Book(
titleInput.value,
authorInput.value,
pagesInput.value,
genreInput.value,
readInput
);
myLibrary.push(newBook);
}
// creates new book card elements in DOM//
function createNewCard(book) {
const cardContainer = document.querySelector('.card-cont');
const cards = document.createElement('div');
cards.classList.add('book-card');
const title = document.createElement('p');
title.innerText = book.title;
cards.appendChild(title);
const author = document.createElement('p');
author.innerText = book.author;
cards.appendChild(author);
const pages = document.createElement('p');
pages.innerText = `${book.pages} pages`;
cards.appendChild(pages);
const genre = document.createElement('p');
genre.innerText = book.genre;
cards.appendChild(genre);
const statusContainer = document.createElement('div');
statusContainer.setAttribute('class', 'read-status');
const statusLabel = document.createElement('p');
statusLabel.innerText = 'Status:';
statusContainer.appendChild(statusLabel);
const statusButton = document.createElement('button');
statusButton.setAttribute('class', 'read-unread');
if (readInput === 'read') {
statusButton.innerText = 'Read';
statusButton.classList.add('isRead');
} else {
statusButton.innerText = 'Unread';
statusButton.classList.add('notRead');
}
statusContainer.appendChild(statusButton);
cards.appendChild(statusContainer);
const removeBtn = document.createElement('button');
removeBtn.classList.add('remove');
removeBtn.innerText = 'Remove';
cards.appendChild(removeBtn);
cardContainer.appendChild(cards);
}
function publishCards() {
const cardContainer = document.querySelector('.card-cont');
const cards = document.querySelectorAll('.book-card');
cards.forEach((card) => cardContainer.removeChild(card));
for (let i = 0; i < myLibrary.length; i++) {
createNewCard(myLibrary[i]);
}
}
const bookForm = document.querySelector('.book-form');
bookForm.addEventListener('submit', (e) => {
e.preventDefault();
closeModal();
addBook();
publishCards();
bookForm.reset();
});
function changeReadStatus() {
if (statusButton.classList.contains('isRead')) {
statusButton.classList.remove('isRead');
statusButton.classList.add('notRead');
statusButton.innerText = 'Unread'
} else {
statusButton.classList.remove('notRead');
statusButton.classList.add('isRead');
statusButton.innerText = 'Read'
}
}
const statusButton = document.querySelector('.read-unread');
statusButton.addEventListener('click', () => {
changeReadStatus();
});
console.log(myLibrary);
<!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="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght#0,300;0,400;0,500;0,600;0,700;0,800;1,300;1,400;1,500;1,600;1,700;1,800&family=Poppins:ital,wght#0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Roboto:ital,wght#0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap"
rel="stylesheet">
<link rel="stylesheet" href="font-awesome-css/fontawesome.css">
<link rel="stylesheet" href="styles.css">
<title>Library Project</title>
</head>
<body>
<header>
<div class="logo">
<i class="fa-solid fa-book"></i>
<h1 class="title"> your libary</h1>
</div>
<button class="sign-in">sign in</button>
</header>
<div class="main">
<button class="add">+ Add Book</button>
<div class="card-cont">
<div class="book-card">
<p>The Cat in the Hat</p>
<p>Dr. Seuss</p>
<p>61 pages</p>
<p>Children's Literature</p>
<div class="read-status">
<p>Status:</p>
<button class="read-unread isRead">Read</button>
</div>
<button class="remove">Remove</button>
</div>
</div>
</div>
<div class="modal">
<form action="#" method="post" class="book-form">
<div class="close-btn-cont">
<button class="close-btn">Ă—</button>
</div>
<h2>What Are You Reading?</h2>
<input type="text" id="title" name="title" placeholder="Title" required>
<input type="text" id="author" name="author" placeholder="Author" required>
<input type="text" id="pages" name="pages" placeholder="# of Pages" pattern="\d+" required>
<input type="text" id="genre" name="genre" placeholder="Genre" required>
<p class="read">Have you read this book?</p>
<div class="radio-cont">
<input type="radio" name="read" id="yes" value="yes" required>
<label for="yes">Yes</label>
<input type="radio" name="read" id="no" value="no" required>
<label for="no">No</label>
</div>
<input type="submit" id="submit" value="Submit">
</form>
</div>
<div class="overlay"></div>
<script src="https://kit.fontawesome.com/817495898e.js" crossorigin="anonymous"></script>
<script src="script.js"></script>
</body>
</html>
I created a list to add items to it, however, I'm also trying to add a delete button to remove any Item that's being added to my list, but I can't get it to work,
see snippet below
const form = document.querySelector("form");
const product = document.querySelector("#fruitName");
const quantity = document.querySelector("#qty");
const list = document.querySelector("#list");
form.addEventListener("submit", (e) => {
e.preventDefault();
const item = fruitName.value;
const numOfItmes = qty.value;
const newLi = document.createElement("li");
newLi.innerText = `${numOfItmes} ${item}`;
list.appendChild(newLi);
button.addEventListener("click", () => {
const button = document.createElement("button");
button.textContent = "X";
li.appendChild(button);
});
form.qty.value = "";
form.fruitName.value = "";
});
button {
width: 100px;
height: 100px;
margin: 20px;
}
#fruit {
width: auto;
height: auto;
}
<!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="color.css" />
<title>Document</title>
</head>
<body>
<h1>Welcome!</h1>
<form action="test">
<label for="item">Enter Product</label>
<input type="text" id="fruitName" />
<label for="item">Enter A Quantity</label>
<input type="number" id="qty" name="qty" />
<button id="fruit">Submit</button>
</form>
<ul id="list"></ul>
<script src="color.js"></script>
</body>
</html>
I created a list to add items to it, however, I'm also trying to add a delete button to remove any Item that's being added to my list, but I can't get it to work,
see my code below
const form = document.querySelector("form");
const product = document.querySelector("#fruitName");
const quantity = document.querySelector("#qty");
const list = document.querySelector("#list");
form.addEventListener("submit", (e) => {
e.preventDefault();
const item = fruitName.value;
const numOfItmes = qty.value;
const newLi = document.createElement("li");
newLi.innerText = `${numOfItmes} ${item}`;
list.appendChild(newLi);
button.addEventListener("click", () => {
const button = document.createElement("button");
button.textContent = "X";
li.appendChild(button);
});
form.qty.value = "";
form.fruitName.value = "";
});
<h1>Welcome!</h1>
<form action="test">
<label for="item">Enter Product</label>
<input type="text" id="fruitName" />
<label for="item">Enter A Quantity</label>
<input type="number" id="qty" name="qty" />
<button id="fruit">Submit</button>
</form>
<ul id="list"></ul>
can anyone help me with this?
You were creating the li's child button element in the wrong place, and you weren't removing the li at all when it was clicked. Here's the working code:
const form = document.querySelector("form");
const product = document.querySelector("#fruitName");
const quantity = document.querySelector("#qty");
const list = document.querySelector("#list");
form.addEventListener("submit", (e) => {
e.preventDefault();
const item = fruitName.value;
const numOfItmes = qty.value;
const newLi = document.createElement("li");
newLi.innerText = `${numOfItmes} ${item}`;
list.appendChild(newLi);
// create button outside of event listener
const button = document.createElement("button");
button.textContent = "X";
newLi.appendChild(button);
// remove the created li element when button is clicked
button.addEventListener("click", () => {
newLi.remove();
});
form.qty.value = "";
form.fruitName.value = "";
});
<h1>Welcome!</h1>
<form action="test">
<label for="item">Enter Product</label>
<input type="text" id="fruitName" />
<label for="item">Enter A Quantity</label>
<input type="number" id="qty" name="qty" />
<button id="fruit">Submit</button>
</form>
<ul id="list"></ul>
Was trying to make a ToDo list and everything was going well until every time I tried to fill out a form and it started giving me that syntax error that is mentioned in the title.
Here's my code:
//Random Alert
alert('Better get to it or moms going to be angry')
//Real work below
the window.addEventListener('load', () => {
const form = document.querySelector("#new-task-form");
const input = document.querySelector("#new-task-input");
const list_el = document.querySelector("#task-list");
form.addEventListener('submit', (e) => {
e.preventDefault();
const task = input.value;
if (!task) {
alert("Please add/fill out the task");
return;
}
const task_el = document.createElement("div");
task_el.classList.add("task");
const task_content_el = document.createElement("div");
task_content_el.classList.add("content");
task_content_el.innerText = task;
task_el.appendChild(task_content_el);
list_el.appendChild(task_el);
})
})
<body>
<header>
<h1>ToDo list 2022(version 1)</h1>
<form id="new-task-form">
<input type="text" id="new-task-input" placeholder="what's on your mind today?">
<input type="submit" id="new-task-submit" value="Add task">
</form>
</header>
<main>
<section class="task-list">
<h2>Tasks</h2>
</section>
</main>
</body>
Google keeps telling me to add a script src after every HTML element has been placed(I placed it above </body>) but it doesn't change anything. The output is meant to list out the input infinite times and when I do it nothing comes up but a console error.
If you want to use querySelector with #, the element needs to have and in attribute. Your section for tasks is missing this attribute, either add it or try to use .tasks-list in querySelector argument to select by class attribute.
//Random Alert
alert('Better get to it or moms going to be angry')
//Real work below
window.addEventListener('load', () => {
const form = document.querySelector("#new-task-form");
const input = document.querySelector("#new-task-input");
const list_el = document.querySelector("#task-list");
form.addEventListener('submit', (e) => {
e.preventDefault();
const task = input.value;
if (!task) {
alert("Please add/fill out the task");
return;
}
const task_el = document.createElement("div");
task_el.classList.add("task");
const task_content_el = document.createElement("div");
task_content_el.classList.add("content");
task_content_el.innerText = task;
task_el.appendChild(task_content_el);
list_el.appendChild(task_el);
})
})
<body>
<header>
<h1>ToDo list 2022(version 1)</h1>
<form id="new-task-form">
<input type="text" id="new-task-input" placeholder="what's on your mind today?">
<input type="submit" id="new-task-submit" value="Add task">
</form>
</header>
<main>
<section class="task-list" id="task-list">
<h2>Tasks</h2>
</section>
</main>
</body>
There is no need to add an onload event listener if the <script> tag is at the bottom of your <body> element.
Also, you used class="task-list" while you actually wanted to use id="task-list"
Please see the code below:
//Random Alert
alert('Better get to it or moms going to be angry')
//Real work below
const form = document.querySelector("#new-task-form");
const input = document.querySelector("#new-task-input");
const list_el = document.querySelector("#task-list");
form.addEventListener('submit', (event) => {
event.preventDefault();
const task = input.value;
if (!task) {
alert("Please add/fill out the task");
return;
}
const task_el = document.createElement("div");
task_el.classList.add("task");
const task_content_el = document.createElement("div");
task_content_el.classList.add("content");
task_content_el.innerText = task;
task_el.append(task_content_el);
list_el.append(task_el);
})
<body>
<header>
<h1>ToDo list 2022(version 1)</h1>
<form id="new-task-form">
<input type="text" id="new-task-input" placeholder="what's on your mind today?">
<input type="submit" id="new-task-submit" value="Add task">
</form>
</header>
<main>
<section id="task-list">
<h2>Tasks</h2>
</section>
</main>
<script src="app.js"></script>
</body>
this is my code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>CV Information</title>
<link rel="stylesheet" href="StyleSheet1.css" />
</head>
<body>
<header><b>CV Information</b></header>
<!--<script src="Script1.js"></script>-->
<div class="mydiv">
<form action="CV_Viewer.html">
<fieldset id="field">
<div class="scrollable" id="scroll">
<header>Languages</header><br />
<label for="mLan">Your Mothertoungue:</label>
<input type="text" id="mLan" placeholder="Primary Language.." name="name" pattern="[A-Za-z ]{3,}" required><br><br>
<input type="button" id="plus" onclick="addTextBox()" class="plus" value="+ other languages..." name="plus" />
</div>
<div style="position: static">
<input type="submit" onclick="webstorage()" class="hov" style="margin-top:30px" value="Next">
</div>
</fieldset>
</form>
</div>
<footer>
Copyright©2022 Rami Joulani
</footer>
<script>
let b = 1;
let q=0;
const array = [];
function addTextBox() {
b++;
const textBox = document.createElement("INPUT");
textBox.setAttribute("type", "text");
textBox.setAttribute("placeholder", "Any Other Language...");
textBox.setAttribute("pattern", "[A-Za-z ]{3,}");
textBox.setAttribute("style", "margin-top:35px;");
textBox.setAttribute("id",q);
const div = document.getElementById("scroll");
div.appendChild(textBox);
var plus = document.getElementById("plus");
div.insertBefore(textBox, plus);
array[q] = textBox.value;
console.log(array[q]);
q++;
return fieldSet();
}
function fieldSet() {
const radio1 = document.createElement("input");
radio1.setAttribute("type", "radio");
radio1.setAttribute("id", "rad1");
radio1.setAttribute("name", "connected");
const div = document.getElementById("scroll");
var plus = document.getElementById("plus");
div.appendChild(radio1);
div.insertBefore(radio1, plus);
const begg = document.createElement("label");
begg.setAttribute("for", "rad1");
const begginer = document.createTextNode("Begginer");
begg.appendChild(begginer);
div.appendChild(begg);
div.insertBefore(begg, plus);
const radio2 = document.createElement("input");
radio2.setAttribute("type", "radio");
radio2.setAttribute("id", "rad2");
radio2.setAttribute("name", "connected")
div.appendChild(radio2);
div.insertBefore(radio2, plus);
const inter = document.createElement("label");
inter.setAttribute("for", "rad2");
const intermadiate = document.createTextNode("Intermadiate");
inter.appendChild(intermadiate);
div.appendChild(inter);
div.insertBefore(inter, plus);
const radio3 = document.createElement("input");
radio3.setAttribute("type", "radio");
radio3.setAttribute("id", "rad3");
radio3.setAttribute("name", "connected")
div.appendChild(radio3);
div.insertBefore(radio3, plus);
const flu = document.createElement("label");
flu.setAttribute("for", "rad3");
const fluent = document.createTextNode("Fluent");
flu.appendChild(fluent);
div.appendChild(flu);
div.insertBefore(flu, plus);
plus.setAttribute("style", "margin-top:20px;")
if(b==4) {
plus.hidden=true;
}
}
function webstorage() {
localStorage.setItem("mothTong", document.getElementById("mLan").value);
}
</script>
</body>
</html>
I changed it multiple times when I tried to solve it
how can I save textBox value and the radio button values separately though they are created with the same attribute
it might be simple but I just couldn't figure it out.
Don't point out to some missing stuff but if you please tell me how is it possible to do it depending on the general form of the code.
I try to run the code it works for the first time but in the second time it won't work I don't know why ?
I want to make it in a way that I can send several messages over and over
var message = document.querySelector('.container');
var btn = document.getElementById('btn');
var inpt = document.getElementById('txt');
function AddMessage() {
if (String(inpt.value) != '' && isNaN(inpt.value) == true) {
message.innerHTML += `<p>${inpt.value} </p>`;
inpt.value = '';
}
}
input {
outline: none;
}
<div class="container">
<input type="text" value="" id="txt">
<button id="btn" onclick="AddMessage()">send</button>
<p>whats your name ?</p>
</div>
Issues with .innerHTML
You are assigning to .innerHTML. This causes recreation of the element's descendants (see innerHTML "On setting..."):
const oldReference = document.getElementById("element");
document.body.innerHTML += ""; // Assigning to innerHTML
const newReference = document.getElementById("element");
const isSameElement = oldReference === newReference;
console.log({ isSameElement });
<div id="element">
As you can see, the old references btn and inpt won't be the elements currently in the DOM.
Sidenote: Parsing .innerHTML may be quite time-consuming, and its use with user input is a security issue.
Security considerations
Especially with user input you shouldn't use .innerHTML, because that is an easy way to insert scripts into your webpage:
document.body.addEventListener("click", evt => {
if (!evt.target.closest("button")) return;
const input = document.querySelector("input");
document.body.innerHTML += input.value;
});
pre{padding:2px 4px;border:1px solid;width:min-content}
<input><button>Insert</button>
<p>Try to input this:</p>
<pre><code><img src=""
onerror="console.log('any script here!')"></code></pre>
<p>Then look into your browser console.
Alternatives for .innerHTML
If you want to add elements, you can use document.createElement(), Element.append(), and Node.textContent:
const input = document.querySelector("input");
document.querySelector("button").addEventListener("click", evt => {
const p = document.createElement("p");
p.textContent = input.value;
document.body.append(p);
input.value = "";
const currentInput = document.querySelector("input");
console.log("Is same input?", input === currentInput);
});
<input><button>Insert</button>
<p>Also try adding some HTML, for example: <code><span>Test</span>
Since your output element is the wrapper for all of the other elements, when you do this you are overwriting all of those elements:
message.innerHTML += `<p>${inpt.value} </p>`;
Visually (and perhaps even intuitively) this has no noticeable effect. But what it does is create entirely new elements which no longer correspond to your btn and inpt variables. Which leaves you interacting with stale objects that don't represent anything on the screen.
Probably the simplest approach would be to create a more specific output element. For example, add another <div> in your container and output to that:
var message = document.getElementById('message'); // reference new element
var btn = document.getElementById('btn');
var inpt = document.getElementById('txt');
function AddMessage() {
if (String(inpt.value) != '' && isNaN(inpt.value) == true) {
message.innerHTML += `<p>${inpt.value} </p>`;
inpt.value = '';
}
}
input {
outline: none;
}
<div class="container">
<input type="text" value="" id="txt">
<button id="btn" onclick="AddMessage()">send</button>
<p>whats your name ?</p>
<div id="message"></div> <!-- new element -->
</div>
This line message.innerHTML += ...
equals to message.innerHTML = message.innerHTML + ..., it assigns something new to message.innerHTML, in other words, it rewrites the content, thus references of btn and inpt are lost, the originals are overriden.
var message = document.querySelector('.container');
var btn = document.getElementById('btn');
var inpt = document.getElementById('txt');
var output = document.getElementById('output');
function AddMessage() {
console.log('addMessage')
if (String(inpt.value) != '' && isNaN(inpt.value) == true) {
output.innerText=inpt.value;
inpt.value = ''
}
}
input {
outline: none;
}
<div class="container">
<input type="text" value="" id="txt" placeholder="write your message here">
<button id="btn" onclick="AddMessage()">send</button>
<p>whats your name ?</p>
<p id="output"></p>
</div>
You can update only inner html for answer, not the full block with input
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<style>
input{
outline: none;
}
</style>
<div class="container">
<input type="text" value="" id="txt">
<button id="btn" onclick="AddMessage()">send</button>
<p>whats your name ?</p>
<p id="answer"></p>
</div>
<script>
var message = document.querySelector('.container');
var btn = document.getElementById('btn');
var inpt = document.getElementById('txt');
var answer = document.getElementById('answer');
function AddMessage(){
if( String(inpt.value) != '' && isNaN(inpt.value) == true )
{
answer.innerHTML = `<p>${inpt.value} </p>`;
inpt.value = '';
}
}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<style>
input{
outline: none;
}
</style>
<div class="container">
<input type="text" value="" id="txt" name="txt">
<button id="btn" onclick="AddMessage()">send</button>
<p>whats your name ?</p>
<ul id="list">
</ul>
</div>
<script>
var message = document.querySelector('.container');
var btn = document.getElementById('btn');
var inpt = document.getElementById('txt');
var list = document.getElementById('list');
let myList = "";
function AddMessage(){
if( String(inpt.value) !== '' && isNaN(inpt.value) == true )
{
myList +=`<li>${inpt.value}</li>`;
list.innerHTML = myList;
}
}
</script>
</body>
</html>