Javascript How to delete element when button is clicked - javascript

I'm trying to make my basic to do list better and I want to be able to delete a task when a button is clicked. How can I go about doing this? I've given the button dynamic ID's but cant seem to find out how to return that specific ID when a specific button is clicked.
Javascript
let Task = [];
function addTask(){
//assign input to array
var task = document.getElementById("userInput").value;
Task.push(task);
//creates node and shows where to find value
let node = document.createElement("li");
let textNode = document.createTextNode(
document.getElementById("userInput").value
);
//create button for text node to delete
const btn = document.createElement('button');
btn.innerHTML = 'Delete';
//adds task to webpage
node.appendChild(textNode);
document.getElementById("myList").appendChild(node);
//Adds button to webpage, gives button dynamic ID
document.getElementById("myList").appendChild(btn).id = Task.length;
}

If I understand correctly what you want is to assign a dynamic ID and return that ID by clicking the button, correct?
In this case you can try something like:
// Adds button to webpage, gives button dynamic ID
document.getElementById("myList").appendChild(btn);
btn.setAttribute("id", "myCustomId");
document.getElementById("myList").appendChild(btn);
btn.setAttribute("onclick", "alert('Current button ID: '+this.id)");

Related

How to create an object of an <li> element?

I created a To-Do List with JS. I'm mostly finished but my last task is to create a local storage. The purpose of that is, that the Tasks should not vanish, when I reload the page. I know that I have to create an array of objects for that, but I don't know how to represent my <'li'> element as an object. So how do I represent my Tasks as an object to create an array
add.addEventListener("click", function (){
// create task text
if(task.value != ""){
let li = document.createElement('li');
ul.appendChild(li);
// create checkbox
let box = document.createElement('input');
box.setAttribute('type', 'checkbox');
li.appendChild(box);
box.classList.add('check');
//create span
let span = document.createElement('span');
li.appendChild(span);
span.innerHTML= task.value;
span.classList.add('task');
// create delete button
let btn = document.createElement('button');
li.appendChild(btn);
btn.classList.add("delete-btn");
btn.innerHTML = 'x';
btn.onclick = function () {
btn.parentElement.remove();
};
});

I want to use vanilla JS to remove the parent element of the button I'm pressing on click

I created a meme generator that accepts text and images and puts them all together. The generator creates a unique ID for each 'meme' and also adds buttons that show up on hover to "delete" the meme. I used vanilla JS to create this and therefore had to layer a few different child divs on top of one another: image, top text, bottom text using z-index.
I am struggling, however, to get the button to delete the parent div. I want to be able to click that delete button, and have the parent div deleted so that the button goes away, along with image and text. picture below + code snippets.
I attemped to do it with vanilla javascript, by adding a closeTheMeme function on click to each button:
let deleteBtns = document.getElementsByClassName('.delete');
function closeTheMeme (){
this.parentElement.parentElement.removeChild();
};
for(let i=0;i<deleteBtns.length;i++){
deleteBtns[i].addEventListener("click",closeTheMeme);
}
No errors on console...Including the rest of the JS below so you can see how the elements are created on click of the meme generator.
'use strict';
let count=0;
// SUBMIT FORM
document.getElementById('memeInput').addEventListener('submit',function(e){
count++;
//prevent default
e.preventDefault();
//set image, top, and bottom to variables we can work with
let bottomText = document.getElementById('bottomText').value;
createMeme();
})
function createMeme(){
//create a meme section with an ID of the number of times the button was clicked, and add it to the meme section
let meme = document.createElement("DIV");
document.body.appendChild(meme);
meme.setAttribute("id", "meme"+count);
//create an image, set that image to equal the link, give it an id based on form submits, set image.src equal to the link
let img = document.createElement("IMG");
img.setAttribute("id","image"+count);
let imageLink = document.getElementById('imageLink').value;
meme.appendChild(img);
document.getElementById("image"+count).src=imageLink;
//set top text variable equal to the ID of toptext. value(form submission)
let topText = document.getElementById('topText').value;
let top = document.createElement('DIV');
top.setAttribute("id","topText"+ count);
meme.appendChild(top);
top.innerHTML = topText;
//set bottom text variable equal to the ID of toptext.value form submission
let bottomText = document.getElementById('bottomText').value;
let bottom = document.createElement('DIV');
bottom.setAttribute("id","bottomText" + count);
meme.appendChild(bottom);
bottom.innerHTML = bottomText;
//add a button that deletes the meme in the same way as above
let deleteButton = document.createElement("BUTTON");
deleteButton.classList.add("delete");
deleteButton.innerHTML = "Delete";
meme.appendChild(deleteButton);
//styling and position
meme.classList.add("meme");
top.classList.add("topWords");
bottom.classList.add("bottomWords");
};
let deleteBtns = document.getElementsByClassName('.delete');
function closeTheMeme (){
this.parentElement.parentElement.removeChild();
};
for(let i=0;i<deleteBtns.length;i++){
deleteBtns[i].addEventListener("click",closeTheMeme);
}
You select the buttons when the page loads. You created no buttons so it is not possible for it to work since there is nothing to bind an event to.
Since you are making the buttons, add the event there.
const deleteButton = document.createElement("BUTTON");
deleteButton.addEventListener("click", function () {
this.closest("div").remove();
});
Other option is event delegation
document.body.addEventListener("click", function (e) {
const btn = e.target.closest(".delete");
if (btn) btn.closest("div").remove();
});

Event listener doesn't work after adding a new element

Basically, I have a text box where I write some text, click "Add Post", and a new post will be prepended to a list of other posts (similar to Twitter). Each of these posts has a 'delete' button.
For now, when I click delete on each posts, I have a console.log that just says, "TEST". And it works fine. However, after I add a post, meaning, a new element has been prepended, the event listener stops working, even for the existing 'delete' buttons (not just the newly added one).
This is how I wrote the event listener for the delete.
for(var i = 0; i < deleteDOM.length; i++) {
deleteDOM[i].addEventListener("click", deleteEntryCont);
}
...Where deleteEntryCont is just a function that console logs "TEST" for now.
deleteDOM is the variable for document.getElementsByClassName("delete") and is just a node list.
Here's the part where a new 'post' is added:
entryList.forEach(function(entry) {
var entryItemDOM = document.createElement("li");
var entryTextDOM = document.createElement("p");
var metaWrapperDOM = document.createElement("div");
var timeStampDOM = document.createElement("span");
var deleteDOM = document.createElement("span");
// Create entry wrapper & class names
entryItemDOM.className = "entry";
entryItemDOM.className += ` ${entry.mood}-entry`;
entryItemDOM.id = entry.id;
// Insert entry at the top of the stack
domEl.entriesDOM.insertBefore(entryItemDOM, domEl.entriesDOM.firstChild);
entryItemDOM.appendChild(entryTextDOM);
entryTextDOM.innerHTML = entry.text;
entryItemDOM.appendChild(metaWrapperDOM);
metaWrapperDOM.className = "overflow-hidden";
metaWrapperDOM.appendChild(timeStampDOM);
timeStampDOM.className = "timestamp";
timeStampDOM.innerHTML = entry.timeStamp;
metaWrapperDOM.appendChild(deleteDOM);
deleteDOM.className = "delete";
deleteDOM.innerHTML = "Delete";
});
Where entryList is an array of objects that this above code renders in HTML.
What could be the issue?
As discussed in the comments, you're only adding the event listeners when the page is loaded, which means it's only added to the posts that are visible at the time. You need to add the listener separately to each new post you create:
metaWrapperDOM.appendChild(deleteDOM);
deleteDOM.className = "delete";
deleteDOM.innerHTML = "Delete";
deleteDOM.addEventListener('click', deleteEntryCont);

Dynamically created form called via onclick disappears immediately Javascript

I have dynamically created a button in my Javascript function and called another function onclick, as shown below.
streambtn = document.createElement("button");
streambtn.setAttribute("onclick","createattribute()");
The createattribute() method opens a subdivision within the dynamically created form and this function is as follows.
function createattribute() {
inputval.innerHTML = "Provide a Stream name and click to add attribute-type pairs to yours stream.";
var input = document.createElement("input");
input.type = "text";
input.placeholder="Attribute name";
input.id="attr"+attrID;
input.className = "attr-textfield-style";
inputval.appendChild(input);
//Display the drop down menu
var newDiv=document.createElement('div');
var html = '<select>', attrtypes = typeGenerate(), i;
for(i = 0; i < attrtypes.length; i++) {
html += "<option value='"+attrtypes[i]+"'>"+attrtypes[i]+"</option>";
}
html += '</select>';
newDiv.className="attr-combobox-style";
newDiv.id="type"+attrID;
newDiv.innerHTML= html;
inputval.appendChild(newDiv);
attrID++;
alert("attrname id: "+input.id+" attrtype id: "+ newDiv.id);
}
The inputval is a division within the dynamically created form where the newly created form elements from the createattribute() function will be appended to. But the issue that I'm facing right now, is that though the method is correctly called, the form(dynamically created form) immediately disappears in a split second once the streambtn is clicked. Once it is clicked, it displays the first line "Provide a Stream name and click to add attribute-type pairs to yours stream." in a flash and disappears. Is there a way to keep it onscreen and then hide it depending on any conditions(like after the user finishes entering the data corresponding to that newly opened form-> created via createattribute() method)?
Add type = "button" as <button> without type = "button" will act as submit button and over click of the submit buttopn, page will be unloaded.
streambtn = document.createElement("button");
streambtn.type = 'button';
streambtn.setAttribute("onclick","createattribute()");

Create List Item From Rich Text Field Content

I want to take the user input text from this div and input tag I've got:
<input id="title" placeholder="Title (Optional)">
<div class="editor" contenteditable></div>
The div is a rich text field that I've put in place of a regular textarea tag
and create a list item inside a <ul> tag.
Here is the javascript I've got, but is not working...
(works just fine with regular text area, but I get nothing with the rich text form)
/*------POST SUBMIT JS------*/
//target all necessary HTML elements
var ul = document.getElementById('list'),
removeAll = document.getElementById('removeAll'),
add = document.getElementById('add');
//make something happen when clicking on 'submit'
add.onclick = function(){
addLi(ul)
};
//function for adding items
function addLi(targetUl){
var inputText = document.getElementsByClassName('editor').value, //grab input text (the new entry)
header = document.getElementById('title').value, //grab title text
li = document.createElement('li'), //create new entry/li inside ul
content = document.createElement('div'),
title = document.createElement('div'),
removeButton = document.createElement('button'); //create button to remove entries
content.setAttribute('class','content')
title.setAttribute('class','title')
content.innerHTML = inputText;
title.innerHTML = header;
if (inputText.split(' ').join(' ').length === 0) {
//check for empty inputs
alert ('No input');
return false;
}
removeButton.className = 'removeMe'; //add class to button for CSS
removeButton.innerHTML = 'Delete'; //add text to the remove button
removeButton.setAttribute('onclick', 'removeMe(this);'); //creates onclick event that triggers when entry is clicked
li.appendChild(title); //add title textnode to created li
li.appendChild(content); //add content textnode to created li
li.appendChild(removeButton); //add Remove button to created li
targetUl.appendChild(li); //add constructed li to the ul
}
//function to remove entries
function removeMe(item){
var deleteConfirm = confirm('Are you sure you want to delete this entry?');
if (deleteConfirm){var parent = item.parentElement;
parent.parentElement.removeChild(parent)}
};
function checkRemoval(){
var entryConfirm = confirm('Are you sure you want to delete all entries?');
if (entryConfirm){
ul.innerHTML = '';
}
};
Here is the demo I'm working on
Here is the demo using a textarea tag
getElementsByClassName('editor') is going to return an array of elements with the class editor, so you can't just do .value, you need to get the first element in the array.
Also, since it's a div, I think you want to use textContent, so it'll look like this
var inputText = document.getElementsByClassName('editor')[0].textContent
for the input type you have to write following into your javascript:
var input_val = getElementsByClassName('title').value;
for the div you have to write following into your javascript:
var div_val = getElementsByClass('editor').value;
I hope this will work

Categories