How to delete a single item when button has clicked in Javascript? - javascript

I'm working on a to-do list project and stuck at this part where when a trash button is clicked all the list items will be deleted and it won't add any new to-do items.
I've checked other posts but couldn't really find the answer for my project, please help!
let input = document.querySelector('#todo')
let btn = document.querySelector('#btn');
let list = document.querySelector('#list');
btn.addEventListener('click', () => {
let txt = input.value;
if (txt === "") {
alert('Please write something to do!');
} else {
let li = document.createElement('li');
li.innerHTML = txt;
list.insertBefore(li, list.childNodes[0]);
input.value = '';
const delBtn = document.createElement("i");
delBtn.classList.add("fas", "fa-trash-alt");
li.appendChild(delBtn);
delBtn.addEventListener('click', e => {
list.parentNode.removeChild(list);
})
}
})
list.addEventListener('click', e => {
if(e.target.tagName == 'LI') {
e.target.classList.toggle('checked');
}
})
<div class="todoList">
<h1>To-do List</h1>
<div class="add-element">
<input type="text" id="todo" placeholder="Add new to-do">
<button id="btn">Add</button>
</div>
<div class="element-list">
<ul id="list"></ul>
</div>
</div>

list.parentNode.removeChild(list); deletes all the list, if you want to delete only one element from the list, add a button to every li and change this line to li.parentNode.removeChild(li); like this:
let input = document.querySelector('#todo')
let btn = document.querySelector('#btn');
let list = document.querySelector('#list');
btn.addEventListener('click', () => {
let txt = input.value;
if (txt === "") {
alert('Please write something to do!');
} else {
let li = document.createElement('li');
li.innerHTML = txt;
list.insertBefore(li, list.childNodes[0]);
input.value = '';
const delBtn = document.createElement("i");
li.appendChild(delBtn);
delBtn.addEventListener('click', e => {
li.parentNode.removeChild(li);
})
}
})
list.addEventListener('click', e => {
if(e.target.tagName == 'LI') {
e.target.classList.toggle('checked');
}
})
<div class="todoList">
<h1>To-do List</h1>
<div class="add-element">
<input type="text" id="todo" placeholder="Add new to-do">
<button id="btn">Add</button>
</div>
<div class="element-list">
<ul id="list"></ul>
</div>
</div>

Related

JavaScript - Comments duplicating on another div

