I was trying to add a delete button to the list element but it was not adding. Now I created the Delete button using forEach loop but now the problem is the delete button is added only to the existing list only whenever I add a new item in the list the list gets added but the delete button is not created.
function createButton(lis) {
const list = document.querySelectorAll("li")
list.forEach(function (lis) {
const button = document.createElement("button");
button.textContent = "Delete";
lis.appendChild(button);
ul.appendChild(lis);
});
}
the problem is in the last lines
function createButton() {
var btn = document.createElement("button");
btn.textContent = "Delete";
li.appendChild(btn);
ul.appendChild(li);
}
here is a simple example of how to add buttons to the list, you can extend on it and customise it
<body>
<ul id= "list" >
</ul>
<button onclick="createButton()">add delete buttons</button>
<script>
const ul=document.getElementById("list")
function createButton() {
const btn = document.createElement("button")
const li = document.createElement("li")
const br = document.createElement("br")
btn.textContent = "Delete"
li.appendChild(btn);
ul.appendChild(li);
ul.appendChild(br)
}
</script>
</body>
Related
I am creating a small library app and I am trying to add a delete entry function. I am looking to add the actual functionality of the button but I can't figure out how to add the eventlistener to each instance. When I click on the image it does nothing.
JAVASCRIPT
//dynamic creation of trash button
let deleteEntry = document.createElement("td")
const deleteBtn = document.createElement("input");
const deleteImg = document.createAttribute("type");
deleteImg.value = "image";
deleteBtn.className = "deletebtn"
deleteBtn.src = "red_trash_can.png";
deleteEntry.append(deleteBtn);
deleteBtn.setAttributeNode(deleteImg)
//
const trashBtn = Array.from(document.getElementsByClassName("deletebtn"));
trashBtn.forEach(button => {
button.addEventListener('click',e => {
console.log(e)
})
})
HTML
<td>
<input class="deletebtn" src="red_trash_can.png" type="image">
</td>
You can add the event listener directly to the deleteBtn before appending it. And also the type can be added directly like you do with the className or the src.
Working example: (i used a dummy image and a simple string in console.log() because the event took so long)
//dynamic creation of trash button
const deleteEntry = document.createElement("td")
const deleteBtn = document.createElement("input");
deleteBtn.type = "image";
deleteBtn.className = "deletebtn"
deleteBtn.src = "https://picsum.photos/200";
deleteBtn.addEventListener('click', () => {
console.log("You clicked the image!")
});
deleteEntry.append(deleteBtn);
document.querySelector("#wrapper").append(deleteEntry);
<div id="wrapper"></div>
I am making a todo list, i have just about everything for it figured out but one area i am stuck on is my UL and Li.
Basically when you enter items into the list, you have the ability to click the checkbox beside said item when you complete the task, and it will put a line through the text.
But i also want it to move that item to the bottom of the list when it is clicked.
would anyone be able to help me with how i would go about doing that
code Below
// making event listener for adding item
let addBTN = document.getElementById('addBtn');
addBTN.addEventListener('click', addItem);
// this creates a new li based on the entered value in the text box that it gets when you hit the button
// Through Research found that setAttribute isn't really needed and i can just use .id , .type etc
function addItem() {
// Creating needed elements as well as getting text from textbox
let newLi = document.createElement("li");
let myLiValue = document.getElementById('textBoxAdd').value;
let liTextNode = document.createElement("label");
liTextNode.textContent = myLiValue;
// makes div for li
let newDivID = ('div_' + myLiValue);
let newDiv = document.createElement('div');
newDiv.id = newDivID;
// makes checkboxes for the li
let newCheckBoxID = ('checkbox_' + myLiValue);
let newCheckBox = document.createElement('input');
newCheckBox.type = 'checkbox';
newCheckBox.id = newCheckBoxID;
// makes delete button for the li
let newDeleteID = ('deleteButton_' + myLiValue);
let newDeleteButton = document.createElement("button")
newDeleteButton.type = 'button';
newDeleteButton.id = newDeleteID
newDeleteButton.textContent = 'Delete';
//newDeleteButton.setAttribute('onclick', 'deleteItem()');
newDeleteButton.innerHTML = 'Delete';
// appends it to my newDiv
newDiv.appendChild(newCheckBox);
newDiv.appendChild(liTextNode);
newDiv.appendChild(newDeleteButton);
// then appends my new div to the new Li
newLi.appendChild(newDiv);
// this just makes sure a user cant enter in a blank value
if (myLiValue == "") {
alert("Please Enter Something Before Hitting Add Item");
} else {
document.getElementById('theNewList').appendChild(newLi);
document.getElementById('textBoxAdd').value = "";
}
}
//creating event listener for checkbox line through text and moving item
let theList = document.getElementById('theNewList');
theList.addEventListener('click', checkedComplete);
// function that will target every check box in the list and if any get checked then it will add a line through the text
function checkedComplete(event) {
const checkboxElement = event.target;
if (checkboxElement.type === 'checkbox') {
if (checkboxElement.checked) {
checkboxElement.nextElementSibling.style.textDecoration = 'line-through';
// add in moving item
} else {
checkboxElement.nextElementSibling.style.textDecoration = 'none';
}
}
}
// adds deleteItem listener to the list
theList.addEventListener('click', deleteItem);
function deleteItem(event) {
const deleteButton = event.target;
if (deleteButton.type === 'button') {
const deleteParentNode = deleteButton.parentNode;
deleteParentNode.parentNode.removeChild(deleteParentNode);
}
}
You are going to have a storage of you todos, right? Even if you did not think about it, it can do all the work. Just create the array (you could use localStorage to prevent you data from disappearing after browser is restarted) containing your todos and their condition, like
const todos = [{todo:"watch the movie", completed: false}, {...}, {...}]
Now you can easily add or remove items with standard array methods pop&push, delete with splice, filter etc. After array is mdified, just update the page and build your list using Array.map.
You should just add the following logic where you have // add in moving item comment:
const theList = document.getElementById('theNewList');
const lastListItem = theList.children[theList.children.length - 1];
theList.insertBefore(lastListItem, checkboxElement.parentNode.parentNode);
We're selecting your ul and searching for its last li and then we're simply placing the li belonging to the checkboxElement after the last li.
Working example:
// making event listener for adding item
let addBTN = document.getElementById('addBtn');
addBTN.addEventListener('click', addItem);
// this creates a new li based on the entered value in the text box that it gets when you hit the button
// Through Research found that setAttribute isn't really needed and i can just use .id , .type etc
function addItem() {
// Creating needed elements as well as getting text from textbox
let newLi = document.createElement("li");
let myLiValue = document.getElementById('textBoxAdd').value;
let liTextNode = document.createElement("label");
liTextNode.textContent = myLiValue;
// makes div for li
let newDivID = ('div_' + myLiValue);
let newDiv = document.createElement('div');
newDiv.id = newDivID;
// makes checkboxes for the li
let newCheckBoxID = ('checkbox_' + myLiValue);
let newCheckBox = document.createElement('input');
newCheckBox.type = 'checkbox';
newCheckBox.id = newCheckBoxID;
// makes delete button for the li
let newDeleteID = ('deleteButton_' + myLiValue);
let newDeleteButton = document.createElement("button")
newDeleteButton.type = 'button';
newDeleteButton.id = newDeleteID
newDeleteButton.textContent = 'Delete';
//newDeleteButton.setAttribute('onclick', 'deleteItem()');
newDeleteButton.innerHTML = 'Delete';
// appends it to my newDiv
newDiv.appendChild(newCheckBox);
newDiv.appendChild(liTextNode);
newDiv.appendChild(newDeleteButton);
// then appends my new div to the new Li
newLi.appendChild(newDiv);
// this just makes sure a user cant enter in a blank value
if (myLiValue == "") {
alert("Please Enter Something Before Hitting Add Item");
} else {
document.getElementById('theNewList').appendChild(newLi);
document.getElementById('textBoxAdd').value = "";
}
}
//creating event listener for checkbox line through text and moving item
let theList = document.getElementById('theNewList');
theList.addEventListener('click', checkedComplete);
// function that will target every check box in the list and if any get checked then it will add a line through the text
function checkedComplete(event) {
const checkboxElement = event.target;
if (checkboxElement.type === 'checkbox') {
if (checkboxElement.checked) {
checkboxElement.nextElementSibling.style.textDecoration = 'line-through';
const theList = document.getElementById('theNewList');
const lastListItem = theList.children[theList.children.length - 1];
theList.insertBefore(checkboxElement.parentNode.parentNode, lastListItem.nextSilbing);
} else {
checkboxElement.nextElementSibling.style.textDecoration = 'none';
}
}
}
// adds deleteItem listener to the list
theList.addEventListener('click', deleteItem);
function deleteItem(event) {
const deleteButton = event.target;
if (deleteButton.type === 'button') {
const deleteParentNode = deleteButton.parentNode;
deleteParentNode.parentNode.removeChild(deleteParentNode);
}
}
<input id="textBoxAdd" type="text" />
<button id="addBtn" type="button">Add</button>
<ul id="theNewList"></ul>
I'm trying to create a list from user text input where each list contains a delete button which deletes the list when the delete button is clicked using javascript. However, I can't get my delete button to work. Here's what I've tried:
In HTML:
<ul id="thisul"></ul>
<input type="text" placeholder="Add New" id="input">
<input type="submit" class="button" value="Submit" onclick ="show()">
In JS:
function show(){
var ul = document.getElementById("thisul");
var input= document.getElementById("input");
var li = document.createElement("li");
li.classList.add("thisLI");
if(input.value!==""){
li.innerHTML=input.value+'<button><i class="fas fa-trash" aria-hidden="true"></i></button>';
ul.appendChild(li);
ul.on("click", "button", function(){
del(this);
});
}
}
function del(x){
var deleting = document.getElementsByClassName("thisLI");
var theList = x.parentElement;
var index = Array.from(deleting).indexOf(x);
theList.removeChild(deleting[index]);
}
Can anyone help me with this?
Thank you!
You seem to be using some jQuery here when adding the event listener. You also want to target some elements in the global scope so you don't have to target them everytime the function is called. Here is how I would do it.
//Global scope
const ul = document.getElementById('thisul');
const input = document.getElementById('input');
function show() {
const li = document.createElement('li')
const div = document.createElement('div')
const button = document.createElement('button')
const i = document.createElement('i')
div.textContent = input.value
i.className = 'fas fa-trash'
i.setAttribute('aria-hidden', 'true')
button.appendChild(i)
button.addEventListener('click', function() {
li.remove()
})
li.append(div, button)
ul.appendChild(li)
}
This should work.
Edit:
Just re-read that you want to click the button to delete. I will tweak the code a little bit.
JSFiddle Link
This question already has answers here:
How do I toggle an element's class in pure JavaScript?
(13 answers)
Find the closest ancestor element that has a specific class
(6 answers)
Closed 2 years ago.
I am making a to-do list. I am trying to add two buttons (checked and delete). When I click on the delete button I want to delete the entire list. For example:
| Grocery shopping| (Checked button) (delete button) |
When I click on the delete button it should delete the whole list as in here (grocery shopping)
But, I am using bootstrap here with javascript and when I refer to className remove here it doesn't actually delete anything and I assume it's not actually referring to the className remove since my className is remove btn btn-primary font-weight-bold float-right mt--5 since I am using bootstrap, Can anyone tell me what am I doing wrong?
My code:
const todoInput = document.querySelector(".form-control");
const todoButton = document.querySelector(".add");
const todoList = document.querySelector(".todo-list");
todoButton.addEventListener("click", addTodo);
todoList.addEventListener("click", deleteCheck);
function addTodo(event) {
event.preventDefault();
const todoDiv = document.createElement("div");
todoDiv.classList.add("todo-item");
const newTodo = document.createElement("h6");
newTodo.innerText = todoInput.value;
todoDiv.appendChild(newTodo);
const removeButton = document.createElement("button");
removeButton.className =
"remove btn btn-primary font-weight-bold float-right mt--5";
const spancontainerforremove = document.createElement("span");
const icontainerforremove = document.createElement("i");
icontainerforremove.className = "fas fa-trash-alt";
spancontainerforremove.appendChild(icontainerforremove);
removeButton.appendChild(spancontainerforremove);
todoDiv.appendChild(removeButton);
const completedButton = document.createElement("button");
completedButton.className =
"complete btn btn-primary font-weight-bold float-right mr-1 mt--5";
const spancontainer = document.createElement("span");
const icontainer = document.createElement("i");
icontainer.className = "fas fa-check-circle";
spancontainer.appendChild(icontainer);
completedButton.appendChild(spancontainer);
todoDiv.appendChild(completedButton);
todoList.appendChild(todoDiv);
todoInput.value = "";
}
function deleteCheck(e) {
const item = e.target;
console.log(item.className);
if (item.className === "remove") { //does not work
item.remove();
}
}
I'm trying to format this code in such a way that when a user clicks a button, new input fields each with a redirect button gets inserted asynchronously into the un-ordered list, it worked up until i added the redirect button to also be inserted upon each click of the spawn button.
Here is my JS code...
function spawnSilly()
{
var div = document.createElement("DIV");
var input = document.createElement("INPUT");
var button = document.createElement("BUTTON");
var att1 = document.createAttribute("type")
var att2 = document.createAttribute("placeholder")
var att3 = document.createAttribute("type")
var att4 = document.createAttribute("onClick")
att1.value = "text"
att2.value = "Title"
att3.value = "button"
att4.value = "redirect()"
input.setAttributeNode(att1)
input.setAttributeNode(att2)
button.setAttribute(att3)
button.setAttribute(att4)
div.appendChild(input)
div.appendChild(button);
var list = document.getElementById("spawnList");
list.insertBefore(div, list.childNodes[0]);
}
This is my HTML
<ul id="spawnList">
</ul>
<button id="spawnbtn" onClick="spawnSilly()">Add</button>
Seems to be the button thats causing the issue, but i can't figure out why?
Any help would be awesome! thanks
Note that setAttribute() takes two arguments, the name of the attribute and the value. Using this in the right way, the code can be simplified like this:
function redirect()
{
console.log("Redirect clicked!");
}
function spawnSilly()
{
var div = document.createElement("DIV");
var input = document.createElement("INPUT");
var button = document.createElement("BUTTON");
input.setAttribute("type", "text");
input.setAttribute("placeholder", "Title");
button.setAttribute("type", "button");
button.setAttribute("onClick", "redirect()");
button.innerHTML = "Redirect";
div.appendChild(input)
div.appendChild(button);
var list = document.getElementById("spawnList");
list.insertBefore(div, list.childNodes[0]);
}
.as-console {background-color:black !important; color:lime;}
<ul id="spawnList"></ul>
<button id="spawnbtn" onClick="spawnSilly()">Add</button>
setAttribute take two parameters, first is the name of attribute and second is value, but you have only one - https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute.
Instead you can set the value to attributes using . operator.
Also, you are attaching a function call att4.value = "redirect()". So, whenever the button gets added your redirect will get called. Instead attach a callback to redirect, so it gets called when the button is clicked.
function spawnSilly()
{
const div = document.createElement("DIV");
const input = document.createElement("INPUT");
const button = document.createElement("BUTTON");
input.type = "text";
input.value = "Title";
button.type ="button";
button.onclick = redirect;
button.textContent = "Click Me!";
div.appendChild(input)
div.appendChild(button);
const list = document.getElementById("spawnList");
list.insertBefore(div, list.childNodes[0]);
}
function redirect() {
console.log('In redirect');
}
<ul id="spawnList">
</ul>
<button id="spawnbtn" onClick="spawnSilly()">Add</button>