Delete Element vanillaJs [duplicate] - javascript

Attempting my first Javascript project, playing around with DOM to make a To-Do List.
After adding an item, how do i get the 'Remove' button to function and remove the item + the remove button.
Furthermore, after a new entry is made, the list item still stays in the input field after being added. How can it be made to be blank after each list item.
And yes i know my code is kinda messy and there is most likely an easier way to create it but I understand it like this for now.
Any help is greatly appreciated. Thanks
JSFiddle Link : http://jsfiddle.net/Renay/g79ssyqv/3/
<p id="addTask"> <b><u> Tasks </u></b> </p>
<input type='text' id='inputTask'/>
<input type='button' onclick='addText()' value='Add To List'/>
function addText(){
var input = document.getElementById('inputTask').value;
var node=document.createElement("p");
var textnode=document.createTextNode(input);
node.appendChild(textnode);
document.getElementById('addTask').appendChild(node);
var removeTask = document.createElement('input');
removeTask.setAttribute('type', 'button');
removeTask.setAttribute("value", "Remove");
removeTask.setAttribute("id", "removeButton");
node.appendChild(removeTask);
}

You can simply assign event:
removeTask.addEventListener('click', function(e) {
node.parentNode.removeChild(node);
});
http://jsfiddle.net/g79ssyqv/6/

Edited the Fiddle... just try this
FiddleLink (Should work now, button and p-tag will be removed)
HTML
<p id="addTask"> <b><u> Tasks </u></b> </p>
<input type='text' id='inputTask'/>
<input type='button' onclick='addText()' value='Add To List'/>
JS
var row = 0;
function addText(){
var input = document.getElementById('inputTask').value;
if(input != "")
{
var node=document.createElement("p");
var textnode=document.createTextNode(input);
node.appendChild(textnode);
node.setAttribute("id","contentP"+row);
document.getElementById('addTask').appendChild(node);
var removeTask = document.createElement('input');
removeTask.setAttribute('type', 'button');
removeTask.setAttribute("value", "Remove");
removeTask.setAttribute("id", "removeButton");
removeTask.setAttribute("onClick", "deleterow("+ row +");");
node.appendChild(removeTask);
row++;
}
else
{
alert("Please insert a value!");
}
}
function deleterow(ID)
{
document.getElementById('contentP'+ID).remove();
}
Greetings from Vienna

Use this
// +your code
.....
node.appendChild(removeTask);
// + modify
removeTask.onclick = function(e){
var dom = this;
var p_dom = this.parentNode;
console.log(p_dom);
var parent_node = p_dom.parentNode;
parent_node.removeChild(p_dom);
}

Related

remove each li item todo list using on click

I intended to make a todo list but I'm getting a problem that i wanna make a button that come inline in list item like so <li>my task</li><button>Delete</button>
but my delete button isn't deleting items correctly it only deletes one items and then start giving error
this is my code, please look here and also tell me what kind of mistakes I'm doing I'm very beginner in web development
<!DOCTYPE html>
<html>
<body>
<input type="text" placeholder="Enter Task" onfocus="this.value=''" id="myTask">
<button onclick="myFunction()">Try it</button>
<button onclick="deleteTask()">del it</button>
<ol id="myList">
</ol>
<script>
function myFunction() {
var node = document.createElement("LI");
var myTask = document.getElementById("myTask").value;
var textnode = document.createTextNode(myTask);
node.appendChild(textnode);
document.getElementById("myList").appendChild(node);
var btn = document.createElement("input");
var abcElements = document.querySelectorAll('LI');
for (var i = 0; i < abcElements.length; i++){
abcElements[i].id = 'abc-' + i;
}
// node.setAttribute("id", "li1");
btn.setAttribute("type", "submit");
btn.setAttribute("value", "delete");
btn.setAttribute("id", "delete");
node.appendChild(btn);
btn.addEventListener('click', ()=>{
// console.log("OK");
document.getElementById("abc-0").parentNode.removeChild(document.getElementById("abc-0"))
})
}
function deleteTask() {
var i = 0;
var item = document.getElementsByTagName("LI")[i];
i++;
item.parentNode.removeChild(item);
}
</script>
</body>
</html>
So I just want to make a delete button with every list item as I click on Try it button
Some points to address:
Don't call a function myFuntion. Give it a descriptive name, like addTask
Don't create id-attributes with sequential numbers. That is almost never needed.
The initial HTML should not have a delete button, since it should associate with a list item.
Don't make the type of the delete button "submit". That only makes sense when you have a form element, and need to submit the form.
Don't give the created button the same id over and over again: that is invalid in HTML. id-attributes should have unique values. But again, it is rarely needed to assign an id to dynamically generated elements.
In an event listener you can use the event object to get the element on which the event was fired. Or you can use the this object in a function. But you can also reference the node variable that exists in the so-called closure.
function addTask() {
var node = document.createElement("LI");
node.textContent = document.getElementById("myTask").value;
var btn = document.createElement("button");
btn.textContent = "delete";
btn.addEventListener('click', () => node.remove());
node.appendChild(btn);
document.getElementById("myList").appendChild(node);
}
li > button { margin-left: 5px }
<input type="text" placeholder="Enter Task" onfocus="this.value=''" id="myTask">
<button onclick="addTask()">Add task</button>
<ol id="myList"></ol>
try something like this:
function myFunction() {
const li = document.createElement("li");
li.innerHTML = document.getElementById("myTask").value;
const button = document.createElement("button");
button.innerHTML = "delete";
li.appendChild(button);
button.addEventListener("click", () => li.parentNode.removeChild(li));
document.getElementById("myList").appendChild(li);
}