I am creating a comment box and I managed to append whatever I type to a div I wanted, however I have added another input and trying to append that along with the comments, however when I do this the second time,it appends both the previous and current comment therefore the previous comment duplicates. I know I'm doing something wrong in my display_commnents function, however I'm not entirely sure what it could be, basically I just want whatever is entered on both title and comments to append on the comment-box with title on top and comment just below. Below is my code:
<div class="container">
<h1>Write New Post</h1>
<form>
<input id="title" type="text" placeholder="Title" value="">
<textarea id="" placeholder="Leave us a comment" value=""></textarea>
<input id="giphy" type="text">
<div class="btn">
<input id="submit" type="submit" value="comment">
<button id="clear">Cancel</button>
</div>
</form>
</div>
<div class="comments">
<h2>Comments</h2>
<div id="comment-box" value="submit">
</div>
</div>
And this is my JS code:
const title = document.querySelector('#title')
const field = document.querySelector('textarea');
const textBackUp = title.getAttribute('placeholder')
const backUp = field.getAttribute('placeholder')
const btn = document.querySelector('.btn');
const clear = document.getElementById('clear')
const submit = document.querySelector('#submit')
// const comments = document.querySelector('#comment-box')
const titleText = document.getElementById('title')
const comments = document.getElementById('comment-box')
let title_arr = [];
let comments_arr = [];
title.onfocus = function(){
this.setAttribute('placeholder', '')
}
title.onblur = function(){
this.setAttribute('placeholder', textBackUp)
}
field.onfocus = function(){
this.setAttribute('placeholder','')
this.style.borderColor = '#333'
btn.style.display = 'block'
} // when clicking on this, placeholder changes into ' ', border colour changes and buttons will appear.
field.onblur = function(){
this.setAttribute('placeholder',backUp)
} //click away, placeholder returns
const display_comments = () => {
let list = '<ul>'
title_arr.forEach(title => {
comments_arr.forEach(comment => {
list += `<li>${title} <br>${comment}`
})
})
list += '</ul>'
comments.innerHTML = list
}
clear.onclick = function(e){
e.preventDefault();
btn.style.display = 'none'
title.value = ''
field.value = ''
display_comments()
}
submit.onclick = function(e){
e.preventDefault();
const head = title.value;
const content = field.value;
if(head.length > 0){
title_arr.push(head)
display_comments();
title.value = '';
}
if(content.length > 0){
comments_arr.push(content)
display_comments();
field.value = '';
}
}
any help would be appreciated
The problem is that you have a double nested loop, producing a Cartesion product of the all the introduced titles and the comments.
To solve this, use only one array for collecting the input, so that title and comment are always kept together in one array entry. Such an entry can be an object with two properties, one for the title, and one for the comment.
Here is your code adapted, just for fixing that issue:
const title = document.querySelector('#title')
const field = document.querySelector('textarea');
const textBackUp = title.getAttribute('placeholder')
const backUp = field.getAttribute('placeholder')
const btn = document.querySelector('.btn');
const clear = document.getElementById('clear')
const submit = document.querySelector('#submit')
// const comments = document.querySelector('#comment-box')
const titleText = document.getElementById('title')
const comments = document.getElementById('comment-box')
let arr = []; // Only one array
title.onfocus = function(){
this.setAttribute('placeholder', '');
}
title.onblur = function(){
this.setAttribute('placeholder', textBackUp);
}
field.onfocus = function(){
this.setAttribute('placeholder','');
this.style.borderColor = '#333';
btn.style.display = 'block';
}
field.onblur = function(){
this.setAttribute('placeholder', backUp);
}
const display_comments = () => {
let list = '<ul>';
// Only one loop -- over objects with two properties
arr.forEach(({head, content}) => {
list += `<li><b>${head}</b><br>${content}`;
})
list += '</ul>';
comments.innerHTML = list;
}
clear.onclick = function(e){
e.preventDefault();
btn.style.display = 'none';
title.value = '';
field.value = '';
display_comments();
}
submit.onclick = function(e){
e.preventDefault();
const head = title.value;
const content = field.value;
// Only one if-block
if(head.length > 0 || content.length > 0){
arr.push({head, content}); // Only one push -- of an object
display_comments();
title.value = '';
field.value = '';
}
}
<div class="container">
<h1>Write New Post</h1>
<form>
<input id="title" type="text" placeholder="Title" value="">
<textarea id="" placeholder="Leave us a comment" value=""></textarea>
<div class="btn">
<input id="submit" type="submit" value="comment">
<button id="clear">Cancel</button>
</div>
</form>
</div>
<div class="comments">
<h2>Comments</h2>
<div id="comment-box" value="submit">
</div>
</div>

If event.target.value is empty then not appendChild into ul, how to solve it?

HTML and Javascript
I would like to create element and remove those I did it But when input field is empty the blank Li display after hit enter. I don't want to display when input field blank. How can I do this?
Codepen Link https://codepen.io/afsar-uddin/pen/abBBQbo
<div class="container">
<div class="list_itme">
<input type="text" id="nameField" placeholder="Write something and hit enter..." >
<ul id="nameList"></ul>
</div>
</div>
let nameField = document.querySelector('#nameField')
let ul = document.querySelector('#nameList')
nameField.addEventListener('keypress', function(event){
if(event.keyCode === 13) {
let name = event.target.value
createLi(ul, name)
event.target.value = ''
}
})
function createLi(ul, name) {
let listItem = document.createElement('li')
listItem.innerHTML = name
let span = document.createElement('span')
span.innerHTML = 'X'
listItem.appendChild(span)
span.className = 'right'
span.addEventListener('click', function(){
ul.removeChild(listItem)
})
ul.appendChild(listItem)
}
Add if(name.length === 0) return;
function createLi(ul, name) {
if(name.length === 0) return;
let listItem = document.createElement('li')
listItem.innerHTML = name
let span = document.createElement('span')
span.innerHTML = 'X'
listItem.appendChild(span)
span.className = 'right'
span.addEventListener('click', function(){
ul.removeChild(listItem)
})
ul.appendChild(listItem)
}

