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>
Related
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 :)
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>
I am in the process of making an HTML form where users have different options. I am trying to make a button that infinitely generates a new set op input fields with increasements in the name, like:
The first generated input should have a name of input1. The next with a name of input2 and so on.
Here is a visual example: https://webmshare.com/ZBvw0
How can this be accomplished?
You can solve this problem by creating your form elements dynamically and appending them to your form element.
Below a simplified example, just to show the main idea.
Main points here are:
Document.createElement() - Which creates a specified HTML element (your form elements in this instance).
Node.appendChild() - Which adds a node to the end of the list of children of a specified parent node (your form element in this instance).
(function() {
var counter = 0;
var btn = document.getElementById('btn');
var form = document.getElementById('form');
var addInput = function() {
counter++;
var input = document.createElement("input");
input.id = 'input-' + counter;
input.type = 'text';
input.name = 'name';
input.placeholder = 'Input number ' + counter;
form.appendChild(input);
};
btn.addEventListener('click', function() {
addInput();
}.bind(this));
})();
input{
display: block;
}
<form id="form" action="">
</form>
<button id="btn" type="button">Click Me!</button>
You can use jquery to fetch the name of the last item.
Then you can use the javascript string replace method and replace 'input' with '' in order to get the number of the last item.
Then just increment it by 1. You will have to parse it as an integer before adding 1 to it.
Then with the incremented number, create a new input field and append it to your container.
Try this
HTML
<div id="demo">
</div>
<input type="button" id="add" value="Add input"/>
Javascript
var num = 1;
document.getElementById('add').addEventListener("click",addInput);
function addInput(){
var demo = document.getElementById('demo');
demo.insertAdjacentHTML('beforeend','<div class="form-holder" style="width: 30%;"><a class="form-label">Billet type</a> <br><select name="ttype'+num+'"><option value="normal">Standard Billet</option><option value="add-on">Tilkøbs Billet</option></select></div><div class="form-holder" style="width: 31%; margin-left: 0.6%;"><a class="form-label">Billet navn</a> <br><input name="tname'+num+'" type="text" placeholder="F.eks. Entré Billet" style="width: 100%;" /></div><div class="form-holder" style="float: right; width: 18%; margin-left: 1%;"><a class="form-label">Antal</a> <br><input name="tquan'+num+'" type="text" placeholder="F.eks. 500" style="width: 100%;" /></div><div class="form-holder" style="float: right; width: 18%;"><a class="form-label">Pris (DKK)</a> <br><input name="tprice'+num+'" type="text" placeholder="F.eks. 100" style="width: 100%;" /></div> <br>');
num++;
}
Check out jsFiddle example
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>
Html input field is inside anchor tag like so ..
<a id="brand" onclick="myFunction()" class="brand" ><input id="mytext" onclick="myFunction()" type="hidden" value="Anchor Title">Anchor Title</a>
Javascript uses set attribute
<script>
function myFunction() {
document.getElementById("brand").innerHTML = "";
document.getElementById("mytext").setAttribute("type", "text");
var elem = document.getElementById("mytext");
elem.value = "Edit Title";
document.getElementById("brand").innerHTML = elem.value;
}
</script>
ACTUAL RESULTS
Anchor title is cleared on click
But, the input field is still hidden
Wanting To Achieve
Anchor title cleared on click
Input text field appears
User inputs text
Text from input becomes anchor title
Input field becomes hidden again
I think you should remove the line:
document.getElementById("brand").innerHTML = "";
(I don't know but maybe you delete the input element by that.)
Notice that when you do document.getElementById("brand").innerHTML = ""; you are deleting all things there are between <a id="brand"> and </a>, in this case the <input> line.
My solution:
<html>
<script>
function myFunction1() {
var elem1 = document.getElementById("mytext1")
elem1.setAttribute("type", "text");
elem1.value="Edit Title";
document.getElementById("mytext2").innerHTML = "";
}
function myFunction2() {
var elem1 = document.getElementById("mytext1")
elem1.setAttribute("type", "hidden");
document.getElementById("mytext2").innerHTML = elem1.value;
}
</script>
<a id="brand" onclick="myFunction1()" class="brand" >
<input id="mytext1" onchange="myFunction2()" type="hidden" value="Anchor Title">
<span id="mytext2">Anchor Title</span>
</a>
</html>