How would I assign each list item a sequential ID in Javascript? (in an html document by the way)

Here is the section which is confusing me:
<script type="text/javascript">
//declaring veriables
var inputField = document.getElementById("input");
var addBtn = document.getElementById("addBtn");
var html = "";
var x = 0;
addBtn.addEventListener('click', function(){
var text = inputField.value;
addToList(text);
})
//adds items to list
function addToList(text){
html += "<li id=(x+=1)><h4><input type='checkbox' id=(x+=1) onclick= 'clearspecifieditems()'>"+text+"</h4></li>";
document.getElementById("myList").innerHTML = html;
inputField.value = "";
}
//clears items
function clearspecifieditems(itemid)
{
//delete selected item
};
So the goal here is to create a to-do list (I'm new to coding). The addToList(text) function is supposed to create a new list item and assign a sequential ID to it. However, I cannot seem to figure out how to have it generate the ID. In addition, clearspecifieditems(itemid) is supposed to get the IDs of all the list items that are checked, and clear all of them.
For the first part of your question either use string concatenation similar to how you added the text variable...
function addToList(text) {
const id = x + 1;
html += '<li id="' + id + '"><h4><input type="checkbox" id="' + id + '">' + text + '</h4></li>';
// ..
}
...or use a template literal:
function addToList(text) {
const id = x + 1;
html += `<li id="${id}"><h4><input type="checkbox" id="${id}" />${text}</h4></li>`;
// ..
}
HOWEVER, for the second part, how to clear checked boxes:
I purposely left the onclick out of the above code because it sounds as if you need a separate button to clear the checkboxes:
// Grab the button and add an click listener to it
// to call `clearSpecifiedItems`
const button = document.querySelector('.clear');
button.addEventListener('click', clearSpecifiedItems, false);
function clearSpecifiedItems() {
// Select all the checked checkboxes using their class
const selected = document.querySelectorAll('.test:checked');
// Set their checked property to false (or null)
selected.forEach(input => input.checked = false);
}
<input class="test" type="checkbox" />
<input class="test" type="checkbox" />
<input class="test" type="checkbox" />
<input class="test" type="checkbox" />
<button class="clear">Clear</button>
Notice that none of these inputs have IDs. I've used a class to pick up the elements instead. So unless you're using the ids for anything else it makes the first part of your code redundant. Just use a CSS selector to grab the elements you need and then process them. No IDs required!
I can see what you're going for. You are almost there. Just a little bit of syntactical error, and a bit of a logical one.
You see, when you increment x two times, You will have a different id for the <li> and the <input>. What I suggest is you increment the x beforehand and then use it.
You can do it like this:
function addToList(text){
x++;
html += "<li id="+ x +"><h4><input type='checkbox' id="+ x +" onclick= 'clearspecifieditems()'>"+text+"</h4></li>";
document.getElementById("myList").innerHTML = html;
inputField.value = "";
}
or this (ES6)
function addToList(text){
x++;
html += `<li id=${x}><h4><input type='checkbox' id=${x} onclick= 'clearspecifieditems()'>${text}</h4></li>`;
document.getElementById("myList").innerHTML = html;
inputField.value = "";
}
Is it absolutely necessary that you must only increment? Can the ID's be truly unique? I suggest you use UUID in that case
Your second question is how to make clearspecifieditems work. Here's what you can do. You can pass the context, or simply the checkbox that was clicked and then get it's ID easily..
So you would define your function something like this:
function clearspecifieditems(element){
//delete selected item
console.log(element.id); // this would give you the ID of the selected checkbox and then you can do whatever with it
};
and slightly modify your function call on the click event
html += "<li id="+ x +"><h4><input type='checkbox' id="+ x +" onclick= 'clearspecifieditems(this)'>"+text+"</h4></li>";
Note this this part.
More more information, See this
Just use string interpolation to reference the x variable and increment it by one every time you add a new item as follows:
/* JavaScript */
var inputField = document.getElementById("input");
var addBtn = document.getElementById("addBtn");
var output = document.getElementById("output");
var html = "";
var x = 0;
function addToList(text) {
output.innerHTML += `<li id=id${x}><h4><input type='checkbox' id=${x}>This list item has an id: id${x}"</h4></li>`;
inputField.value = "";
x++;
}
addBtn.addEventListener('click', function(){
var text = inputField.value;
addToList(text);
})
<!-- HTML -->
<input type="text" id="input" />
<button id="addBtn">Add Items</button>
<div id="output"></div>
And for removing checked elements, simply add another button, say removeBtn and then add a click listener to the button that invokes the clearspecifieditems().
Inside the function, assign a variable to a list of all the checkboxes, loop through the variable using forEach and remove any checkbox that is not checked like this:
function clearspecifieditems() {
var check = document.querySelectorAll('[id^="id"]');
check.forEach(checkBox => {
if(checkBox.children[0].children[0].checked){
checkBox.remove();
}
});
}
removeBtn.addEventListener('click', clearspecifieditems);
#output {list-style: none;}
/* <input type="text" id="input" />
<button id="addBtn">Add Items</button> */
<ul id="output">
<li id="id0"><h4><input type="checkbox" id="input0">This list item has an id: id0"</h4></li>
<li id="id1"><h4><input type="checkbox" id="input1">This list item has an id: id1"</h4></li>
<li id="id2"><h4><input type="checkbox" id="input2">This list item has an id: id2"</h4></li>
<li id="id3"><h4><input type="checkbox" id="input3">This list item has an id: id3"</h4></li>
</ul>
<hr>
<button id="removeBtn">Remove</button>
You're sending X as 1. You should do like this :
var input = document.getElementById("input");
var div = document.getElementById("div");
var button = document.getElementById("addbutton");
var id = 0;
button.onclick = function() {
text = input.value;
addtask(text)
}
function addtask(text) {
var element = document.createElement("li");
element.setAttribute("id", id)
var deleteE = document.createElement("input");
deleteE.setAttribute("type", "checkbox");
deleteE.setAttribute("onclick", "deleteX(" + id + ")");
var node = document.createTextNode(text);
element.appendChild(deleteE);
element.appendChild(node);
div.appendChild(element);
id += 1;
}
function deleteX(id) {
document.getElementById(id).style.visibility = "hidden";
}
<input id="input"> <button id="addbutton"> add </button>
<div id="div"></br> </div>

Is there a way to dynamically create nested divs onclick?

I'm attempting to create a page where the user is able to customize the form to their needs by adding in extra divs or nested divs (as many layers deep as they'd like). Within each div I'd like to have text input and a button which adds another div on the same level and a button that nests a div within it. Both divs should again have a text input and a button which does the same thing.
However I've gotten a bit stuck. When I attempt to create a nested div I always end up adding it at the very bottom instead of inside its parent.
<html>
<script type="text/javascript">
var counter = 1;
function addNode() {
var newDiv = document.createElement('div');
counter++;
newDiv.innerHTML = "Entry " + counter + " <br><input type='text' name='myInputs'>";
document.getElementById("dynamicInput").appendChild(newDiv);
var newButton = document.createElement('button');
newButton.type = "button";
newButton.onclick = addSub;
document.getElementById("dynamicInput").appendChild(newButton);
}
function addSub() {
var newDiv = document.createElement('div');
counter++;
newDiv.innerHTML = "Entry " + counter + " <br><input type='text' name='myInputs' style='margin:10px'>";
document.getElementById("subInput").appendChild(newDiv);
}
</script>
<form class="form" method="POST">
<div id="dynamicInput" name="dynamicInput" multiple="multiple">
Entry 1<br><input type="text" name="myInputs">
<div id="subInput" name="subInput" multiple="multiple">
<input type="button" value="add nested" onClick="addSub();">
</div>
</div>
<input type="button" value="Add another text input" onClick="addNode();" >
<input type="submit" value = "answer" multiple="multiple"/>
</form>
</html>
Here is a complete solution for you keep in mind that if you need to bind extra events on your produced inputs and buttons you ll have to do it inside the functions addNode or addSub as i did for the click event on the buttons.
Working example : https://jsfiddle.net/r70wqav7/
var counter = 1;
function addNode(element) {
counter++;
var new_entry="Entry "+counter+"<br><input type='text' name='myInputs'><br>";
element.insertAdjacentHTML("beforebegin",new_entry);
}
function addSub(element) {
counter++;
var new_sub_entry="<div class='block'>"
+"Entry "+counter+"<br><input type='text' name='myInputs'><br>"
+"<div class='buttons'>"
+"<input class='add_sub_button' type='button' value='add nested'>"
+"<input class='add_button' type='button' value='Add another text input' >"
+"</div>"
+"</div><br />"
+"</div>";
element.insertAdjacentHTML("beforebegin",new_sub_entry);
var blocks=element.parentNode.getElementsByClassName("block");
blocks[blocks.length-1].getElementsByClassName("add_sub_button")[0].addEventListener("click",function(){
addSub(this.parentNode);
});
blocks[blocks.length-1].getElementsByClassName("add_button")[0].addEventListener("click",function(){
addNode(this.parentNode);
});
}
var buttons=document.getElementsByClassName("add_button");
for(i=0;i<buttons.length;i++){
buttons[i].addEventListener("click",function(){
addNode(this.parentNode);
});
}
var nested_buttons=document.getElementsByClassName("add_sub_button");
for(i=0;i<buttons.length;i++){
nested_buttons[i].addEventListener("click",function(){
addSub(this.parentNode);
});
}
div.block{
padding:5px;
border:2px solid #000;
}
<form class="form" method="POST">
<div class="block">
Entry 1<br><input type="text" name="myInputs"><br>
<div class="buttons">
<input class="add_sub_button" type="button" value="add nested">
<input class="add_button" type="button" value="Add another text input" >
</div>
</div><br />
<input type="submit" value = "answer" multiple="multiple"/>
</form>
EDITED : There was an error binding the click event on nested items updated to work properly
Here's another worked example which makes use of the concepts I mentioned in an earlier comment. I've moved the Add-Item button outside the form and altered the method used to determine the text for each new item added. Rather than keep a counter, I count the number of existing items in the document and increment it, using this as as the n in the string "Entry n"
I should have added(appended) the sub-item before the button that creates new ones, but was lazy and just called appendChild on the button after the other new element was added - the end result is the same, but it's less efficient and will cause slower performance/shorter battery life.
I was going to use the .cloneNode method of the .dynamicInput div, when clicking "Add new item", however this will copy all subitems of the chosen target and we still need to call addEventListener for the button anyway, so I've opted to simply create each input-item added with the "Add new item" button instead.
<!doctype html>
<html>
<head>
<script>
"use strict";
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}
function allByClass(className,parent){return (parent == undefined ? document : parent).getElementsByClassName(className);}
function allByTag(tagName,parent){return (parent == undefined ? document : parent).getElementsByTagName(tagName);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('addNewInputBtn').addEventListener('click', myAddNewItem, false);
var subItemBtn = document.querySelectorAll('.dynamicInput button')[0];
subItemBtn.addEventListener('click', myAddSubItem, false);
}
function makeNewItem(titleStr)
{
var div = newEl('div');
div.className = 'dynamicInput';
var heading = newEl('h3');
heading.innerText = titleStr;
div.appendChild(heading);
var input = newEl('input');
div.appendChild(input);
var btn = newEl('button');
btn.innerText = 'Add sub-items';
btn.addEventListener('click', myAddSubItem, false);
div.appendChild(btn);
return div;
}
function myAddNewItem(evt)
{
var numAlreadyExisting = allByClass('dynamicInput').length; // count number of divs with className = dynamicInput
var newNum = numAlreadyExisting + 1;
var newInputPanel = makeNewItem('Entry ' + newNum);
byId('myForm').appendChild(newInputPanel);
return false;
}
function myAddSubItem(evt)
{
evt.preventDefault(); // stops this button causing the form to be submitted
var clickedBtn = this;
var inputDiv = clickedBtn.parentNode;
var newInput = newEl('input');
inputDiv.appendChild(newInput);
inputDiv.appendChild(clickedBtn);
}
</script>
</head>
<body>
<form id='myForm'>
<div class='dynamicInput'>
<h3>Entry 1</h3>
<input type='text'/><button>Add sub-item</button>
</div>
</form>
<button id='addNewInputBtn'>Add new item</button>
</body>
</html>

