New tasks won't delete when checkbox clicked. - javascript

I am new to programming and for fun am trying to put together a todo list app.
When the user clicks on the text of the first Item the program will strike-through the text and when the user clicks the checkbox on the first item it disappears like I want it to. But when I add a new task the strike-through and checkbox don't work. Here is my code. Thanks for the.
HTML
<!DOCTYPE html>
<head>
</head>
<body>
<div id = "header">
<h1> To Do List</h1>
</div>
<div id = "form">
<form>
<input type = "text" id = "todo">
<button type = "button" id= "submit"> Submit </button>
</form>
</div>
<div id = "tasklist">
<ol id = "list">
<li id = "listitem"><input type = "checkbox" class="checkbox"
> Clean</li>
</ol>
</div>
<script type="text/javascript" src="todo.js"></script>
</body>
Here is my js
window.onload = function(){
//Add new to do task by entering text and clicking submit
var submit = document.getElementById('submit');
submit.onclick = function(){
var task = document.getElementById('todo').value;
console.log(task);
var ol = document.getElementById("list")
var entry = document.createElement('li');
entry.id = 'id'
var checkbox = document.createElement('input');
checkbox.type = "checkbox";
checkbox.className = "checkbox"
entry.appendChild(checkbox)
entry.appendChild(document.createTextNode(task));
ol.appendChild(entry);
};
//Strike through task if click on text
$("li").click(function(){
$(this).css("text-decoration", "line-through");
});
//Remove task when click checkbox
$(".checkbox").click(function(){
$(this).parent().hide();
})
};

