the checkbox is not working like its supposed as it only function when added i was expecting that when i click the checkbox to hide all my books but it only works when i first add another then when the checkbox is clicked is when it hide all my books here is my code:
const addForm = document.forms["add-book"];
addForm.addEventListener("submit", function (e) {
e.preventDefault();
const added = addForm.querySelector('input[type="text"]').value;
//create elements
const li = document.createElement("li");
const bookName = document.createElement("span");
const deleteBtn = document.createElement("span");
//add content
bookName.textContent = added;
deleteBtn.textContent = "delete";
// add classes
bookName.classList.add("name");
deleteBtn.classList.add("delete");
li.appendChild(bookName);
li.appendChild(deleteBtn);
list.appendChild(li);
//hide books
const hideBox = document.querySelector("#hide");
hideBox.addEventListener("change", function (e) {
if (hideBox.checked) {
list.style.display = "none";
} else {
list.style.display = "initial";
}
});
});
Related
I want to be able to press on my trashcan and be able to delete any todo i want. Right now i can only remove the first index off my todo with with the help off splice. Also when i inspect my array in console i want to be able to use true or false. So when i click on my button my object gets removed from my screen and inside off the array in console it should show that my object indeed have been removed and turns into true instead of false( todoIsRemoved: false). here is a link so you can see all off my code: https://jsfiddle.net/marvstarv/tqdzn8bg/.
this is my class:
let p=0;
let allTheToDos = [];
class Todo{
constructor(toDoItem, removedToDo){
this.Id= p ++;
this.toDoItem = toDoItem;
this.removedToDo = removedToDo;
}
}
this is the function i need help with,
function removeTask (){
let liContainer = document.getElementById ("mySection"); // contains my label(checkmark), Li, and trashcan button.
allTheToDos.splice(Todo,1);
liContainer.innerHTML="";
generateHtml();
console.log(allTheToDos);
}
this function is conected to line 64 off my "main.js": deleteButton.addEventListener('click', () =>{removeTask(allTheToDos[i])});
i appriciate all the help, get back to me if anything was unclear.enter code here
I updated your Js file to:
window.onload = function(){
// without this my site keeps realoding when adding a new item
let firstTask = new Todo ('Bädda sängen',false);
let secondTask = new Todo ('Hänga upp tavlorna',false);
let thirdTask = new Todo ('Kick back & realx',false);
// Adding my premade todo's into my Array that has the variable 'allTheToDos'
allTheToDos.push(firstTask);
allTheToDos.push(secondTask);
allTheToDos.push(thirdTask);
// creating a function so that the user can add a new todo
let addButton = document.getElementById('addBtn');
addButton.addEventListener('click',addNewTask);
generateHtml ();
// let checkedLi = document.getElementById('listItem')
// checkedLi.addEventListener('click',)
console.log(allTheToDos);
}
// my puublic
let p=0;
let allTheToDos = [];
class Todo{
constructor(toDoItem, removedToDo){
this.Id= p ++;
this.toDoItem = toDoItem;
this.removedToDo = removedToDo;
}
}
function generateHtml (){
// Creating an Ul for my items
let section = document.getElementById('mySection');
let myUl = document.createElement('ul');
myUl.className = 'listContainer';
section.appendChild(myUl);
// Creating the loop for my premade todo objects
for(i=0; i<allTheToDos.length; i++){
// Create a div wrapper for my li
let myListWrapperItemContainer = document.createElement('div');
myListWrapperItemContainer.className = "listItemsWrapper";
let id = `to_do_${i}`;
myListWrapperItemContainer.id = id;
// Creating Checked button
let checkedIcon = document.createElement('label');
checkedIcon.className = 'checkedIcon listItemsIcon';
checkedIcon.innerHTML = '<i class="fas fa-check"></i>';
//Creating li
let myLi = document.createElement("li");
myLi.classList = "listItem lineTrough";
myLi.id= "listItem";
// Creating delete button
let deleteButton = document.createElement('button');
deleteButton.id ="deleteButton";
deleteButton.className = 'trashCan listItemsIcon';
deleteButton.innerHTML = '<i class="fas fa-trash-alt"></i>';
// OnClick
deleteButton.addEventListener('click', () => {removeTask(id)});
// Adding everything to my html
myListWrapperItemContainer.appendChild(checkedIcon);
myListWrapperItemContainer.appendChild(myLi);
myListWrapperItemContainer.appendChild(deleteButton);
myLi.innerHTML = allTheToDos[i].toDoItem;
myUl.appendChild(myListWrapperItemContainer);
}
}
function addNewTask (stopRefresh){
stopRefresh.preventDefault();
let liContainer = document.getElementById ("mySection");
let inputValue = document.getElementById('textBox').value;
liContainer.innerHTML="";
if (inputValue == ""){
alert("Type in something");
generateHtml();
}
else{
let newInputValue = new Todo (inputValue);
allTheToDos.push(newInputValue);
generateHtml();
}
}
function removeTask (id){
let element = document.getElementById(id);
let index = allTheToDos.findIndex(e => e.toDoItem === element.textContent);
allTheToDos.splice(index,1);
element.parentNode.removeChild(element);
}
Currently I have a delete function already which is shown by a cross
So how I am doing this is by using a function that renders in the information from another database, into this list.
function renderCafe(doc){
let li = document.createElement('li');
let name = document.createElement('span');
let city = document.createElement('span');
let cross = document.createElement('div');
li.setAttribute('data-id', doc.id);
name.textContent = doc.data().name;
city.textContent = doc.data().city;
cross.textContent = 'x';
li.appendChild(name);
li.appendChild(city);
li.appendChild(cross);
cafeList.appendChild(li);
// deleting data
cross.addEventListener('click', (e) => {
e.stopPropagation();
let id = e.target.parentElement.getAttribute('data-id');
db.collection('cafes').doc(id).delete();
});}
So how do I create the edit button function like this delete one? Should it also be an EventListener that occurs when clicked?
I was thinking to have an edit button, when clicked, changes into "Update", while the static information turns into a text box with the current values.
Then when the "Update" is being clicked, it then saves the information.
I am a student, and have no prior knowledge in javascript, i took these codes from tutorials that I can find online.
Here's a possible solution, similar to your style.
Replace the alert with a database update.
Make sure you're listening for document changes, and updating your UI accordingly, so that the new name and city will replace your old ones.
const cafeList = document.getElementById('cafe-list');
const sampleCafes = [
{ data: () => ({ name: 'new cafe', city: 'new city'}), id: 'sample-cafe' },
];
sampleCafes.forEach(cafe => renderCafe(cafe));
function renderCafe(doc){
let li = document.createElement('li');
let name = document.createElement('p');
let city = document.createElement('p');
let nameInput = document.createElement('input');
let cityInput = document.createElement('input');
let edit = document.createElement('div');
let submit = document.createElement('div');
let cross = document.createElement('div');
li.setAttribute('data-id', doc.id);
name.textContent = doc.data().name;
city.textContent = doc.data().city;
nameInput.value = name.textContent;
cityInput.value = city.textContent;
nameInput.hidden = true;
cityInput.hidden = true;
edit.textContent = 'edit';
submit.textContent = 'submit';
submit.hidden = true;
cross.textContent = 'x';
li.appendChild(name);
li.appendChild(city);
li.appendChild(nameInput);
li.appendChild(cityInput);
li.appendChild(edit);
li.appendChild(submit);
li.appendChild(cross);
cafeList.appendChild(li);
// deleting data
cross.addEventListener('click', (e) => {
e.stopPropagation();
let id = e.target.parentElement.getAttribute('data-id');
alert(`db.collection('cafes').doc(id).delete();`);
});
// editing data
edit.addEventListener('click', (e) => {
e.stopPropagation();
nameInput.hidden = false;
cityInput.hidden = false;
submit.hidden = false;
name.hidden = true;
city.hidden = true;
edit.hidden = true;
});
// submitting new data
submit.addEventListener('click', (e) => {
e.stopPropagation();
const id = e.target.parentElement.getAttribute('data-id');
nameInput.hidden = true;
cityInput.hidden = true;
submit.hidden = true;
name.hidden = false;
city.hidden = false;
edit.hidden = false;
const newName = nameInput.value;
const newCity = cityInput.value;
alert(`TODO: update doc '${id}' to\n{name: '${newName}', city: '${newCity}'}.`);
});
}
<ul id="cafe-list"></ul>
I'm very new to coding so I'm not sure if you get the whole picture with this much, but I can clarify more if this isn't sufficient. Greatly appreciate any help. Thank you!
//remove and complete svg format
var removeSVG = '<svg></svg>';
var completeSVG = '<svg></svg>';
//user clicked on the add button
//If there is any text in the input field add that to the Todo list
document.getElementById('add').addEventListener('click', function () {
var value = document.getElementById('item').value;
if (value) {
addItemTodo(value);
document.getElementById('item').value = "";
}
});
function deleteItem() {
var item = this.parentNode.parentNode;
var parent = this.parentNode;
parent.removeChild(item);
}
function completeItem() {
var item = this.parentNode.parentNode;
var parent = this.parentNode;
var id = parent.id;
var target = (id === 'todo') ? document.getElementById('completed') : document.getElementById('todo');
parent.removeChild(item);
target.insertBefore(item, target.childNodes[0]);
}
//Adds a new item to the todo list
function addItemTodo(text) {
var list = document.getElementById('todo');
var item = document.createElement('li');
item.innerText = text;
var buttons = document.createElement('div');
buttons.classList.add('buttons');
var remove = document.createElement('button');
remove.classList.add('remove');
remove.innerHTML = removeSVG;
//add click event for remove button
remove.addEventListener('click', deleteItem);
var complete = document.createElement('button');
complete.classList.add('complete');
complete.innerHTML = completeSVG;
//add click event for the complete button
complete.addEventListener('click', completeItem);
buttons.appendChild(remove);
buttons.appendChild(complete);
item.appendChild(buttons);
list.insertBefore(item, list.childNodes[0]);
}
//add click event for remove button
remove.addEventListener('click', deleteItem);
So I posted the whole javascript, so you get an idea of the structure, The html itself is just two tags with id=todo and completed respectively
check this https://jsfiddle.net/dp722j27/
function deleteItem() {
var parent = this.parentNode.parentNode.parentNode;
var item = this.parentNode.parentNode;
parent.removeChild(item);
}
If you want to delete button, that was clicked, do like this:
function deleteItem(event) {
var item = event.target.parentNode;
var parent = event.target.parentNode.parentNode;
parent.removeChild(item);
}
//add click event for remove button
document.addEventListener('click', deleteItem);
When adding a new item to the list i would like it to change color based on the input value.
How do i add the input.value to my new appended li item?
I have created a codepen if anyone would be able to help
http://codepen.io/o-sewell/pen/mOBjvQ
// DIV TOGGLE
const toggleButton = document.querySelector('#toggleList');
const listDiv = document.querySelector('.list');
// User INPUT
const userInput = document.querySelector('.userInput');
const button = document.querySelector('button.description');
const p = document.querySelector('p.description');
let listItem = document.querySelectorAll('li');
// ADD ITEM
const addItemInput = document.querySelector('.addItemInput');
const addItemButton = document.querySelector('button.addItemButton');
button.addEventListener('click', () => {
for (let i = 0; i < listItem.length; i++) {
listItem[i].style.color = userInput.value;
}
p.innerHTML = userInput.value + ':';
});
toggleButton.addEventListener('click', () => {
if (listDiv.style.display == 'none') {
listDiv.style.display = 'block';
toggleButton.textContent = 'Hide list';
} else {
listDiv.style.display = 'none';
toggleButton.textContent = 'Show list';
}
});
addItemButton.addEventListener('click', () => {
let list = document.querySelector('ul');
let li = document.createElement('li');
li.textContent = addItemInput.value;
let appendedItem = list.appendChild(li);
console.log(appendedItem);
for (let i = 0; i < appendedItem.length; i++) {
appendedItem[i].style.color = userInput.value;
}
console.log(appended item);
addItemInput.value = '';
});
Here is the new one :
//DIV TOGGLE
const toggleButton = document.querySelector('#toggleList');
const listDiv = document.querySelector('.list');
var lastPickedColor = "black"; // it will store the last picked color
//User INPUT
const userInput = document.querySelector('.userInput');
const button = document.querySelector('button.description');
const p = document.querySelector('p.description');
let listItem = document.querySelectorAll('li');
//ADD ITEM
const addItemInput = document.querySelector('.addItemInput');
const addItemButton = document.querySelector('button.addItemButton');
button.addEventListener('click', () => {
lastPickedColor = userInput.value;
for(let i = 0; i < listItem.length; i++) {
listItem[i].style.color = lastPickedColor;
}
p.innerHTML = userInput.value + ':';
});
toggleButton.addEventListener('click', () => {
if (listDiv.style.display == 'none') {
listDiv.style.display = 'block';
toggleButton.textContent = 'Hide list';
} else {
listDiv.style.display = 'none';
toggleButton.textContent = 'Show list';
}
});
addItemButton.addEventListener('click', () => {
let list = document.querySelector('ul');
let li = document.createElement('li');
li.style.color = lastPickedColor; // so it will add li with last picked color
li.textContent = addItemInput.value;
let appendedItem = list.appendChild(li);
console.log(appendedItem);
for(let i = 0; i < appendedItem.length; i++) {
appendedItem[i].style.color = userInput.value;
}
console.log(appendeditem);
addItemInput.value = '';
});
I added lastPickedColor variable to top of the page whenever you change the color, it will store the lastPickedColor and all list add with this color.
The answer is quite simple.
You're defining the initial list when the js is executed, but the new element is created dynamically. Therefore, you'll have to create a new nodelist based on all elements, including the new one. You can simply redefine it inside the current click event:
button.addEventListener('click', () => {
listItem = document.querySelectorAll('li');
for(let i = 0; i < listItem.length; i++) {
listItem[i].style.color = userInput.value;
}
p.innerHTML = userInput.value + ':';
});
To give it the same color as the existing ones, change this function to apply the styling directly on the latest added element:
addItemButton.addEventListener('click', () => {
let list = document.querySelector('ul');
let li = document.createElement('li');
li.textContent = addItemInput.value;
let appendedItem = list.appendChild(li);
appendedItem.style.color = userInput.value;
addItemInput.value = '';
});
Working codepen example
so I have made 2 changes for your code to work. Please see
http://codepen.io/amoolya/pen/GNMXqa?editors=1111
First change
addItemButton.addEventListener('click', () => {
let list = document.querySelector('ul');
let li = document.createElement('li');
li.textContent = addItemInput.value;
let appendedItem = list.appendChild(li);
appendedItem.style.color = list.firstElementChild.style.color; //The newly appended item is given the color of the first list element. In your case, this would be whatever color the user chose last.
});
Second Change:
I added
document.querySelectorAll('li');
inside your event handler for the color change button so that each time, the length of the new list is calculated.
iam making a to do list app just using javascript... in which you can add tasks edit them and delete.but my edit task function is working for the list items with which are there in html document before dom manipulation but after i add new elements it doesn't work for newly appended elements
//Problem: User interaction doesn't provide desired results.
//Solution: Add interactivty so the user can manage daily tasks.
var taskInput = document.getElementById('new-task'); //new-task
var addButton = document.getElementsByTagName('button')[0]; //first button
var incompleteTasksHolder = document.getElementById('incomplete-tasks'); //incompleteTasks
var completedTasksHolder = document.getElementById('completed-tasks'); //completedTasks
//new task list item
var createNewTaskElement = function(taskString){
//create listItem
var listItem = document.createElement('li');
//input(checkbox)
var checkBox = document.createElement('input');
//label
var label = document.createElement('label');
//input(text)
var editInput = document.createElement('input');
//button.edit
var editButton = document.createElement('button');
//button.delete
var deleteButton = document.createElement('button');
//Each element needs modifying
checkBox.type = 'checkbox';
editInput.type = 'text';
editButton.innerText = 'edit';
editButton.className = 'edit';
deleteButton.innerText = 'delete';
deleteButton.className = 'delete';
label.innerText = taskString;
//Each elements needs appended
listItem.appendChild(checkBox);
listItem.appendChild(label);
listItem.appendChild(editInput);
listItem.appendChild(editButton);
listItem.appendChild(deleteButton);
return listItem;
}
//Add a new task
var addTask = function(){
//Create a new list item with the text from #new-task:
var listItem = createNewTaskElement(taskInput.value);
//append listItems to incomplete tasks holder
incompleteTasksHolder.appendChild(listItem);
}
//Edit an existing task
var editTask = function(){
console.log('the edit task function is running');
var listItem = this.parentNode;
var editInput = listItem.querySelector('input[type="text"]');
var label = listItem.querySelector('label');
var containsClass = listItem.classList.contains('editMode');
//if the class of the parent is .editMode
if(containsClass){
//Switch from .editMode
//label text become the input's value
label.innerText = editInput.value;
}else{
//Switch to .editMode
//input value becomes the label's text
editInput.value = label.innerText;
}
//Toggle .editMode on the listItem
listItem.classList.toggle('editMode');
}
//Delete an existing task
var deleteTask = function(){
var listItem = this.parentNode;
var ul = listItem.parentNode;
//Remove the parent list item from the ul
ul.removeChild(listItem);
}
//Mark a task as complete
var taskCompleted = function() {
console.log("Task complete...");
//Append the task list item to the #completed-tasks
var listItem = this.parentNode;
completedTasksHolder.appendChild(listItem);
bindTaskEvents(listItem,taskIncomplete);
}
//Mark a task as incomplete
var taskIncomplete = function(){
//Append the task list item to the #incomplete-tasks
var listItem = this.parentNode;
incompleteTasksHolder.appendChild(listItem);
bindTaskEvents(listItem,taskCompleted);
}
//Set the click handler to the addTask function
addButton.addEventListener("click", addTask);
var bindTaskEvents = function(taskListItem, checkBoxEventHandler) {
console.log("Bind list item events");
//select taskListItem's children
var checkBox = taskListItem.querySelector("input[type=checkbox]");
var editButton = taskListItem.querySelector("button.edit");
var deleteButton = taskListItem.querySelector("button.delete");
//bind editTask to edit button
editButton.onclick = editTask;
//bind deleteTask to delete button
deleteButton.onclick = deleteTask;
//bind checkBoxEventHandler to checkbox
checkBox.onchange = checkBoxEventHandler;
}
//cycle over incompletetaskHolder ul list items
for(var i = 0; i < incompleteTasksHolder.children.length; i++){
//bind events to list's item children(taskCompleted)
bindTaskEvents(incompleteTasksHolder.children[i], taskCompleted);
}
//cycle over completedTasksHolder ul list items
for(var i = 0; i < completedTasksHolder.children.length; i++){
//bind events to list item's children (taskIncomplete)
bindTaskEvents(completedTasksHolder.children[i], taskIncomplete);
}
An event cannot be attached to an undefined Element. Solution: attach events after definition.