Remove checked checkboxes

I am making a To-do list, where I want to be able to add new tasks, and delete tasks that are checked off. However, it seems my function just deletes all tasks, not just the ones that are checked off. Neither does it seem to allow new tasks to be added.
html:
<h1 id="title"> To-do list</h1>
<div id="task_area">
</div>
<input type="text" id="putin"></input>
<button id="add">add</button>
javascript:
<button id="clear">Clear completed tasks</button>
var tasks = document.getElementById("task_area")
var new_task = document.getElementById("add")
var clear = document.getElementById("clear")
new_task.addEventListener("click", function() {
var putin = document.getElementById("putin")
var input = document.createElement('input')
input.type = "checkbox"
var label = document.createElement('label')
label.appendChild(document.createTextNode(putin.value))
task_area.appendChild(input)
task_area.appendChild(label)
})
clear.addEventListener("click", function() {
for (i = 0; i < task_area.children.length; i++) {
if (task_area.children[i].checked === true) {
task_area.remove(tasks.children[i])
}
}
})
jsfiddle: https://jsfiddle.net/4coxL3um/
.remove removes the element you are calling it from, and doesn't take an argument for what to remove. The following:
task_area.remove(tasks.children[i])
should be
tasks.children[i].remove()
EDIT: As Mononess commented below, this will only remove the checkboxes and not the labels. While you could delete both using Jayesh Goyani's answer below, it's probably better that each input/label pair be wrapped in a single div or span for easier management.
You could try adding an event listener to each child of task_area that calls the below function. Haven't gotten a chance to test it out, and may not fulfill all of your requirements, but should get the job done.
function removeClicked() {
this.parentNode.removeChild(this);
}
Please try with the below code snippet. Below code will help you to remove selected checkbox with label.
<body>
<h1 id="title">To-do list</h1>
<div id="task_area">
</div>
<input type="text" id="putin" />
<button id="add">add</button>
<button id="clear">Clear completed tasks</button>
<script>
var tasks = document.getElementById("task_area")
var new_task = document.getElementById("add")
var clear = document.getElementById("clear")
new_task.addEventListener("click", function () {
var putin = document.getElementById("putin")
var input = document.createElement('input')
input.type = "checkbox"
var label = document.createElement('label')
label.appendChild(document.createTextNode(putin.value))
task_area.appendChild(input)
task_area.appendChild(label)
//document.getElementById("task_area").innerHTML = putin.value
})
clear.addEventListener("click", function () {
for (i = 0; i < task_area.children.length; i++) {
if (task_area.children[i].checked === true) {
tasks.children[i].nextSibling.remove();
tasks.children[i].remove();
}
}
})
</script>
</body>
Please let me know if any concern.

