Add a button element to each list element - javascript

I want to add button element to each list element (JavaScript).
This is my code. I used fro loop. In the output, only the last element of the list is getting the button element. What am I doing wrong.
function createButtonElement() {
var btn = document.createElement("button"); `
btn.appendChild(document.createTextNode("Delete Me"));
var a = document.querySelectorAll("li");
for(var v =0; v<a.length;v++)
{
a[v].appendChild(btn);
}
}

You created only one button and append it on the first <LI>, then you append it to the second <LI>... as he can't be on two different place this command move your button to the second place, and so on.
to duplicate élent you have to use the cloneNode method : https://developer.mozilla.org/en-US/docs/Web/API/Node/cloneNode
sample code :
const MyList = document.querySelector('#My-List')
, AddButtons = document.querySelector('#Add-Buttons')
AddButtons.onclick=_=>
{
let newBt = document.createElement('button')
newBt.textContent = 'Delete Me'
document.querySelectorAll("#My-List li").forEach(eLI=>eLI.appendChild( newBt.cloneNode(true)) )
}
MyList.onclick=e=>
{
if (e.target.tagName.toLowerCase() !='button') return
let pLI = e.target.parentElement
MyList.removeChild(pLI)
}
<button id="Add-Buttons">Add Buttons to each element on list</button>
<ul id="My-List">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
PLUS
I added the way to deal with the click on the added buttons, via the event delegation

This behavior is documented in Node.appendChild() on MDN:
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).
Instead, instantiate a new button for each li within your loop:
function createButtonElement() {
var a = document.querySelectorAll("li");
for (var v = 0; v < a.length; v++) {
var btn = document.createElement("button");
btn.appendChild(document.createTextNode("Delete Me"));
a[v].appendChild(btn);
}
}
<li>a</li>
<li>b</li>
<li>c</li>
<button onclick="createButtonElement()">Click</button>

You need to create a new button for each item, otherwise the button just moves from item to item until you get to the last one.
function createButtonElement() {
var a = document.querySelectorAll("li");
for(var v =0; v<a.length;v++)
{
let btn = document.createElement("button");
btn.appendChild(document.createTextNode("Delete Me"));
a[v].appendChild(btn);
}
}
<button onclick="createButtonElement()">click</button>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>

You need to create the button for each li element
function createButtonElement() {
var a = document.querySelectorAll("li");
for(var v =0; v<a.length;v++) {
var btn = document.createElement("button");
btn.appendChild(document.createTextNode("Delete Me"));
a[v].appendChild(btn);
}
}

Related

Can't use removeChild() to delete the element just appended to list. Can only delete the ones at the beginning

This is two button. One is "appendChild" ,One is "Remove Child".
List ----Before------------
one
two
three
appended
appended
-------------------------
After appended two new elements, I want to remove the last one. But when I press the remove button.
List ---After-------------
one
two
(?????????? be deleted)
appended
appended
-------------------------
The appended elements are still there. I see many solve this problem with jQuery, but I am totally new. I am wondering if JavaScript has the solution.
apd.onclick = function() {
let apd = document.getElementById('apd')
let node = document.createElement('li')
node.className = 'added'
let textnode = document.createTextNode('this is node content')
node.appendChild(textnode)
document.getElementById('list').appendChild(node)
}
let list = document.getElementById('list')
let rem = document.getElementById('rem')
rem.onclick = function() {
let node = document.createElement('li')
document.getElementById('list').removeChild(list.children[0])
}
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<button id="apd">click me to append child!</button>
<button id="rem">click me to remove child!</button>
You can use list.lastElementChild.remove(); for delete problem and instead of onclick event use addEventListener as suggest by #T.J- Crowder into comment like:
let list = document.getElementById('list')
let rem = document.getElementById('rem')
let apd = document.getElementById('apd')
apd.addEventListener('click', () => {
let node = document.createElement('li')
let textnode = document.createTextNode('this is node content')
node.className = 'added'
node.appendChild(textnode)
list.appendChild(node)
});
rem.addEventListener('click', () => {
list.lastElementChild.remove();
//or if you need application for IE use list.removeChild(list.lastElementChild);
});
<ul id="list">
<li>123125151</li>
<li>123125151</li>
<li>123125151</li>
<li>123125151</li>
<li>123125151</li>
</ul>
<button id="apd">click me to append child!</button>
<button id="rem">click me to remove child!</button>
Reference:
Element.lastElementChild
Element.remove() - note: not on Internet Explorer, you'd need removeChild on the parent instead
EventTarget.addEventListener()
You are deleting the first one and not the last one.
Instead of list.children[0], you can use list.children[list.children.length - 1] which will be the last one.
apd.onclick = function() {
let apd = document.getElementById('apd')
let node = document.createElement('li')
node.className = 'added'
let textnode = document.createTextNode('this is node content')
node.appendChild(textnode)
document.getElementById('list').appendChild(node)
}
let list = document.getElementById('list')
let rem = document.getElementById('rem')
rem.onclick = function() {
let node = document.createElement('li')
document.getElementById('list').removeChild(list.children[list.children.length - 1])
}
<ul id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<button id="apd">click me to append child!</button>
<button id="rem">click me to remove child!</button>

I want to remove the `active` class on the button which was previously clicked using vanilla javascript

I'm stuck with a problem. I'm adding active classes to the pagination button which is clicked. When I click another link I want to remove the active class on the link that was previously clicked.
Any ideas?
html:
<ul class="pagination">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
</ul>
javascript:
const buttons = document.querySelectorAll('.pagination li');
for(let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", () => {
showPage((i + 1),students);
buttons[i].firstElementChild.setAttribute('class', 'active')
});
}
Select the active button and remove the class:
const buttons = document.querySelectorAll('.pagination li');
for(let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener("click", () => {
showPage((i + 1),students);
// Add these two lines:
const active = document.querySelector('.pagination li a.active');
if ( active )
active.className = '';
// Updated to use className
buttons[i].firstElementChild.className = 'active';
});
}
Assuming there'll be only one element with the active class, you can do this:
var activeElement = document.getElementsByClassName('active')[0];
if(typeof(activeElement) != "undefined"){
activeElement.classList.remove("active");
}
In case there is more than one element with the active class, only the first element will be modified.

How to insert the same element on beginning and on the end of the list with insertBefore and appendChild?

I would like to add elements with the same text on the end and at the beginning of the list. I want use appendChild and insertBefore. But, if I do this in following way is added only one element, this which is as last in the code of the script:
var list = document.getElementsByTagName('ul')[0];
var firstElement = list.firstChild;
var newElement = document.createElement('li');
var newText = document.createTextNode('new text');
newElement.appendChild(newText);
list.appendChild(newElement);
list.insertBefore(newElement, firstElement);
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
You have to clone the element you want to insert.
In your code you are "moving" the element from the button to the top, because you dealing with the same item which can only exist once in the html.
So just add a .cloneNode(true) and a cloned item can be at the top and at the other one at the bottom.
var list = document.getElementsByTagName('ul')[0];
var firstElement = list.firstChild;
var newElement = document.createElement('li');
var newText = document.createTextNode('new text');
newElement.appendChild(newText);
list.appendChild(newElement);
list.insertBefore(newElement.cloneNode(true), firstElement);
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>

Changing header style not working in Chrome

I'm trying to change the appearance of my h1. I've done a part of the code but I noticed that it doesn't work in Chrome. Anyone know why? And if you have a suggestion how to better write the code below:
Link: http://codepen.io/Winterfox/pen/KzRbpZ
window.onload = function() {
var ownHeading = document.getElementById("heading");
var newHeading = document.getElementById("newheading");
ownHeading.addEventListener("input", buildLayout);
function buildLayout() {
newHeading.innerHTML = ownHeading.value;
};
/*---------------------------------------------------------*/
var changeStyleBtn = document.getElementsByClassName("changestyle-btn");
var changeStyleUl = document.getElementById('change-h-font');
for (var i = 0; i < changeStyleBtn.length; i++) {
changeStyleBtn[i].addEventListener('click', changeStyle, false);
}
function changeStyle() {
changeStyleUl.style.display = "block";
};
/*-------------------------------------------------------*/
var changeStyleLi = changeStyleUl.getElementsByTagName('li');
for (var i = 0; i < changeStyleLi.length; i++) {
changeStyleLi[i].addEventListener('click', changeFont, false);
}
function changeFont() {
// here it stops working in chrome (can't click on lis)
alert("clic");
console.log(this);
};
};
Issue appears to be with the ul element being embedded #changestyle-btn div
<div class="changestyle-btn">+
<ul class="changestyle" id="change-h-font">
<li>1</li>
<li>2</li>
</ul>
</div>
Once I move the element out of the div it works fine in Chrome.
<div class="changestyle-btn">+</div>
<ul class="changestyle" id="change-h-font">
<li>1</li>
<li>2</li>
</ul>
This is most likely because you have already bound a click event to the #changestyle-btn div so when you attempt to click the li element it is only firing the first event.

include variable with addEventListener

I´ve just started to learn JavaScript and made a click function to change value of i depending on which li element is being clicked. Instead of having 3x of basically same function is it possible to send variable with addEventLisener to check with a if statement. Because if I add 1 or 2 more li it would add a lot of unnecessary code.
HTML:
<div><img src="image1" />
<ul>
<li id="list1">1</li>
<li id="list2">2</li>
<li id="list3">3</li>
</ul>
</div>
JavaScript:
var list1 = getElementById('list1');
var list2 = getElementById('list2');
var list3 = getElementById('list3');
list1.addEventListener("click", clicked1);
list2.addEventListener("click", clicked2);
list3.addEventListener("click", clicked3);
var i = 0;
function clicked1(){
i= 0;
loop();
}
function clicked2(){
i = 1;
loop();
}
function clicked3(){
i = 2;
loop();
}
function loop(){
if (i > 2){
i=0;
}
var imageloop = getElementById('slideshow').getElementsByTagName('img');
imageloop[0].src = 'image' + i;
i++
setTimeout(loop,3000);
}
So when one of the li element is being clicked it will change the img currently displaying.
Bind to the list, not the list item - <ul id="ul1">... :
document.getElementById('ul1').addEventListener('click', function (e) {
var li = e.target;
alert(li.id); // list1, list2, respectively, etc.
});
http://jsfiddle.net/seancannon/D6HX4/
As Teemu said, bind to the list and use e.target. Then, change i according to e.target.innerHTML (because for your purposes, that's easier since the innerHTML is similar to the id, but simpler).
Assuming the <ul> element now has an id of "list":
var list = document.getElementById("list");
var i = null;
list.addEventListener("click", function(e) {
window.i = parseInt(e.target.innerHTML, 10);
console.log(window.i);
});
You don't need Separate code for each <li>,
Here is How to do it in single function:
HTML:
<div>
<ul id="All_List">
<li id="list1">1</li>
<li id="list2">2</li>
<li id="list3">3</li>
</ul>
</div>
JavaScript:
var clicked_li=0; /* It'll store the number of <li> being clicked */
var ul=document.getElementById("All_List"); /* <ul> Element with all <li> */
window.onload=function(){
var lis=ul.getElementsByTagName("li"); /* All <li>'s from <ul> */
for(var i=0;i<lis.length;i++){
var li=lis[i]; /* Specific <li> from <ul> ie, lis[0] means first <li> of <ul> */
li.addEventListener("click", function(){ /* Listen and bind click event to that <li> */
clicked_li=getIndex(this); /* Store Which <li> Was clicked in clicked_li */
alert("'list"+clicked_li+"' was clicked!");
/* if you just want to get the id you can use event.target.id; instead of getIndex(); */
}, false);
}
};
function getIndex(node) {
var childs = node.parentNode.getElementsByTagName("li"); /* Get parent <ul> and all child <li> of that parent */
for (var i = 0; i < childs.length; i++) {
if (node == childs[i]) break; /* Find which <li> from current <ul> was clicked */
}
return (i+1); /* Return No.(index) of that <li> starting with 1 */
}
and here is the:
fiddle for the same.
Hope it'll help you. Cheers!
This is an "improve/clearer" of Vedant Terkar answer. Which may give a more clear aspect on
the answer he gave.
if we give ul id group. We dont need id for each of the list-item inside the ul.
<ul id="group">
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
Javascript
var i=0;
we set i to be a global variable and equal to 0 assuming it will display image(0) if nothing else is called.
window.onload=function(){
var lis=document.getElementById("group").getElementsByTagName('li');
We are now creating a Nodelist which is called lis. Then we loop through the NodeList to se which list-element is being clicked at.
for(i=0;i<lis.length;i++){
var li=lis[i];
li.addEventListener("click",index, false);
}
}
function index(){
var lis = document.getElementById("group").getElementsByTagName('li');
i = getIndex(this);
for(var a=0; a < lis.length; a++){
if(a ==i){
lis[i].innerHTML = 'Choosen';
}else{
lis[a].innerHTML = 'list'+a;
}
}
}
function getIndex(node) {
var childs = node.parentNode.getElementsByTagName("li");
for (var i = 0; i < childs.length; i++) {
if (node == childs[i]) break;
}
return (i);
}

Categories

Resources