Appended item is instantly removed - javascript

I am trying to understand the basics of eventListeners, i have created a simple form where i just want to add a value of an input to a UL, however when i append the value, i am able to see it in the list for a brief second and then it is instantly removed, i cannot figure out why, could anyone help?.
const submitButton = document.querySelector('#add-task-btn');
const clearButton = document.querySelector('#remove-task-btn');
const item = document.querySelector('#task');
const taskList = document.querySelector('.collection');
allEventListeners();
function allEventListeners(){
submitButton.addEventListener('click', function(){
if (item.value === ''){
alert('Please add a task')
};
const li = document.createElement('li');
li.appendChild(document.createTextNode(item.value));
taskList.appendChild(li);
item.value = "";
})
}

You just need to provide an event parameter for your handler function and then call preventDefault()
submitButton.addEventListener('click', function(ev){
ev.preventDefault(); // prevent the page submit
//...
});

Related

I need help giving function to my edit button when clicked to edit the shopping list item, then saving changes

after searching, I don't know where to start to give edit button functionality so the code that I did try, I've already deleted. My delete button is fully functional by the way. I thought an if else statement would work but I yielded no results.
// submit event
type here
//create form
const form = document["addItem"]
const div = document.querySelector('#todos')
const ul = document.querySelector('#list');
form.addEventListener("submit", (e) => {
e.preventDefault();
// addItem event handler for submit event on submit
const typedInput = document.getElementById("title").value
console.log(typedInput)
const list = document.getElementById("list")
document.addEventListener("click", addItem);
// created elements and appended to list to display on the website
const div = document.createElement("div")
const ul = document.createElement("list");
const li = document.createElement("li");
div.appendChild(document.createTextNode(typedInput));
ul.appendChild(li);
li.appendChild(div);
// added button to represent the edit button when clicked
const button = document.createElement("button");
button.name = "edit";
li.appendChild(button).textContent = "edit"
// added newButton to store delete button, appended to the parentElement to remove the list item
//after submission
const newButton = document.createElement("button");
newButton.name = "removeItem";
li.appendChild(newButton).textContent = "X"
document.getElementById('list').appendChild(li);
newButton.addEventListener("click", function(){
this.parentNode.remove();
})
})

Javascript - Issue on event listeners of classList

