append(); is not a function.error in console - javascript

I trying to do simple to do list but append(); is not working and logging an error
Uncaught TypeError: ul.append is not a function
at HTMLButtonElement.takeValue
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<input type="text" id="field">
<button type="submit" id="btn-sub">submit</button>
<ul class="collection">
<li class="collection-item">Alvin</li>
</ul>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha256-k2WSCIexGzOj3Euiig+TlR8gA0EmPjuc79OEeY5L45g=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
<script src="js/main.js"></script>
JS
let btn = document.getElementById('btn-sub');
btn.addEventListener('click', takeValue);
function takeValue(e) {
e.preventDefault();
let con = document.getElementsByClassName('container');
let val = document.getElementById('field').value;
let ul = document.getElementsByClassName('collection');
let li = document.createElement('li');
li.classList.add('collection-item');
li.innerText = val;
ul.append(li);
con.prepend(ul);
}

How you can read here
Document.getElementsByClassName()
Returns an array-like object of all
child elements which have all of the given class names. When called on
the document object, the complete document is searched, including the
root node. You may also call getElementsByClassName() on any element;
it will return only elements which are descendants of the specified
root element with the given class names.
so, if you have at least a 'container':
let con = document.getElementsByClassName('container')[0];
same for your 'collection':
let ul = document.getElementsByClassName('collection')[0];
then, as you can read here
The Node.appendChild()
method adds a node to the end of the list of
children of a specified parent node. If the given child is a reference
to an existing node in the document, appendChild() moves it from its
current position to the new position (there is no requirement to
remove the node from its parent node before appending it to some other
node).
function addItem() {
let con = document.getElementsByClassName('container')[0];
let val = document.getElementById('field').value;
let ul = document.getElementsByClassName('collection')[0];
let li = document.createElement('li');
li.classList.add('collection-item');
li.innerText = val;
ul.appendChild(li);
con.prepend(ul);
}
<input id="field" value="hello" />
<div class="container">
<ul class="collection">
</ul>
</div>
<button onclick="addItem()">hit</button>

Related

why is this appearing ?: clone.getElementById is not a function

I've got this error:
index.js:29 Uncaught TypeError: clone.getElementById is not a function
at HTMLButtonElement.changeImg (index.js:29:11)
changeImg # index.js:29
It marks the line highlighted. I don't understand why. If somebody can help me I'll appreciate it.
//captura de elementos:
const btn = document.querySelector('.btn');
const templateImg = document.querySelector('.templateImg').content;
const imgContainer = document.querySelector('.imgContainer');
const fragment = document.createDocumentFragment();
let arrayImg = [
"/img/food1.jpg",
"/img/food2.jpg",
"/img/food3.jpg",
"/img/food4.jpg",
"/img/food5.jpg",
"/img/food6.jpg",
"/img/food7.jpg",
"/img/food8.jpg",
"/img/food9.jpg"
];
const changeImg = () => {
let ran = Math.floor(Math.random() * 9);
//Crear clon del template:
const clone = templateImg.firstElementChild.cloneNode(true);
console.log(clone);
console.log(arrayImg[ran]);
//capturar elemento y modificar el src:
clone.getElementById("img").src = arrayImg[ran];
fragment.appendChild(clone);
imgContainer.appendChild(fragment);
}
btn.addEventListener('click', changeImg);
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="StyleSheet" href= "style.css" type= "text/css">
<title>Cambiador de imagenes</title>
</head>
<body>
<div class="container">
h1>Food and drink in Florianopolis</h1>
<div class="imgContainer"><!--templateImg--></div>
<button type="text" class="btn" id="btn">Change</button>
</div>
<template class="templateImg">
<img id="img" src="/img/food1.jpg">
</template>
<script src="./index.js"></script>
</body>
</html>
I was trying to change the images inside the template modifying the src:
<template class="templateImg">
<img id="img" src="/img/food1.jpg">
</template>
When I use querySelector, the error is that the value I try to replace is null even though it's not, and with getElementById, I get that message that it's not a function.
you create a "clone" with this code:
const clone = templateImg.firstElementChild.cloneNode(true);
that is a image element(see in console) and you for changing image src just need to use this code:
clone.src = arrayImg[ran];
getElementById() is a method of document not of any HTML element.
What you want to use instead is querySelector which you can in fact use on elements.