Why I cannot add new note after editing created one?

I cannot add new Note after editing. How can I exit from the cycle?
This is a part where I create a new note
const createNote = () => {
if (button.className === "button") {
const div = document.createElement("div");
div.setAttribute("class", "note");
div.textContent = input.value;
field.appendChild(div);
const btn = document.createElement("button");
btn.setAttribute("class", "edit");
btn.textContent = "Edit";
div.appendChild(btn);
const del = document.createElement("button");
del.setAttribute("class", "del");
del.textContent = "Delete";
div.appendChild(del);
console.log("Note has been created");
input.value = "";
}
Here is a part where I want to edit created Note but also I want to create a new one (this part is inside function createNote)
const edit = document.querySelectorAll(".edit");
for (let i of edit) {
i.onclick = () => {
input.value = i.previousSibling.nodeValue;
button.innerText = "Edit";
button.classList.add("editable");
/*button.classList.remove("button");*/
if (button.className === "button editable") {
button.onclick = () => {
i.previousSibling.nodeValue = input.value;
input.value = "";
button.classList.remove("editable");
button.classList.add("button");
button.innerText = "Add";
};
}
};
}
};
button.onclick = createNote;
Here is HTML that I am using
<body>
<div class="container">
<div class="insert">
<input type="text" name="Note" id="noteId" placeholder="add note">
<button class="button">Add</button>
</div>
<div class="field">
<div class="note">Test note
<button class="edit">Edit</button>
<button class="del">Delete</button>
</div>
</div>
</div>
<script src="js/index.js"></script>
</body>

Cannot remove list item from ul todo list