paste input type file value to input type text

i have script like this, for append a new elment based user input
var tmp;
$('#add').click(function(){
var galer=parseInt($('#many').val());
for(var h=1;h<=tmp;h++){
$(".af_"+h).remove();
}
for(var x=1;x<=galer;x++){
$("#kontenPlus").append("<input type='file' id='photo_"+x+"'> <input type='text' id='src_"+x+"'>");
}
tmp=galer;
});
for(var u=1;u<=tmp;u++){
$('#photo_'+u).change(function(){
$('#src_'+x).val($(this).val());
});
}
this html code:
<input type='text' id='many'><div id='add'>Add element</div>
<div id='kontenPlus'></div>
i want to ask why value of '#photo_+x', isn't put in '#src_'+x, is function can be looped ?
LINK:http://jsfiddle.net/rizalfarez/V5AdP/3/
Because these elements are being dynamically created you will need to delegate the event listening like
$(window).on( "change", function() {
//
var id = $(this).id;
//
if (id.indexOf("photo") === 0) {
the reason that the value of text boxes does not get updated is because they are dynamically created, so the change event is not bind to them.
I have changed your code and optimized it a little like this:
var tmp;
$('#add').click(function(){
var galer = parseInt($('#many').val());
$('.af').remove();
for(var x=1;x<=galer;x++)
$('#kontenPlus').append('<div class="af"><input type="file" id="photo_'+x+'"><input type="text" id="src_'+x+'"></div>');
$('[id^="photo_"]').each(function(){
$(this).change(function(){
$(this).next().val($(this).val());
});
});
});

Categories

Resources