Why is my .parentNode returning undefined? [duplicate]

This question already has answers here:
What do querySelectorAll and getElementsBy* methods return?
(12 answers)
Closed 1 year ago.
I´m trying to make a simple To-do List, and I want it to have a button to add the tasks that I want and another button to remove all tasks but when I click the delete button I get an error: "Cannot read property 'removeChild' of undefined" I don´t know why it says the parentNode is undefined.
Here is the code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>To do List</title>
</head>
<body>
<header>
<h1>To-do List</h1>
<div id="form">
<input type="text" name="" id="tarefa" value="Add an item!">
<button id="submit">Submit</button>
<button id="delete">Clear List</button>
</div>
</header>
<main>
<ul id="lista">
<li id="112">Test1</li>
<li>Test2</li>
</ul>
</main>
<script src="javascript.js"></script>
</body>
</html>
//Javascript file
const tarefa = document.getElementById("tarefa")
const adicionar = document.getElementById("submit")
const limpar = document.getElementById("delete")
const padre = document.getElementById("lista")
const fpp = document.querySelectorAll("li")
//Add the tasks
function enviar(e){
var coisa = document.createElement("li")
let escrito = tarefa.value;
padre.appendChild(coisa)
coisa.innerHTML = escrito
}
//Delete the tasks
function apagar(e){
fpp.parentNode.removeChild(fpp)
console.log("aaaa")
}
adicionar.addEventListener("click",enviar)
limpar.addEventListener("click",apagar)
.querySelectorAll returns a NodeList (because you're selecting all li tags, not just one), so you need to do a forEach loop. Give the context, I asume fds is supposed to be fpp (you never define fds in the code you provided), so here is the code you would need, given that assumption:
function apagar(e){
fpp.forEach(function(el) {
el.parentNode.removeChild(el)
})
}
Update
Use this so that you dont get null errors once the list is deleted the first time.
function apagar(e){
document.querySelectorAll("li").forEach(function(el) {
el.parentNode.removeChild(el)
})
}
How about
function apagar(){
padre.innerHTML = "";
}

cannot change css property of desired amount of elements using eventListener due to elements being created by javascript

I am attempting to change the backgroundColor of "gridElement" once "button" is clicked.
What was attempted, changing the way the elements are created to later include the event:
cloneNode() // doesn't work with eventListeners unless you use eventDelegation, in this case there is no parentElement to delegate the event too.
jQuery.clone() // the event is not tied directly to "gridElement" rather it is tied to "button" so jQuery.clone() would not be deep copying any associated events.
Also, attempting to make references to all gridElements:
used window.globalVarRef = localVar. // only references the first element and not all.
How can I modify the code so that the eventListener will change all "gridElement" and not just the first?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="CSS/main.css">
<title> Method 1 // appendChild() </title>
</head>
<body>
<div id="container">
<div id="gridContainer"></div>
</div>
<script>
const gridContainer = document.getElementById('gridContainer');
function createPixels(){
let pixels = 256;
for(let k=0;k<pixels;k++) {
const gridElement = document.createElement('div');
gridElement.classList.add('gridElement');
gridContainer.appendChild(gridElement);
window.allGridElements = gridElement;
}
}
createPixels();
const button = document.createElement('button');
button.classList.add('button');
button.textContent = 'button';
gridContainer.appendChild(button);
function changeBkg(){
window.allGridElements.style.backgroundColor = 'blue';
}
button.addEventListener('click', changeBkg);
</script>
</body>
</html>
The problem lies in your changeBkg function. To select all of the elements with the class of "gridElement", you want to use a for loop to find those elements and then change their styles. I added some basic css to the grid element so we can see the color change in action. Does that solve your issue?
.gridElement {
width: 100px;
height: 100px;
background: red;
display: inline-block;
margin-right: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" type="text/css" href="CSS/main.css">
<title> Method 1 // appendChild() </title>
</head>
<body>
<div id="container">
<div id="gridContainer"></div>
</div>
<script>
const gridContainer = document.getElementById('gridContainer');
function createPixels(){
let pixels = 256;
for(let k=0;k<pixels;k++) {
const gridElement = document.createElement('div');
gridElement.classList.add('gridElement');
gridContainer.appendChild(gridElement);
window.allGridElements = gridElement;
}
}
createPixels();
const button = document.createElement('button');
button.classList.add('button');
button.textContent = 'button';
gridContainer.appendChild(button);
function changeBkg(){
var items = document.getElementsByClassName('gridElement');
for (let i=0; i < items.length; i++) {
items[i].style.backgroundColor = 'blue';
}
}
button.addEventListener('click', changeBkg);
</script>
</body>
</html>

Is it possible to remove the child elements of the Ul I have with my code?

On each click of the deleteButton, I want to be able to remove the span and li element from my ul. Here is my code:
let textArea = document.getElementById('textArea');
let submit = document.getElementById("submit")
let ul = document.getElementById("task-list");
let deleteButton = document.getElementsByClassName("deleteButton");
//add todo
submit.addEventListener("click", function(){
let listItem = document.createElement("li");
let val = textArea.value;
listItem.innerHTML = `<button class="deleteButton">X</button> ${val}`;
ul.appendChild(listItem);
textArea.value = "";
});
//delete todo
deleteButton.addEventListener("click", function(){
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://kit.fontawesome.com/1f5460a8a6.js"></script>
<link rel="stylesheet" href="style.css">
<title>Todo List</title>
</head>
<body>
<div id="container">
<h1>To-do List</h1>
<input type="text" id="textArea"><button id="submit">+</button>
<ul id="task-list">
</ul>
</div>
<script src="script.js"></script>
</body>
</html>
Is it possible with something like I have setup here? Sorry about asking, but I am just stuck and want to become unstuck. I am thinking that using removeChild may work. However, I don’t think it can take both the span and li elements away at the same time.
You would have to attach an eventHandler on each instance of a delete-button, which you can't the way you're trying, because it's a nodeList and not a single element. I would suggest doing it within the eventHandler on 'submit', like so:
submit.addEventListener("click", function(){
let listItem = document.createElement("li");
let val = document.createTextNode(textArea.value);
let btn = document.createElement('button');
btn.textContent = 'X';
btn.onclick = e => e.target.parentNode.remove();
listItem.append(btn, val);
ul.appendChild(listItem);
textArea.value = "";
});
Try this. Hope it will work.
document.querySelector("ul").addEventListener("click", function(e) {
var element = e.target;
element.remove()
});

Javascript - How to add <input> element into div using createElement Method

I have a problem with simple thing.
I want to add a element into html div tag using createElement Method. I have tried a lot of diferent ways but always getting the same result - nothing happens.
This is my code:
function changeReleaseDate()
{
var parentElement = document.getElementByClassName("container body-content");
var existingElement = document.getElementByClassName("btn btn-default");
var newInput = document.createElement("input");
newInput.type = "text";
newInput.className = "form-control";
parentElement.insertBefore(newInput, existingElement);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My ASP.NET Application</title>
<link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
<script src="script.js"></script>
</head>
<body>
<div class="container body-content">
<h2>Index</h2>
<button id="btn" type="button" onclick="changeReleaseDate()" class="btn btn-default">Default</button>
<hr />
<footer>
<p>©My ASP.NET Application</p>
</footer>
</div>
</body>
</html>
I also tried to use appendChild but in this case input field was placed out of div.
The problem is that getElementByClassName should be getElementsByClassName.
This method returns a HTMLCollection, so to access the first element from this list you need to use bracket with index 0:
var parentElement = document.getElementsByClassName("container body-content")[0];
var existingElement = document.getElementsByClassName("btn btn-default")[0];
Demo: http://jsfiddle.net/jak4efau/
However it's more convenient in your case to use querySelector method:
var parentElement = document.querySelector(".container body-content");
var existingElement = document.querySelector(".btn.btn-default");
Also note, that you need to take care of the case when user clicks button multiple times, you probably don't want to append multiple input fields.

Categories