Is it possible to get the ids of the 2 div tags on clicking the button, using javascript?
<div id="main">
<div id="content">
</div>
<button onclick="function();">show it</button>
</div>
I have 2 div tags here. The 1st div is in the main div while the content div is inside the main div and the button is inside the main div as well.
Is it possible to get the main and content id of the 2 div tags on clicking the button?
EXPECTED OUTPUT when I press the button:
alert: main
alert: content
You need to pass the element to the function. Then you can use parentNode to get the DIV that contains the button. From there, you can use querySelector to find the first DIV in the parent.
function showIt(element) {
var parent = element.parentNode;
alert(parent.id);
var content = parent.querySelector("div");
alert(content.id);
}
<div id="main">
<div id="content">
</div>
<button onclick="showIt(this);">show it</button>
</div>
<div id="main2">
<div id="content2">
</div>
<button onclick="showIt(this);">show it</button>
</div>
<div id="main3">
<div id="content3">
</div>
<button onclick="showIt(this);">show it</button>
</div>
document.getElementById('button').onclick = function () {
var divs = document.querySelectorAll('div');
for (var i = 0; i < divs.length; i++) {
var id = divs[i].getAttribute('id');
alert(id);
}
};
http://jsfiddle.net/jm5okh69/1/
This should work in all browsers and uses the cleaner .id method.
var button = document.getElementById('button');
button.onclick = getIDs;
function getIDs(){
var id,divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
id = divs[i].id // .id is a method
alert(id);
}
}
<div id="main">
<div id="content"></div>
<button id="button">show it</button>
</div>
Related
I'm learning JavaScript and this is a practice scenario for me.
What I have already is a button that clones content, and within that content that has been cloned, there is a button to remove it.
When I click the button that prompts you to remove the content, it removes the first set of content.
What I want to happen is when you click the button that prompts you to remove the content, it removes the content related to that button and nothing else.
This is the CodePen link.
https://codepen.io/JosephChunta/pen/YzwwgvQ
Here is the code.
function addContent() {
var itm = document.getElementById("newContent");
var cln = itm.cloneNode(true);
document.getElementById("placeToStoreContent").appendChild(cln);
}
function removeContent() {
var x = document.getElementById("content").parentNode.remove();
}
// This is for debug purposes to see which content is which
document.getElementById('orderContent')
.addEventListener('click', function(e) {
const orderedNumber = document.querySelectorAll('.thisIsContent');
let i = 1;
for (p of orderedNumber) {
p.innerText = '' + (i++);
}
});
.contentThatShouldBeHidden {
display: none;
}
<div id="placeToStoreContent">
</div>
<button id="orderContent" onclick="addContent()">Add Content</button>
<div class="contentThatShouldBeHidden">
<div id="newContent">
<div id="content">
<p class="thisIsContent">This is a prompt</p>
<button onclick="removeContent()">Remove this</button>
<hr />
</div>
</div>
</div>
When you'r trying to remove by ID, it takes the first ID it finds.
To remove the correct content, send this onclick.
<button onclick="removeContent(this)">Remove this</button>
And handle it in your function:
function removeContent(el) {
el.parentNode.remove();
}
Example:
function addContent() {
var itm = document.getElementById("newContent");
var cln = itm.cloneNode(true);
document.getElementById("placeToStoreContent").appendChild(cln);
}
function removeContent(el) {
el.parentNode.remove();
}
// This is for debug purposes to see which content is which
document.getElementById('orderContent')
.addEventListener('click', function(e) {
const orderedNumber = document.querySelectorAll('.thisIsContent');
let i = 1;
for (p of orderedNumber) {
p.innerText = '' + (i++);
}
});
.contentThatShouldBeHidden { display: none; }
<div id="placeToStoreContent">
</div>
<button id="orderContent" onclick="addContent()">Add Content</button>
<div class="contentThatShouldBeHidden">
<div id="newContent">
<div id="content">
<p class="thisIsContent">This is a prompt</p>
<button onclick="removeContent(this)">Remove this</button>
<hr />
</div>
</div>
</div>
In your remove button, do this:
<!-- The "this" keyword is a reference to the button element itself -->
<button onclick="removeContent(this)">Remove this</button>
And in your javascript:
function removeContent(element) {
element.parentNode.remove();
}
I'm trying to loop through divs and set the content of a div inside the outer div. I tried this.
Here is the HTML div's I want to loop through and I want to set the content of div with class content-detail with the value for its attribute data-form data.
//the javascript code I used is this
$(function($) {
for (var i of $(".item .content-detail")) {
var container = document.querySelector($(i)[0]);
var formData = $(i).attr("data-formdata");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<div class="item">
<div class="down-div"> </div>
<div class="detail">
<h4>Detail</h4>
<div id="div_" class="content-detail" data-formdata="my Item">
</div>
<div class="text-center">
<button class="btn btn-blue center"> SET !</button>
</div>
</div>
</div>
<div class="item">
<div class="down-div"> </div>
<div class="detail">
<h4>Detail</h4>
<div id="div_" class="content-detail" data-formdata="my Item">
</div>
<div class="text-center">
<button class="btn btn-blue center"> SET !</button>
</div>
</div>
</div>
But am stuck at this point var container = document.querySelector($(i)[0]);
I don't know how to get the jquery selector of that current div to a variable.
This may need some tweaks, but it should be close...
$(function ($) {
$(".item .content-detail").each(function(index, element) {
element.text($(element).attr("data-formdata"))
})
});
Take a look at the .each() method
$(function($) {
for (var i of $(".item .content-detail")) {
//var container = document.querySelector($(i)[0]);
var container = i;
var formData = $(i).attr("data-formdata");
}
});
I just needed the element
If you want to set the content of each DIV, you don't need a for loop. The .text() method takes a callback function, and it will be called on each element that matches the selector. The returned value is used as the new content.
$(".item .content-detail").text(function() {
return $(this).data("formdata");
});
This works.
$(function($) {
$(".item .content-detail").text(function(){
return $(this).attr("data-formdata");
})
});
Can you not just use JS like this:
[UPDATED]
function test() {
var divs = document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
var divsSub = divs[i].getElementById("div_").querySelectorAll(".content-detail");;
for (var iS = 0; iS < divsSub.length; iS++) {
var x = divsSub[iS].getAttribute("data-formdata");
divsSub[iS].innerHTML = x;
}
}
}
Scenario
I would like to get all child nodes of my div and change it color.
Code:
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.childNodes;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
myCollection[i].style.color = "red";
}
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
Error:
This is not working. It seems tha in my collection i have all nodes. h2 p text buton. I Expeceted just p h2 and buton.
EDIT
Explanation
Note: Whitespace inside elements is considered as text, and text is considered as nodes. Comments are also considered as nodes.
So we need to check if node is element node, or use querySelectorAll.
Examples in answers below. Thanks for your help.
Text nodes do not have style attributes. If you want to use childNodes, check that the nodeType is 1 (an Element node) first:
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.childNodes;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
if (myCollection[i].nodeType === 1) myCollection[i].style.color = "red";
}
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
But I would prefer using querySelectorAll and forEach here:
function myFunction() {
document.querySelectorAll('#divv > *')
.forEach(child => child.style.color = "red");
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
(or, you could simply set #divv's style.color to red)
You could use the children property to access the children of a given node:
The ParentNode property children is a read-only property that returns a live HTMLCollection which contains all of the child elements of the node upon which it was called.
- MDN web docs
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.children;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
myCollection[i].style.color = "red";
}
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
Another way to do with ES6 would be to spread the child nodes into an array and loop through them with a .forEach:
const myFunction = () => {
[...document.querySelector('#divv').children].forEach(child => {
child.style.color = 'red';
});
}
<div id="divv">
<div class="child">
I am a child
</div>
<div>
<div class="grandchild">
I am a grand child
</div>
</div>
<button onclick="myFunction()">Try it</button>
</div>
Alternatively, you could use the .forEach from the NodeList class directly but the previous method gives you more freedom to work with Array's method such as .reduce, .map, etc...
const myFunction = () => {
document.querySelectorAll('#divv > *').forEach(child => {
child.style.color = 'red';
});
}
<div id="divv">
<div class="child">
I am a child
</div>
<div>
<div class="grandchild">
I am a grand child
</div>
</div>
<button onclick="myFunction()">Try it</button>
</div>
This code is supposed to be looping and adding multiple divs, but it isn't working. When I click it, only one div appears. If I click again, nothing happens.
<body>
<div class="start" >
<div id = "coba">
</div>
<div id = "cobi">
</div>
</div>
<script>
var divs = document.getElementById("coba").addEventListener("click", function () {
for (var i = 1; i < 100; i++) {
var di = document.createElement('div');
document.getElementById('coba').appendChild(di);
}
});
</script>
</body>
Thanks for your help
Your code does not work because you did not do anything with the variable "i" in the for statement. If you look at the fiddles of user2181397 & meghan Armes you will see how they added a line in the script to put it to work.
I tested the below in my IDE and it works just fine:
<body>
<div class="start" style="margin-top:50px; color:black;">
<div id = "coba">
<p>Click Me</p>
</div>
<div id = "cobi">
</div>
</div>
<script>
var divs = document.getElementById("coba").addEventListener("click", function() {
for (var i = 1; i < 100; i++) {
var di = document.createElement('div');
di.innerHTML=i;
document.getElementById('coba').appendChild(di);
}
});
</script>
</body>
OUTLOOK:
I have a website which has a page called questions.html . In the page , there are many questions with answers. Each question is a div element. The answers is also a div and are hidden initially and is visible only when a button is clicked.
ATTEMPT & PROBLEM:
I have done it successfully for one set of question and answer , but when I do the same for another set the whole system gets messy. When I click on the button on the second question div , the answer div of the first question div shows up. But I want the button on the second question div to open the answer div of the second question div.
HTML :
<div id = "question1">
<div id = "answer1" style = "display:none;">This is the 1st answer</div>
<button id = "button1" onClick = "show()">Click For Answer</button>
</div>
<div id = "question2">
<div id = "answer2" style = "display:none;">This is the 1st answer</div>
<button id = "button2" onClick = "show()">Click For Answer</button>
</div>
JavaScript :
function show()
{
var div=document.getElementById("answer1");
var button=document.getElementById("button1");
div.style.display="block";
button.style.display="none";
}
I also noticed that it happens because my variables div and button wont select the div with the next set of ids (answer2 and button2)
MY APPROACH:
So I thought of creating a new function for each set of question and answer div. But this seems very unprofessional.
So is there any other way?
Thanks for the help :)
Pass the IDs as arguments:
function show(answerID, buttonID)
{
var div=document.getElementById(answerID);
var button=document.getElementById(buttonID);
div.style.display="block";
button.style.display="none";
}
Then the HTML would be:
<div id = "question1">
<div id = "answer1" style = "display:none;">This is the 1st answer</div>
<button id = "button1" onClick = "show('answer1', 'button1')">Click For Answer</button>
</div>
<div id = "question2">
<div id = "answer2" style = "display:none;">This is the 1st answer</div>
<button id = "button2" onClick = "show('answer2', 'button2')">Click For Answer</button>
</div>
If you can use jQuery,
$(".show-answer").on("click", function() {
$(this).siblings(".answer").css("display", "block");
$(this).css("display", "none");
});
.answer {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="question">
<div class="answer">This is the 1st answer</div>
<button class="show-answer">Click For Answer</button>
</div>
<div class="question">
<div class="answer">This is the 1st answer</div>
<button class="show-answer">Click For Answer</button>
</div>
Selection process becomes simple and HTML looks clean.
use previoussibling to show answers div and pass this for button
update there is problem with previoussibling that it consider text as node also so i have provided a function in working demo that can be used to overcome that problem
function show(obj)
{
var div=obj.previousSibling;
var button=obj
div.style.display="block";
button.style.display="none";
}
<div id = "question1">
<div id = "answer1" style = "display:none;">This is the 1st answer</div><button id = "button1" onClick = "show(this)">Click For Answer</button>
</div>
<div id = "question2">
<div id = "answer2" style = "display:none;">This is the 1st answer</div><button id = "button2" onClick = "show(this)">Click For Answer</button>
</div>
function show(obj)
{
console.log(obj.previousSibling)
var div=previousElementSibling(obj);
var button=obj
div.style.display="block";
button.style.display="none";
}
function previousElementSibling( elem ) {
do {
elem = elem.previousSibling;
}
while ( elem && elem.nodeType !== 1 );
return elem;
}
<div id = "question1">
<div id = "answer1" style = "display:none;">This is the 1st answer</div><button id = "button1" onClick = "show(this)">Click For Answer</button>
</div>
<div id = "question2">
<div id = "answer2" style = "display:none;">This is the 1st answer</div><button id = "button2" onClick = "show(this)">Click For Answer</button>
</div>
You don't need all that ID / class trickery,
also using inline JS is quite hard to maintain.
See this instead, where I've only used class="qa"
var qa = document.getElementsByClassName("qa");
function show(){
this.parentNode.getElementsByTagName("DIV")[0].style.display = (this.clicked^=1) ? "block" : "none";
}
for(var i=0; i<qa.length; i++)
qa[i].getElementsByTagName("BUTTON")[0].addEventListener("click", show, false);
div.qa > div{
display:none;
}
<div class="qa">
<div>This is the 1st answer</div>
<button>Click For Answer</button>
</div>
<div class="qa">
<div>This is the 1st answer</div>
<button>Click For Answer</button>
</div>
You can even use pure CSS for this, by just replacing button with a and usign the :target pseudo selector
div.qa > div{
display:none;
}
div.qa > div:target{
display:block;
}
<div class="qa">
<div id="one">This is the 1st answer</div>
Click For Answer
</div>
<div class="qa">
<div id="two">This is the 2nd answer</div>
Click For Answer
</div>