The $("li").click(function(){ click handler will only work for elements that are in the DOM when the handler is applied - it won't work for future elements! You'll need to implement jQuery's .on() handler instead, which will work for elements that get added to the DOM in the future.
//Strike through task if click on text
$(document).on('click','li', function(){
$(this).css("text-decoration", "line-through");
});
//Remove task when click checkbox
$(document).on('change','.checkbox', function(){
$(this).parent().hide();
});
https://jsfiddle.net/3fr54rp0/

You need to delegate the event handler for those links since they aren't in the DOM when the page is rendered. You can do this by attaching the click handler by using $(document).on() and specifying the element you want the handler to attach to.
Here's a reference https://learn.jquery.com/events/event-delegation/
//Add new to do task by entering text and clicking submit
var submit = document.getElementById('submit');
submit.onclick = function() {
var task = document.getElementById('todo').value;
console.log(task);
var ol = document.getElementById("list")
var entry = document.createElement('li');
entry.id = 'id'
var checkbox = document.createElement('input');
checkbox.type = "checkbox";
checkbox.className = "checkbox"
entry.appendChild(checkbox)
entry.appendChild(document.createTextNode(task));
ol.appendChild(entry);
};
$(document).on('click', 'li', function(e) {
//Strike through task if click on text
$(this).css("text-decoration", "line-through");
}).on('click', '.checkbox', function(e) {
//Remove task when click checkbox
$(this).parent().hide();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="header">
<h1> To Do List</h1>
</div>
<div id="form">
<form>
<input type="text" id="todo">
<button type="button" id="submit"> Submit </button>
</form>
</div>
<div id="tasklist">
<ol id="list">
<li id="listitem"><input type="checkbox" class="checkbox"> Clean</li>
</ol>
</div>

Related

How to get the innerHTML of an input in Java script

I am making a TODO list. I have difficulties with setting the input text on my card. Everything I write in the input, I want to select and to put on the card.
I tried to select the innerHTML of an input when I type something in. I don't know how to select the typed input text. I would then create a new element with the text inside, and would append it to the card.
let btn = document.querySelector('.add');
let textspace = document.querySelector('.todotext');
const input = document.querySelector('input');
// eventlistner by button clicked
btn.addEventListener('click', function() {
var txt = document.getElementsByClassName('input').innerHTML;
});
<div class="card">
<div class="todoheader">TODO List</div>
<div class="todotext"></div>
<ul class="list"></ul>
<div class="addtodo">
<buton class="add" type="button"> + </buton>
<input type="text" class="input" placeholder="add todo" />
</div>
</div>
To get the value of the input use the value property, not innerHTML. Also note that you already have a reference to the input Element in the input variable, so you don't need to use getElementsByClassName() to retrieve it - not least of all because the syntax there is flawed.
Once you have the text you can use createElement() to add a new p element to the .todotext container:
const btn = document.querySelector('.add');
const textspace = document.querySelector('.todotext');
const input = document.querySelector('input');
btn.addEventListener('click', function() {
const txt = input.value;
if (!txt)
return;
const p = document.createElement('p');
p.textContent = txt;
textspace.appendChild(p);
input.value = '';
});
<div class="card">
<div class="todoheader">TODO List</div>
<div class="todotext"></div>
<ul class="list"></ul>
<div class="addtodo">
<button class="add" type="button"> + </button>
<input type="text" class="input" placeholder="add todo" />
</div>
</div>
As others already answered your question. I just wanted to point out that there is a misspelling in your code (buton instead of button). Fix that and the button element would be rendered correctly.
First, getElementsByClassName will return HTMLCollection which is array-like, you need to use querySelector instead, also the innerHTML, textContent, innerText properties all are empty string for the input because the input is a self-closing tag without content inside, you need to use value property.
let btn = document.querySelector('.add');
let textspace = document.querySelector('.todotext');
const input = document.querySelector('input');
// eventlistner by button clicked
btn.addEventListener('click', function() {
var txt = input.value;
console.log(txt)
});
<div class="card">
<div class="todoheader">TODO List</div>
<div class="todotext"></div>
<ul class="list"></ul>
<div class="addtodo">
<buton class="add" type="button"> + </buton>
<input type="text" class="input" placeholder="add todo" />
</div>
</div>
btn.addEventListener('click', function() {
var txt = document.getElementByClassName('input').value;
});
You were using getElementByClassName which will be HTMLCollection.To loop over each element you need to convert it into an array loop over them.
var txt = document.getElementsByClassName('input').value;
You should get the value of an input , not the innerHTML
Also assign a unique id to you input fields and select them with it, it's much better :)

More suitable method to remove 'li' Elements from List?

This solution below works for adding and removing list items. I had to implement Math.random() in order to set a unique id for each element. I was thinking in the professional world this definitely wouldn't cut it considering the chance of a repeating ID.
Wanted to know what would be a more suitable implementation? Any feedback welcome!
Thanks!
HTML
<html>
<head>
<body>
<p id = 'listTitle'> Your List </p>
<form onsubmit = "return false">
<input id = 'inputBar' type = "text" placeholder = "Enter Item"></input>
<input type = "submit" onclick = "getName()"></input>
<input type = "button" value = "Remove" </input>
</form>
<ol id = 'demo'>
</ol>
</body>
</head>
</html>
JS
function getName() {
var input = document.getElementById('inputBar').value
var list = document.getElementById('demo')
var entry = document.createElement('li')
entry.setAttribute("id", Math.floor(Math.random()* (100 - 1) + 1 ))
console.log(entry.id)
entry.setAttribute("onclick", "removeName(this.id)")
entry.appendChild(document.createTextNode(input))
list.appendChild(entry)
}
function removeName(removeID) {
var listItem = document.getElementById(removeID)
listItem.remove()
}
There's no need for dynamic IDs. When appending the new element, just attach a listener that calls entry.remove() when clicked. You can also assign to the textContent instead of using the unnecessarily verbose createTextNode / appendChild.
function getName() {
const inputValue = document.getElementById('inputBar').value;
const li = document.getElementById('demo').appendChild(document.createElement('li'));
li.onclick = () => li.remove();
li.textContent = inputValue;
}
<p id='listTitle'> Your List </p>
<form onsubmit="return false">
<input id='inputBar' type="text" placeholder="Enter Item"></input>
<input type="submit" onclick="getName()"></input>
<input type="button" value="Remove" </input>
</form>
<ol id='demo'>
</ol>

Removing Checked checkbox elements using a function

Trying to make a to-do list using JavaScript but can't seem to figure out a way to delete the checked checkboxes.
I tried to have the program change the id then delete everything with that new id but that didn't seem to work, maybe I was missing something important not sure but if any of you know a different way of deleting checked checkboxes, I'd appreciate the help.
function add() {
var myDiv = document.getElementById("myDiv");
var inputValue = document.getElementById("myInput").value;
// creating checkbox element
var checkbox = document.createElement('input');
if (inputValue === '') {
alert("Input is Empty!");
} else {
document.getElementById("myUL").appendChild(checkbox);
}
// Assigning the attributes to created checkbox
checkbox.type = "checkbox";
checkbox.name = "name";
checkbox.value = "value";
checkbox.id = "checkBox";
// create label for checkbox
var label = document.createElement('label');
// assigning attributes for the created label tag
label.htmlFor = "checkBox";
// appending the created text to the created label tag
label.appendChild(document.createTextNode(inputValue));
// appending the checkbox and label to div
myDiv.appendChild(checkbox);
myDiv.appendChild(label);
}
function remove() {
var doc = document.getElementById("checkBox").checked;
doc.remove;
}
<h1>To Do List</h1>
<input type="text" id="myInput">
<button onclick='add()'>Click me!</button>
<button onclick="remove()">Delete</button>
<ul id="myUL">
<div id="myDiv"></div>
</ul>
There are several issues to your code:
You are recycling the #checkBox ID. Remember that IDs must be unique within a document. Therefore, you should be generating a unique ID for each label + checkbox pair
You are only removing the checkbox element and not the label text, so even if your logic works, the appearance / outcome of your code is not what you want.
A solution will be wrapping your label text and the checkbox element inside the label. The advantages of this is that:
The <label> element does not need a for attribute, since clicking on the label will automatically check the nested checkbox
You can use .closest('label') to remove the entire label text + checkbox pair, when you hit the delete button
In order to iterate through all the checked checkboxes, you can simply run this selector: document.querySelector('.checkbox:checked'). To iterate through this Node collection, you can use Array.prototype.forEach().
Another note: you might want to return from the function if there an empty text is provided when a user wants to add a textbox.
See proof-of-concept example below:
function add() {
var myDiv = document.getElementById("myDiv");
var inputValue = document.getElementById("myInput").value;
// creating checkbox element
var checkbox = document.createElement('input');
if (inputValue === '') {
alert("Input is Empty!");
return;
} else {
document.getElementById("myUL").appendChild(checkbox);
}
// Assigning the attributes to created checkbox
checkbox.type = "checkbox";
checkbox.name = "name";
checkbox.value = "value";
checkbox.classList.add("checkbox");
// create label for checkbox
var label = document.createElement('label');
// appending the checkbox and created text to the created label tag
label.appendChild(checkbox);
label.appendChild(document.createTextNode(inputValue));
// appending label to div
myDiv.appendChild(label);
}
function remove() {
const checkboxes = document.querySelectorAll('.checkbox:checked');
Array.prototype.forEach.call(checkboxes, function(checkbox) {
checkbox.closest('label').remove();
});
}
<h1>To Do List</h1>
<input type="text" id="myInput">
<button onclick='add()'>Click me!</button>
<button onclick="remove()">Delete</button>
<ul id="myUL">
<div id="myDiv"></div>
</ul>
I think you should restructure your html. Create a separate function createItem() which
returns a <div> containing <input> and text. Give a specific className to container div.
Inside remove() you querySelectorAll() to get all items. And use forEach() to loop through items and check if the input of item is checked then remove() it
Note: id of the element in whole document should be unique
function createItem(text){
const container = document.createElement('div');
container.className = 'item'
container.innerHTML = `<input type="checkbox" /><span>${text}</span>`
return container;
}
function add() {
var myDiv = document.getElementById("myDiv");
var inputValue = document.getElementById("myInput").value;
// creating checkbox element
var checkbox = document.createElement('input');
if (inputValue === '') {
alert("Input is Empty!");
} else {
document.getElementById("myUL").appendChild(createItem(inputValue));
}
}
function remove() {
var doc = document.querySelectorAll('.item');
doc.forEach(x => {
if(x.querySelector('input').checked){
x.remove()
}
})
}
<h1>To Do List</h1>
<input type="text" id="myInput">
<button onclick='add()'>Click me!</button>
<button onclick="remove()">Delete</button>
<ul id="myUL">
<div id="myDiv"></div>
</ul>
Use a query:
function removeCheckedCheckboxes() {
const query = document.querySelectorAll('[type="checkbox"]:checked');
Array.from(query).forEach(element =>
element.remove()
);
}
<html>
<body>
<span style="background: red; display: inline-block">
<input type="checkbox">
</span>
<br>
<span style="background: orange; display: inline-block">
<input type="checkbox">
</span>
<br>
<span style="background: yellow; display: inline-block">
<input type="checkbox">
</span>
<br>
<span style="background: green; display: inline-block">
<input type="checkbox">
</span>
<br>
<span style="background: blue; display: inline-block">
<input type="checkbox">
</span>
<br>
<span style="background: purple; display: inline-block">
<input type="checkbox">
</span>
<br>
<br>
<button onclick="removeCheckedCheckboxes()">
Remove checked checkboxes
</button>
</body>
</html>

JavaScript Appended Element Text Not Showing

I'm trying to create an online to do list for users and I want it to function so that when you enter a task and click the 'JotIT' button the task is appended.
So far the function to append works but the text is not visible for some reason even though when I inspect it, the text shows up in the HTML.
<script>
var welcome = 'Welcome To JotIT';
var jotItem = function()
{
//Create & Get the necessary elements
var item = document.createElement('input'),
space = document.createElement('br'),
form = document.getElementById("listing"),
frag = document.createDocumentFragment(),
textVal = document.getElementById("input-jot");
//Set Attributes to list item
item.setAttribute('type', 'checkbox');
item.setAttribute('name', 'jot-list');
//If there is no input in the textbox then create an alert popup
if(textVal.value === "")
alert("Please insert a value");
else {
item.innerHTML = textVal.value;
frag.appendChild(item);
frag.appendChild(space);
form.appendChild(frag);
textVal.value = "";
}
}
</script>
</head>
<body>
<h1 id="head">JotIT</h1><br>
<p> <script type="text/javascript">document.write(welcome);</script></p>
<input type="form" id= "input-jot">
<button class = 'btn-info' id="jot-down" onclick=jotItem();>JotIt!</button>
<!-- TODO: Add form submit tag instead of ul tag -->
<!-- TODO: Align the list items -->
<form id = "listing" method="get">
<input type="checkbox" name="me"> Start </input>
</form>
</body>
You Have to insert a label. Inputs should be self closing / empty elements. In particular an input of type checkbox won't correctly display a label. Use the label element for this purpose instead.
var welcome = 'Welcome To JotIT';
var jotItem = function() {
//Create & Get the necessary elements
var item = document.createElement('input'),
label = document.createElement('label'),
space = document.createElement('br'),
form = document.getElementById("listing"),
frag = document.createDocumentFragment(),
textVal = document.getElementById("input-jot");
//Set Attributes to list item
item.setAttribute('type', 'checkbox');
item.setAttribute('name', 'jot-list');
//If there is no input in the textbox then create an alert popup
if (textVal.value === "")
alert("Please insert a value");
else {
label.innerText = textVal.value;
frag.appendChild(label); // here goes the label
frag.appendChild(item);
frag.appendChild(space);
form.appendChild(frag);
textVal.value = "";
}
}
</head>
<body>
<h1 id="head">JotIT</h1>
<br>
<input type="form" id="input-jot">
<button class='btn-info' id="jot-down" onclick=jotItem();>JotIt!</button>
<!-- TODO: Add form submit tag instead of ul tag -->
<!-- TODO: Align the list items -->
<form id="listing" method="get">
<label>Start</label>
<input type="checkbox" name="me" />
</form>
</body>
This has to do with the fact that you're adding the label to the input incorrectly. Use the below HTML syntax and it will resolve your issue:
<label><input type="checkbox" name="jot-list" />The Text</label>

create buttons on onclick function while getting values from textboxes for their rows and columns

<body>
<header>
</header>
<nav>
<div class="table" id="div1" >
</div>
<br>
<br>
<br>
<div class="boxes" id="boxes">
<input type="text" maxlength="2" name="value" id='value' />
<input type="text" maxlength="2" name="value2" id='value2' />
<input type="button" value="submit" onclick="size()" />
</div>
</nav>
</body>
So basically when i write this window.onload = function() {beggining1(10,10);};
everything works ok, when page loads 10 rows and 10 columns of buttons are made.
But now i want instead on pageload ,I want to make the buttons from a button which recieves columns and rows properties from 2 text boxes.<input type="button" value="submit" onclick="size()" />
<script type="text/javascript">
var rows = getElementById('value');
var columns = getElementById('value2');
window.onload = function() {beggining1(10,10);};
function size(){
beggining1(rows,columns);
}
function beggining1(k,l){
for (i=1;i<k;i++){
for (j=1;j<l;j++){
var btn = document.createElement("BUTTON");
btn.className = "button1";
btn.style.cssText = 'background:green;height:50px;width:50px;margin:5px;';
var t = document.createTextNode(i+"_"+j);
btn.appendChild(t);
document.getElementById("div1").appendChild(btn);
document.getElementById('div1').addEventListener('click' , reserve);
}
document.getElementById('div1').appendChild(document.createElement("br"));
}
}
</script>
I dont know whats wrong in my code and im trying to understand but i can't i guess its something stupid i miss.
Replace size function with the updated one mentioned below and remove window.load handler as now you want to generate when user click on button,
I return false from the size() function because if the button is in form tag it would submit the form and postback the page.
<script type="text/javascript">
function size(){
var rows = document.getElementById("value").value;
var columns = document.getElementById("value2").value;
beggining1(rows,columns);
return false;
}
function beggining1(k,l){
for (i=1;i<k;i++){
for (j=1;j<l;j++){
var btn = document.createElement("BUTTON");
btn.className = "button1";
btn.style.cssText = 'background:green;height:50px;width:50px;margin:5px;';
var t = document.createTextNode(i+"_"+j);
btn.appendChild(t);
document.getElementById("div1").appendChild(btn);
document.getElementById('div1').addEventListener('click' , reserve);
}
document.getElementById('div1').appendChild(document.createElement("br"));
}
}
</script>

Categories