I am trying to make a task tracker for myself using HTML CSS and JS. I am trying to add the users text and add it to the table but when it adds its undefined. I understand I haven't declared something but I am really unsure of what it is.
I believe the issue is within the JavaScript and how I have structured, it's my first day on DOM for JS.
var getTask = console.log(document.getElementById("task-text").value);
function postTask(getTask) {
document.getElementById('all-tasks').innerHTML = '<tr><td>' getTask '</td></tr>';
}
postTask(getTask)
:root {
font-family: Inter, Serif;
}
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.container {
display: grid;
grid-template-columns: repeat(4) 1fr;
grid-template-rows: 1fr;
grid-template-areas:
"header header header header";
}
.header {
grid-area: header;
background-image: linear-gradient(to right, rgb(0, 119, 255), rgb(30, 45, 255));
text-align: center;
color: white;
}
.container-2 {
display: grid;
grid-template-columns: 1.1fr 0.8fr 1.1fr;
grid-template-rows: 1fr;
grid-template-areas:
". tasks .";
font-weight: bold;
}
.tasks {
grid-area: tasks;
border-radius: 0.5rem;
margin-top: 5rem;
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
}
.current-tasks {
margin: 2rem;
}
.current-tasks h2 {
color: rgb(0, 119, 255);
margin-bottom: .5rem;
}
.current-tasks td {
color: rgb(44, 143, 255);
display: block;
border: none;
}
.current-tasks table {
border-collapse: separate;
border-spacing: 0 15px;
}
.container-3 {
display: grid;
grid-template-columns: 1.1fr 0.8fr 1.1fr;
grid-template-rows: 1fr;
grid-template-areas:
". add-tasks-box .";
}
.add-tasks-box {
grid-area: add-tasks-box;
border-radius: 0.5rem;
margin-top: 5rem;
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
}
.inner-box{
margin: 2rem;
}
.add-tasks {
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
border-radius: .1rem;
}
.add-tasks input {
margin: .2rem;
width: 97%;
border: rgb(0, 0, 0);
}
<!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">
<link href="https://rsms.me/inter/inter.css" rel="stylesheet">
<title>Motivation</title>
</head>
<body>
<div >
<div >
<h1>Let's keep on track</h1>
</div>
</div>
<div >
<div >
<div >
</div>
<div >
<h2>Tasks</h2>
<table id="all-tasks">
<tr><td>Understand JavaScript in greater detail.</td></tr>
<tr><td>Use a framework like ReactJS or JQuery.</td></tr>
<tr><td>Implement some sort of database to my website.</td></tr>
</table>
</div>
</div>
</div>
<div >
<div >
<div >
<h2>Add a new task</h2>
<div >
<form>
<input type="text" placeholder="Add a new task here." id="task-text"/>
</form>
</div>
<button onclick="postTask()" id="btn1">Submit</button>
</div>
</div>
</div>
<script src="index.js"></script>
</body>
</html>
CodePudding user response:
Two things:
You are assigning
console.log(...)
togetTask
, which isn't what you want.console.log()
always returns undefined. So let's say you wrote this instead:var getTask = document.getElementById("task-text").value);
getTask
isn't a "live" value, it copies the value fromdocument.getElementById("task-text")
over to your variable. So in your function, you need to just get the.value
from the element every time. However, note that if you havevar input = document.getElementById("task-text")
, then you can later do thingsinput.value
sinceinput
is an object (an Element).
const list = document.getElementById('list');
const input = document.getElementById('task-text');
function postTask() {
const listItem = document.createElement('li');
// Using `innerText` prevents HTML injection
listItem.innerText = input.value;
list.appendChild(listItem)
}
<ul id="list"></ul>
<label>New task: <input id="task-text"></label>
<button onclick="postTask()" id="btn1">Submit</button>
I simplified the idea in the example above but the same concepts apply. Also note that I'm using appendChild to add my HTML to the DOM node on the page. You originally had someElement.innerHTML = '...'
which is probably not what you want to do. Whenever you do that, you re-render the entire contents, which is inefficient and can lead to subtle bugs if the other child DOM nodes had things like event listeners attached. See this page for some further explanation of that.
CodePudding user response:
postTask()
expects the task text to be passed as an argument. But you're doing onclick="postTask()"
, with no argument. Pass an argument like this:
onclick="postTask(document.getElementById('task-text').value)"
There's no need to call postTask()
at top-level, since the user hasn't entered anything, it should only be called from the click handler.
function postTask(getTask) {
document.getElementById('all-tasks').innerHTML = '<tr><td>' getTask '</td></tr>';
}
:root {
font-family: Inter, Serif;
}
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.container {
display: grid;
grid-template-columns: repeat(4) 1fr;
grid-template-rows: 1fr;
grid-template-areas:
"header header header header";
}
.header {
grid-area: header;
background-image: linear-gradient(to right, rgb(0, 119, 255), rgb(30, 45, 255));
text-align: center;
color: white;
}
.container-2 {
display: grid;
grid-template-columns: 1.1fr 0.8fr 1.1fr;
grid-template-rows: 1fr;
grid-template-areas:
". tasks .";
font-weight: bold;
}
.tasks {
grid-area: tasks;
border-radius: 0.5rem;
margin-top: 5rem;
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
}
.current-tasks {
margin: 2rem;
}
.current-tasks h2 {
color: rgb(0, 119, 255);
margin-bottom: .5rem;
}
.current-tasks td {
color: rgb(44, 143, 255);
display: block;
border: none;
}
.current-tasks table {
border-collapse: separate;
border-spacing: 0 15px;
}
.container-3 {
display: grid;
grid-template-columns: 1.1fr 0.8fr 1.1fr;
grid-template-rows: 1fr;
grid-template-areas:
". add-tasks-box .";
}
.add-tasks-box {
grid-area: add-tasks-box;
border-radius: 0.5rem;
margin-top: 5rem;
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
}
.inner-box{
margin: 2rem;
}
.add-tasks {
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
border-radius: .1rem;
}
.add-tasks input {
margin: .2rem;
width: 97%;
border: rgb(0, 0, 0);
}
<!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">
<link href="https://rsms.me/inter/inter.css" rel="stylesheet">
<title>Motivation</title>
</head>
<body>
<div >
<div >
<h1>Let's keep on track</h1>
</div>
</div>
<div >
<div >
<div >
</div>
<div >
<h2>Tasks</h2>
<table id="all-tasks">
<tr><td>Understand JavaScript in greater detail.</td></tr>
<tr><td>Use a framework like ReactJS or JQuery.</td></tr>
<tr><td>Implement some sort of database to my website.</td></tr>
</table>
</div>
</div>
</div>
<div >
<div >
<div >
<h2>Add a new task</h2>
<div >
<form>
<input type="text" placeholder="Add a new task here." id="task-text"/>
</form>
</div>
<button onclick="postTask(document.getElementById('task-text').value)" id="btn1">Submit</button>
</div>
</div>
</div>
<script src="index.js"></script>
</body>
</html>
CodePudding user response:
why you have console.log assigned to a variable???!
CodePudding user response:
Essentially the problem is not really that console.log
always returns undefined
, that's just the most immediate issue. You're still going to run into a similar problem because of when your code is running. Every script
element runs when the page is loaded, so postTask
is being called before the page is fully rendered, so it's not going to have any value yet.
Solution is make sure the code runs only when the button is clicked (i.e. within the click handler). Note that the handler shown below follows the practice of attaching event handlers separately, to promote separation of code and display elements (i.e. Using "onClick='js-code-here'" isn't recommended)
document.getElementById("btn1").addEventListener("click", function() {
if (task = document.getElementById("task-text").value) {
document.getElementById('all-tasks').innerHTML = '<tr><td>' task '</td></tr>';
}
})
:root {
font-family: Inter, Serif;
}
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.container {
display: grid;
grid-template-columns: repeat(4) 1fr;
grid-template-rows: 1fr;
grid-template-areas:
"header header header header";
}
.header {
grid-area: header;
background-image: linear-gradient(to right, rgb(0, 119, 255), rgb(30, 45, 255));
text-align: center;
color: white;
}
.container-2 {
display: grid;
grid-template-columns: 1.1fr 0.8fr 1.1fr;
grid-template-rows: 1fr;
grid-template-areas:
". tasks .";
font-weight: bold;
}
.tasks {
grid-area: tasks;
border-radius: 0.5rem;
margin-top: 5rem;
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
}
.current-tasks {
margin: 2rem;
}
.current-tasks h2 {
color: rgb(0, 119, 255);
margin-bottom: .5rem;
}
.current-tasks td {
color: rgb(44, 143, 255);
display: block;
border: none;
}
.current-tasks table {
border-collapse: separate;
border-spacing: 0 15px;
}
.container-3 {
display: grid;
grid-template-columns: 1.1fr 0.8fr 1.1fr;
grid-template-rows: 1fr;
grid-template-areas:
". add-tasks-box .";
}
.add-tasks-box {
grid-area: add-tasks-box;
border-radius: 0.5rem;
margin-top: 5rem;
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
}
.inner-box{
margin: 2rem;
}
.add-tasks {
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
border-radius: .1rem;
}
.add-tasks input {
margin: .2rem;
width: 97%;
border: rgb(0, 0, 0);
}
<!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">
<link href="https://rsms.me/inter/inter.css" rel="stylesheet">
<title>Motivation</title>
</head>
<body>
<div >
<div >
<h1>Let's keep on track</h1>
</div>
</div>
<div >
<div >
<div >
</div>
<div >
<h2>Tasks</h2>
<table id="all-tasks">
<tr><td>Understand JavaScript in greater detail.</td></tr>
<tr><td>Use a framework like ReactJS or JQuery.</td></tr>
<tr><td>Implement some sort of database to my website.</td></tr>
</table>
</div>
</div>
</div>
<div >
<div >
<div >
<h2>Add a new task</h2>
<div >
<form>
<input type="text" placeholder="Add a new task here." id="task-text"/>
</form>
</div>
<button id="btn1">Submit</button>
</div>
</div>
</div>
<script src="index.js"></script>
</body>
</html>