I tried to remove the list item inside ul with querySelectorAll and remove going through each li element. Where is the mistake please, and how is it fixed?
<div class='container'>
<h1> New todo list</h1>
<form>
<input type= 'text' id='item'
required>
<ul> </ul>
<button id='button'> clear all</
button>
</div>
Here's the code:
var form =
document.querySelector('form')
var ul = document.querySelector('ul')
var button =
document.querySelector(#button)
var input =
document.querySelector('item')
var liMaker = text => {
var li =
document.createElement('li')
li.textContent = text
ul.insertBefore(li,
ul.childNodes[0])
button.onclick = remove
}
form.addEventListener('submit',
function(e){
e.preventDefault()
liMaker(input.value)
input.value = ' '
})
function remove(e){
Array.from(
document.querySelectorAll('
li')).forEach(item =>
e.target.item.remove())
}
I have edited your code a little and added a new button to keep the functionality separate. I think this is the kind of functionality you were after if I understood your question correctly.
<div class='container'>
<h1> New todo list</h1>
<form>
<input type='text' id='item' required>
<ul id="myList"></ul>
<button id='button'>add</button>
</form>
<button id="clear">Clear</button>
</div>
JS:
var form = document.querySelector('form')
var ul = document.querySelector('ul')
var button = document.querySelector('#button');
var input = document.querySelector('#item');
var clear = document.querySelector('#clear');
var liMaker = text => {
var li = document.createElement('li');
li.textContent = text;
ul.insertBefore(li, ul.childNodes[0])
}
form.addEventListener('submit', function(e) {
e.preventDefault()
liMaker(input.value)
input.value = '';
});
clear.addEventListener('click', remove);
function remove(){
saveToDos();
while (ul.firstChild) {
ul.removeChild(ul.firstChild);
}
}
function saveToDos() {
var items = ul.getElementsByTagName("li");
for (var i = 0; i < items.length; ++i) {
savedToDos.push(items[i].innerHTML);
}
localStorage.setItem('savedValues', savedToDos);
}
Here is a link to a working pen: https://codepen.io/caeking/pen/RzyKmV

Moving items to different lists with DOM Manipulation JS

I'm creating something like GMAIL functionality with JavaScript ES5 ( I use only const and let, that's it, rest ES5).
So I manage to create the list functionality, all works except that when I select the items and move them to a different list, they lose any functionality, and I can't do anything with them.
I believe I need to use querySelectorAll to get all the lists, but that doesn't work. Not sure what should I do here.
I think I need to select all the lists, and then loop them to add interactivity.
CodePen: https://codepen.io/Aurelian/pen/dJryrX?editors=1010
JS:
window.onload = function() {
//////////////////////////////////
// VARIABLES
//////////////////////////////////
// Form
const form = document.querySelector('#registrar');
const input = form.querySelector('input');
// Lists
const partyList = document.querySelector('.party-lists');
const partyInvitedList = document.querySelector('#list-invited')
const partyGoingList = document.querySelector('#list-going');
const partyNotSure = document.querySelector('#list-not-sure');
const partyNotGoing = document.querySelector('#list-not-going');
// List Options
const listOptions = document.querySelector('.list-options');
const btnMoveToGoing = document.querySelector('.btnMoveGoing');
const btnMoveToNotSure = document.querySelector('.btnMoveNotSure');
const btnMoveToNotGoing = document.querySelector('.btnMoveNotGoing');
const btnDeleteSelected = document.querySelector('.btnDeleteSelected');
//////////////////////////////////
// FUNCTIONS
//////////////////////////////////
function createLI(text) {
const li = document.createElement('li');
const span = document.createElement('span');
span.textContent = text;
li.appendChild(span);
const label = document.createElement('label');
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
label.appendChild(checkbox);
li.appendChild(label);
const editButton = document.createElement('button');
editButton.textContent = 'edit';
li.appendChild(editButton);
const removeButton = document.createElement('button');
removeButton.textContent = 'remove';
li.appendChild(removeButton);
return li;
}
//////////////////////////////////
// EVENT HANDLERS
//////////////////////////////////
form.addEventListener('submit', function(e) {
e.preventDefault();
const text = input.value;
input.value = '';
const li = createLI(text);
partyInvitedList.appendChild(li);
});
partyList.addEventListener('click', function(e) {
if (e.target.tagName === 'BUTTON') {
const button = e.target;
const li = button.parentNode;
const ul = li.parentNode;
if (button.textContent === 'remove') {
ul.removeChild(li);
} else if (button.textContent === 'edit') {
const span = li.firstElementChild;
const input = document.createElement('input');
input.type = 'text';
input.value = span.textContent;
li.insertBefore(input, span);
li.removeChild(span);
button.textContent = 'save';
} else if (button.textContent === 'save') {
const input = li.firstElementChild;
const span = document.createElement('span');
span.textContent = input.value;
li.insertBefore(span, input);
li.removeChild(input);
button.textContent = 'edit';
}
}
});
listOptions.addEventListener('click', function(e) {
partyList.querySelectorAll('*:checked').forEach(function (listItems) {
const button = e.target;
var items = listItems.parentNode.parentNode;
if(button.className === 'btnMoveGoing') {
partyGoingList.appendChild(items);
items.checked = false;
var item = listItems;
item.checked = false;
} else if(button.className === 'btnMoveNotSure'){
partyNotSure.appendChild(items);
var item = listItems;
item.checked = false;
} else if(button.className === 'btnMoveNotGoing'){
partyNotGoing.appendChild(items);
var item = listItems;
item.checked = false;
} else if(button.className === 'btnDeleteSelected'){
listItems.parentNode.parentNode.remove();
var item = listItems;
item.checked = false;
}
});
});
}
HTML:
<div class="top">
<form id="registrar">
<input type="text" name="name" placeholder="Invite Someone">
<button type="submit" name="submit" value="submit">Submit</button>
</form>
<div class="list-options">
<button class="btnMoveGoing">Move to Going</button>
<button class="btnMoveNotSure">Move to Not Sure</button>
<button class="btnMoveNotGoing">Move to Not Going</button>
<button class="btnDeleteSelected">Delete Selected</button>
</div>
</div><!-- /top -->
<div class="col">
<h3>Invited</h3>
<ul id="list-invited" class="party-lists">
</ul>
</div>
<div class="col">
<h3>Going</h3>
<ul id="list-going" class="party-lists">
</ul>
</div>
<div class="col">
<h3>Not Sure</h3>
<ul id="list-not-sure" class="party-lists">
</ul>
</div>
<div class="col">
<h3>Not Going</h3>
<ul id="list-not-going" class="party-lists">
</ul>
</div>

Categories

Resources