This question already has answers here:
JS get the clicked element with event.target
(4 answers)
Getting the parent div of element
(7 answers)
Closed 3 years ago.
I am struggling to get the parent of button when it is clicked. This is my HTML structure:
<p><button class="remove">x</button> Hamlet<input value="5"></p>
I don't want to use the ID in button because I have many of the same buttons. Any help is appreciated. Thanks!!!
Like this? Note I delegate from a container
document.getElementById("container").addEventListener("click", function(e) {
let tgt = e.target;
if (tgt.classList.contains("remove")) tgt.closest("p").remove();
})
<div id="container">
<p><button class="remove">x</button> Hamlet<input value="1"></p>
<p><button class="remove">x</button> Ophelia<input value="2"></p>
<p><button class="remove">x</button> Polonius<input value="3"></p>
</div>
For browser that doe not like closest you can use tgt.parentElement.remove()
Maybe consider adding a universal click event to all buttons.
const onClickButton = function () {
// The parent element
const parent = this.parentElement;
parent.style.backgroundColor = 'red';
};
[...document.getElementsByTagName('button')].forEach(button => button.addEventListener('click', onClickButton));
<p>
<button class="remove">x</button>
Hamlet1
<input value="5">
</p>
<p>
<button class="remove">x</button>
Hamlet2
<input value="5">
</p>
<p>
<button class="remove">x</button>
Hamlet3
<input value="5">
</p>
Related
This question already has answers here:
Why can event listeners stop working after using element.innerHTML?
(3 answers)
Closed 1 year ago.
const yazı = document.getElementsByTagName("input")[0]
let buton = document.getElementsByTagName("button")[0]
var kucuk = document.getElementsByClassName("little")[0]
buton.addEventListener("click", function(e) {
kucuk.innerHTML += `
<ul>
<li> ${yazı.value}<span></span></li>
</ul>
`
})
<div class="container">
<h2>a message you would like to pass</h2>
<button>submit</button>
<div class="little">
<input type="text" /><br />
</div>
</div>
It is like a simple Todo Project. The problem is when i click the button it prints the first value in the input everytime. And when i put the button to inside of the little class, it works only in first click nothing more. When i take button and input outside of the little class, it works properly. But i don't understand the core reason of that.
To take the new value of the input you have take the value inside the callback function:
let buton = document.getElementsByTagName("button")[0]
var kucuk = document.getElementsByClassName("little")[0]
buton.addEventListener("click",function (e) {
const yazı = document.getElementsByTagName("input")[0]
kucuk.innerHTML += `
<ul>
<li> ${yazı.value}<span></span></li>
</ul>
`
})
<div class="container">
<h2>a message you would like to pass</h2>
<button>submit</button>
<div class="little">
<input type="text" /><br />
</div>
</div>
Update: When the button is inside the the element with class="little" and you are replacing the html using innerHTML, the button is losing the click event. Use insertAdjacentHTML in that case:
let buton = document.getElementsByTagName("button")[0]
var kucuk = document.getElementsByClassName("little")[0]
buton.addEventListener("click",function (e) {
const yazı = document.getElementsByTagName("input")[0]
kucuk.insertAdjacentHTML('beforeend', `
<ul>
<li> ${yazı.value}<span></span></li>
</ul>
`);
});
<div class="container">
<h2>a message you would like to pass</h2>
<div class="little">
<button>submit</button>
<input type="text" /><br />
</div>
</div>
I am struck in a problem, where I need to point out the current number of the class I am using in JS. For example here is my code:
<div>
<p class="child"><button type="submit" onclick="myfunction()">Click here</button></p>
<p class="child"><button type="submit" onclick="myfunction()">Click here</button></p>
<p class="child"><button type="submit" onclick="myfunction()">Click here</button></p>
<p class="child"><button type="submit" onclick="myfunction()">Click here</button></p>
</div>
Now I know if I type document.getElementsByClassName("child"), it will provide me an array with all the able usage of class p mentioned. However I want to know the exact button which was clicked.
Like if the second button p class was clicked, I want my function to return me the number 2. Similarly if the third button was clicked, I want the number 3 returned to me. Is there any function for that? How should I proceed? I am completely new to JS.
What you're trying to do is called Event Delegation in javascript. You just add the event listener on the parent element in order to avoid having to add event handlers to multiple child elements.
e.target gives you the element on which the event handler (here click) was called on. You can get info regarding that element using various properties like e.target.textContent gives you the button text.
const container = document.querySelector(".container")
container.addEventListener('click',(e)=>{
console.log(e.target)
console.log(e.target.textContent)
})
<div class="container">
<p><button type="button">Click here 1</button></p>
<p><button type="button">Click here 2</button></p>
<p><button type="button">Click here 3</button></p>
<p><button type="button">Click here 4</button></p>
</div>
You can pass this to the function, which is the current element.
I've added code to find all .child elements, and find the index that matches this button's parent, and then alert it.
I would recommend using addEventListener instead of onclick attributes.
Depending on what you are doing, I'd recommend adding data="n" attributes added to the DOM elements, or an object map of values. But this will work as is:
function myfunction(el){
const index = Array.from(document.getElementsByClassName('child'))
.findIndex(x=>x===el.parentNode);
alert(index);
}
<div>
<p class="child"><button type="submit" onclick="myfunction(this)">Click here</button></p>
<p class="child"><button type="submit" onclick="myfunction(this)">Click here</button></p>
<p class="child"><button type="submit" onclick="myfunction(this)">Click here</button></p>
<p class="child"><button type="submit" onclick="myfunction(this)">Click here</button></p>
</div>
You can loop over the list of elements having this class, add the event listener to each item, so you can access the number inside the function normally. Here is an example:
let childs = document.getElementsByClassName('child');
for(let i = 0; i < childs.length; i++){
let el = childs[i];
el.addEventListener('click', function(e){
console.log(i+1);
});
}
<div>
<p class="child"><button type="submit">Click here 1</button></p>
<p class="child"><button type="submit">Click here 2</button></p>
<p class="child"><button type="submit">Click here 3</button></p>
<p class="child"><button type="submit">Click here 4</button></p>
</div>
I am implementing a functionality where every child element has a button that removes that element from the DOM. When there is only one such element left I need it to remove the parent as well.
The problem is that the parent sometimes has before and after elements present, so the check has to take that in to account and probably has to be based on the type of element I am after, namely div.
So I am basically after div:only-of-type but the javascript version, non jquery.
I am imagining something like this:
if (target.parentNode.onlyOfType()) {
//do seomthing
}
You can check the length of children of the parentNode based on which you can you can remove the parent element of the targeted element.
Demo:
var btns = document.querySelectorAll('.myClass');
Array.from(btns).forEach(function(b){
b.addEventListener('click', function(target){
if (this.parentNode.children.length == 1) {
this.parentNode.remove();
}
else alert('Has other child, can not be deleted');
})
});
<div class="">Container 1
<button type="button" class="myClass">Delete</button>
<label>Some Other</label>
</div>
<div class="">Container 2
<button type="button" class="myClass">Delete</button>
</div>
<div class="">Container 3
<label>Some Other</label>
<button type="button" class="myClass">Delete</button>
</div>
If you want to check the type then you can use querySelectorAll() like the following way:
var btns = document.querySelectorAll('.myClass');
Array.from(btns).forEach(function(b){
b.addEventListener('click', function(){
var type = this.type;
if (this.parentNode.querySelectorAll(type).length == 1) {
this.parentNode.remove();
}
else alert('Has other child with same type, can not be deleted');
})
});
<div class="">Container 1
<button type="button" class="myClass">Delete</button>
<label>Some Other</label>
</div>
<div class="">Container 2
<button type="button" class="myClass">Delete</button>
</div>
<div class="">Container 3
<label>Some Other</label>
<button type="button" class="myClass">Delete</button>
<button type="button" class="myClass">Edit</button>
</div>
I'm working on my real-estate project, I have a contact modal box and I want to get the title from tag a into the button value in modal box.
I'm not good at English, if I'm saying something wrong somewhere please forgive me
I have tried many ways but it still doesn't work and the result I get is the title but only works just for 1 id
function change() {
let a_id = document.getElementById('test');
let btn_id = document.getElementById("btn-test");
let btn = a_id.getAttributeNode('title').value;
// btn_id.value = btn;
btn_id.innerHTML = btn_id.value = btn;
}
<body>
<p>Click the button find out if the button has an onclick attribute specified.</p>
hello
<input type="button" onload="change()" title="hello" value="Try it" id="btn-test">
</body>
this is my code https://hastebin.com/ohasiqavun.xml?
You are supposed to use classes instead of ids here. Ids are unique and thus it only works for 1 element.
I just created the following alternative for you to get the values from every button seperate. noticed that I changed the HTML to 3 container who all include the same content. I removed the ID's and changed them for classes:
JS:
let changeallbuttons = document.querySelector('.changeallbuttons')
changeallbuttons.addEventListener('click', function() {
document.querySelectorAll('.container').forEach(item =>{
let button = item.querySelector('input')
let a = item.querySelector('.test')
button.value = a.getAttribute('title')
})
})
document.querySelectorAll('.container').forEach(item =>{
item.addEventListener('click', function() {
let button = item.querySelector('input')
let a = item.querySelector('.test')
button.value = a.getAttribute('title')
})
})
HTML:
<div class="container">
<p>Click the button find out if the button has an onclick attribute specified.</p>
<a href="#" title="bye1" class="test" >hello</a>
<input type="button" title="hello" value="Try it">
</div>
<div class="container">
<p>Click the button find out if the button has an onclick attribute specified.</p>
<a href="#" title="bye2" class="test" >hello</a>
<input type="button" title="hello" value="Try it">
</div>
<div class="container">
<p>Click the button find out if the button has an onclick attribute specified.</p>
hello
<input type="button" title="hello" value="Try it">
</div>
<input class="changeallbuttons" type="button" title="hello" value="Try it">
This question already has answers here:
previousSibling not working
(2 answers)
Closed 6 years ago.
this is demo code so I want only follow the pattern that when user click button it show inner text of anchor in h3 tag .
My Code
var a = document.getElementById('btn');
var b = a.previousSibling.firstChild.innerText;
alert(b);
<div class="box">
<p>This is a paragraph</p>
<h3> Heading </h3>
<button id="btn">Click Me</button>
</div>
I am getting this :
Error is Cannot read property 'innerText' of null
you need to use previousElementSibling instead
var a = document.getElementById('btn');
var b = a.previousElementSibling.firstChild.innerText;
console.log(b);
<div class="box">
<p>This is a paragraph</p>
<h3>Heading</h3>
<button id="btn">Click Me</button>
</div>
Try this,
<div class="box">
<p>This is a paragraph</p>
<h3>Heading</h3>
<button id="btn">Click Me</button>
</div>
var a = document.getElementById('btn') ;
var b = a.previousElementSibling.firstChild.innerText ;
alert(b);
I got your sample working in a fiddle here by eliminating whitespace between the button and the closing </h3> tag: https://jsfiddle.net/shggo1x4/
<div class="box">
<p> This is a paragraph </p><h3> Heading </h3><button id="btn"> Click Me</button>
</div>
var a = document.getElementById('btn') ;
var b = a.previousSibling.firstChild.innerText;
alert(b) ;
previousSibling considers whitespace to be a text node, so as #dippas said, use the previousElementSibling property.