Deleting List dynamically when Button is clicked Javascipt - javascript

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

Related

Trying to add a delete button in the DOM

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>

moving li's so that i can make a new list

// makes an li inside of a ol when a button is pressed
function addLi() {
var txtVal = document.getElementById('txtVal').value,
listNode = document.getElementById('list'),
liNode = document.createElement("li"),
txtNode = document.createTextNode(txtVal);
liNode.appendChild(txtNode);
listNode.appendChild(liNode);
};
function addoutp() {
};
I don't know what to put inside this function to move the inputted text over to another part of the screen separately...
You were very close. Just adding some HTML that matches your selectors in the JS code and it started working. I also added a check to make sure there was a value before adding to the list and also a reset to clear the input value after the text gets added to the list (txtVal.value = '';).
// makes an li inside of a ol when a button is pressed
function addLi() {
var txtVal = document.getElementById('txtVal'),
listNode = document.getElementById('list'),
liNode = document.createElement("li"),
txtNode = document.createTextNode(txtVal.value);
if (txtVal.value) {
liNode.appendChild(txtNode);
listNode.appendChild(liNode);
// clear the input
txtVal.value = '';
}
};
<input id="txtVal" type="text" />
<button onclick="addLi()">Add to list</button>
<ol id="list"></ol>

Unable to get asynchronous child spawning in JavaScript

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>

Dynamically inserting elements so they can still be deleted

I want to dynamically add textboxes so each textbox added appears as the last in the list but above the button. I also want a button allowing the deletion of each textbox. The code below adds the textboxes just as I want, but when clicking on "Remove Field" only that text is removed. The textbox associated with that text remains. This DOES work if I don't use "insertBefore" so I'm thinking that messes up what "removalLink" knows what to delete?
<script>
var namesCount = 0;
listNames = function (){
var field_area = document.getElementById("fields");
var li = document.createElement("li");
var input = document.createElement("input");
input.id = "txtName"+namesCount;
input.name = "txtName"+namesCount;
input.type = "text";
li.appendChild(input);
field_area.appendChild(li);
//INSERT ELEMENT JUST BEFORE ADD BUTTON
sp2 = document.getElementById("btnNames");
parentDiv = sp2.parentNode;
parentDiv.insertBefore(input, sp2);
//create the removal link
var removalLink = document.createElement("a");
removalLink.onclick = function(){
this.parentNode.parentNode.removeChild(this.parentNode)
}
var removalText = document.createTextNode("Remove Field");
removalLink.appendChild(removalText);
li.appendChild(removalLink);
field_area.appendChild(li);
//INSERT ELEMENT JUST BEFORE ADD BUTTON
var sp2 = document.getElementById("btnNames");
var parentDiv = sp2.parentNode;
parentDiv.insertBefore(div, sp2);
namesCount++
}
</script>
<body>
<ul id="fields">
Add More Names
</ul>
</body>
Since you've tagged jQuery, I'd suggest using it to significantly simplify your code.
First, fix your HTML so all the children of the <ul> are <li> tags like this:
<ul id="fields">
<li>Add More Names</li>
</ul>
And, then you can replace the entire listNames() function with this much simpler version that doesn't have your issue. I use the .closest("li") method to find the parent <li> tag to remove no matter how many parents above it is located which helps to prevent simple errors or dependencies on the exact HTML layout (e.g. it makes the code less fragile or prone to mistakes):
<script>
var nameCount = 0;
function listNames() {
var id = "txtName" + nameCount;
var li = $("<li>");
$("<input/>", {type: "text", name: id, id: id}).appendTo(li);
$("<a>Remove Field</a>").click(function() {
$(this).closest("li").remove();
}).appendTo(li);
li.insertBefore("#fields li:last");
nameCount++;
}
</script>
Working demo: http://jsfiddle.net/jfriend00/tjb24/
As I show in the demo link, you can also get rid of the onclick handler from the HTML and just hook up to it with an event listener, otherwise referred to as unobtrusive javascript where you separate the HTML from the javascript.
If you still want it all in plain javascript, you can do this:
<ul id="fields">
<li id="fieldAdd>Add More Names</li>
</ul>
<script>
var nameCount = 0;
document.getElementById("btnNames").addEventListener("click", function(e) {
var id = "txtName" + nameCount;
var li = document.createElement("li");
var input = document.createElement("input");
input.type = "text";
input.name = input.id = id;
li.appendChild(input);
var removeLink = document.createElement("a");
removeLink.innerHTML = "Remove Field";
removeLink.addEventListener("click", function(e) {
this.parentNode.parentNode.removeChild(this.parentNode);
e.preventDefault();
});
li.appendChild(removeLink);
var fields = document.getElementById("fields");
var fieldAdd = document.getElementById("fieldAdd");
fields.insertBefore(li, fieldAdd);
nameCount++;
e.preventDefault();
});
</script>
Working demo: http://jsfiddle.net/jfriend00/gTWqu/

Delete a div using "this" with Javascript

What I would like to do is to create a div by clicking on a button. In that div there will be another button if clicked will delete the div that it is in. So potentially the first button will create many div's with this delete button inside but I want the delete button to only delete the div that it is within. Any suggestions?
If you do not need to keep the "delete button" on your page, bind the click event on each of them and use .removeChild on the parent element of the parent div.
FIDDLE DEMO
You can do something like:
<script>
var addDiv = (function() {
var div = document.createElement('div');
div.appendChild(document.createTextNode('some text'));
var button = document.createElement('button');
button.appendChild(document.createTextNode('Remove...'));
button.type = "button";
return function() {
var d = div.cloneNode(true);
var b = button.cloneNode(true);
b.onclick = function() {
var d = this.parentNode;
d.parentNode.removeChild(d);
};
d.appendChild(b);
document.body.appendChild(d);
};
}())
</script>
<button onclick="addDiv()">Add a div</button>
The above is just a trivial example to demonstrate one way to go about it. Note that if you clone an element, listeners added as properties or by addEventListener are dropped (this script would be very much simpler if they weren't).
HTML:
<input type="button" id='create' value="Create div!"/>
JS:
var i = 0;
document.onclick = function(e) {
var t = e.target;
if(t.id == 'create'){
t.parentNode.innerHTML += '<div>I AM A CHILD '+(++i)+' <input type="button" class="child" value="DELETE ME!"/><br/></div>';
}
if (t.className == 'child') {
t.parentNode.outerHTML = '';
}
};
using document.onclick and detecting the target element can be used as a live click to monitor newly created divs.
Its early and my brain may be a little foggy and the code may be a little dirty
Here is a jsfiddle

Categories