I have a "+" button that , when clicked, triggers the creation of a block with an input and 2 buttons, one for validating the input and one for removing it.
// My code looks almost like this :
addBtn.addEventListener('click', e => {
addClick++;
// All the elements of the same line (input and 2 buttons) have an int in common in their id string ==> addClick
// I'm missing all the declarations of the variables here
blockDiv.appendChild(posteInput);
blockDiv.appendChild(validateBtn);
blockDiv.appendChild(deleteBtn);
globalPostesBlock.appendChild(blockDiv)
let allDeleteBtn = document.getElementsByClassName('delete-button');
for (let i = 0; i < allDeleteBtn.length; i++) {
allDeleteBtn[i].addEventListener('click', e => {
// Retrieving the block with the same id
let deleteBtnId = parseInt((allDeleteBtn[i].getAttribute('id').match(/\d+/g)).toString());
let singlePosteBlock = document.getElementById(`poste-block-${deleteBtnId}`);
singlePosteBlock.remove();
}
})
}
The event listener represents the action of clicking the delete button so it can remove its entire containing block
I have the same logic for the validate button, but I'm using ajax in it.
Each time I create a new block, I want to create an event listener associated to this block, but all I found so far is an event listener with a loop on every buttons, so what happens is that the action triggers as many time as the block numbers because of the loop, but I don't know how to dissociate every event listeners.
If I have 3 blocks and I validate one input value which is being inserted in the DB afterwards, the value is being inserted 3 times.
Does this help ?
//id pool
let latestId = 0;
//retrive the button
var myButton = document.querySelector("button");
myButton.addEventListener("click", createKids);
//function declaration :: createKids
function createKids() {
latestId++;
//declare and initialization
let div = document.createElement("div");
let input = document.createElement("input");
let buttonSend = document.createElement("button");
let buttonDelete = document.createElement("button");
//append input & buttons to div
div.appendChild(input);
div.appendChild(buttonSend);
div.appendChild(buttonDelete);
//Some beautifying
buttonSend.innerText = "Send me";
buttonDelete.innerText = "Delete me";
//some logic
div.dataset.id = latestId;
//event handeling
buttonSend.addEventListener("click", sendItem);
buttonDelete.addEventListener("click", deleteItem);
//insert div
document.body.appendChild(div);
}
function sendItem(event) {
//do action and delete ?
let input = event.target.parentNode.querySelector("input");
//retrive data
let val = input.value;
let id = event.target.parentNode.dataset.id;
//disable input for fun ^^
input.disabled = true;
//console istead of send
console.log(id,val);
//handle some more
setTimeout(() => {
event.target.parentNode.remove();
}, 3000);
}
function deleteItem(event) {
event.currentTarget.parentNode.remove();
}
<p>Does this help?</p>
<button>Magic Button</button>

Facing problem in JavaScript function execution

I am trying to make a simple Shopping List App in which user can Add, Delete and mark the task done when completed. So far, I am able to add the task but facing problem in executing the done and delete functions. I am getting an error because when I execute it, the done and delete buttons are not there but what should I do to fix it?
var inp = document.getElementById("form");
var button = document.getElementById("click");
//Create List Function with Done and Delete Buttons
function addVal() {
var ul = document.getElementById("list");
var li = document.createElement("li");
var span = document.createElement("span");
var done = document.createElement("button");
var del = document.createElement("button");
li.appendChild(document.createTextNode(""));
span.appendChild(document.createTextNode(inp.value));
done.appendChild(document.createTextNode("Done"));
del.appendChild(document.createTextNode("Delete"));
li.appendChild(span);
li.appendChild(done);
li.appendChild(del);
done.setAttribute("class", "doneBut");
del.setAttribute("class", "delBut");
ul.appendChild(li);
inp.value = "";
}
//Get Input Length
function checkLength() {
return inp.value.length;
}
//Run function on Button Click
function onButtonClick() {
if (checkLength() > 0) {
addVal();
}
}
//Run function on Enter Keypress
function onEnter(event) {
if (checkLength() > 0 && event.which === 13) {
addVal();
}
}
//Trigger Events
button.addEventListener("click", onButtonClick);
inp.addEventListener("keypress", onEnter);
//Done and Delete Button Functions
var doneButton = document.getElementsByClassName("doneBut");
var deleteButton = document.getElementsByClassName("delBut");
function doneTask() {
doneButton.parentNode.classList.add("done");
}
function delTask() {
deleteButton.parentNode.classList.add("delete");
}
doneButton.addEventListener("click", doneTask);
deleteButton.addEventListener("click", delTask);
<input type="text" placeholder="Enter Your Task..." id="form" />
<button id="click">Add Task</button>
<h2>List:</h2>
<ul id="list"></ul>
Please Help.
Your problem is that the code tries to add events before the buttons exist. The buttons don’t exist until the addVal function gets called. Since addVal is not being called before the you try to add your event handlers, the getElementById returns null, and you attempt to add an event listener to null.
Additionally it looks like you’re planning to add multiple done and delete buttons. That wouldn’t normally be a problem, except you’re referencing them by ID, and IDs MUST be unique. You’ll need to switch this to a class or an attribute, since you’ll need one per item in the shopping cart.
You’ll probably want to look into event delegation, so that you can add your events once to the page before any buttons exist. https://javascript.info/event-delegation
It's most likely because your script is running before your code is running. Add the <script> tags just before the closing </body> tag to fix it:
<script>/* Your code here */</script>
</body>
You need to place this in a window.onload function, or run it in a function inside of the body tag's onload. Those elements don't exist yet when the script is run:
window.onload = function() {
var inp = document.getElementById("form");
var button = document.getElementById("click");
button.addEventListener("click", onButtonClick);
inp.addEventListener("keypress", onEnter);
}

How to specify the order of a focusout and a click event?

I have an input field with a JS focusout event. Under my input field, I have an autocomplete popup with suggestions. But when I click on a suggestion, it’s playing the focusout before the event listener on the click of the autocomplete! Any clues on how I can I fix this conflict?
Picture of the input and its autocompletion:
The click event:
resultsFrom.addEventListener('click', (event) => {
let e;
e = event.target.parentNode;
inputFrom.value = e.getAttribute('data-display');
});
The focusout event:
inputFrom.addEventListener('focusout', () => {
const list = document.querySelector('#results-from');
let first = list.firstChild;
inputFrom.value = first.getAttribute('data-display');
resultsFrom.innerHTML = '';
});
The focusout event has a property on the event object of relatedTarget - this is the element that's going to gain the focus, in this case, it will be the element you're clicking on.
You need to check if that element is within your results, and not clear them out if that's the case. Something like this:
inputFrom.addEventListener('focusout', (e) => {
const list = document.querySelector('#results-from');
if (!list.contains(e.relatedTarget)) {
//the target is not in the list, continue as before
//otherwise allow the click to function by not clearing out resultsFrom
let first = list.firstChild;
inputFrom.value = first.getAttribute('data-display');
resultsFrom.innerHTML = '';
}
});

delete button not working todo list DOM

I swear I scoured the forum for a solution, but I honestly just started learning Javascript a few days ago so I am not very good at deducing solutions from different code and using the logic on my own. Total noob I am.
I want my delete button to delete the item it is assigned to when clicked. I do not understand why my deleteMe() function doesn't do anything.
var button = document.getElementById("enter");
var input = document.getElementById("userinput");
var ul = document.querySelector("ul");
var listItem = document.querySelectorAll("li");
var dlt = document.getElementsByClassName(".delete")
function deleteMe() {
dlt.addEventListener("click", function() {
this.removeChild();
})
}
function delButton(parent) {
var del = document.createElement("button");
del.appendChild(document.createTextNode("Done!"));
parent.appendChild(del);
button.className = "delete";
}
function addToggle() {
this.classList.toggle("done");
}
function addEntry() {
if (input.value.length > 0 ) {
var newItem = document.createElement("li");
newItem.appendChild(document.createTextNode(input.value));
ul.appendChild(newItem);
input.value="";
newItem.addEventListener("click",addToggle);
delButton(newItem);
}
}
for ( var i = 0 ; i < listItem.length; i++) {
listItem[i].addEventListener("click", addToggle);
delButton( listItem[i]);
}
button.addEventListener("click", addEntry);
input.addEventListener("keypress", function() {
if ( event.keyCode === 13 ) {
addEntry()}
});
I would really really appreciate if someone could explain what I am doing wrong.
Thank you!
dlt is currently an HTMLCollection, not an element, so you can't add an event listener to it. Either select an element from it first (such as through iteration), or even better, assign the listener to the container, and have the listener check to see if the clicked target's className is delete. I would add the listener to the ul, just once, near the beginning of your script:
ul.addEventListener('click', (e) => {
// e.target represents the clicked element
if (e.target.className !== 'delete') return;
e.target.parentElement.remove();
});
If you wanted to assign a separate listener to each delete, you would have to add the listener inside delButton, like so:
function delButton(parent) {
var del = parent.appendChild(document.createElement("button"));
del.textContent = 'Done!';
button.className = "delete";
button.addEventListener('click', () => button.parentElement.remove());
}

Categories