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>
Related
I am creating new rows using jquery and want to delete that row when delete button is pressed. Adding new row part is working fine and the problem is in delete part. When I click on delete button then nothing happens. It doesn't even show alert which is written in code. It seems to me like delete button is not even getting pressed.
How can I delete that particular record when delete button is pressed?
JSfiddle is given below
https://jsfiddle.net/ec2drjLo/
<div class="row">
<div>
Currency: <input type="text" id="currencyMain">
</div>
<div>
Amount: <input type="text" id="amountMain">
</div>
<div>
<button id="addAccount">Add Account</button>
</div>
</div>
<div id="transactionRow">
</div>
As you have added the elements as a string, they are not valid HTML elements and that's why you can't add an event listener. You can add the click event to the document body and capture the event target, like
$(document).on('click', function (e){
if(e.target.className === 'deleteClass'){
//process next steps
}
}
You can try the demo below, not sure if it's the result you need, but the delete button works. Hope it helps!
let accountCount = 0;
$("#addAccount").click(function (e)
{
accountCount++;
let mystring = "<label class=\"ok\" id=\"[ID]\">[value]</label>";
let deleteString = "<button class=\"deleteClass\" id=\"deleteAccount"+ accountCount +"\">Delete Account</button>";
let currency = mystring.replace("[ID]", "currency"+ accountCount).replace("[value]", $("#currencyMain").val());
let amount = mystring.replace("[ID]", "amount"+ accountCount).replace("[value]", $("#amountMain").val());
$("#transactionRow").append(currency);
$("#transactionRow").append(amount);
let div = document.createElement('div');
div.innerHTML =deleteString;
$("#transactionRow").append(div);
$("#currencyMain").val('');
$("#amountMain").val('')
});
$(document).on('click', function (e)
{
if(e.target.className === 'deleteClass'){
var content = $("#transactionRow").html();
var pos = content.lastIndexOf("<label class=\"ok");
if(pos > 5)
$("#transactionRow").html(content.substring(0,pos));
else
alert("You cannot delete this row as at least one Account must be present");
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="row">
<div>
Currency: <input type="text" id="currencyMain">
</div>
<div>
Amount: <input type="text" id="amountMain">
</div>
<div>
<button id="addAccount">Add Account</button>
</div>
</div>
<div id="transactionRow" style="border: 1px solid grey">
</div>
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();
}
<button onclick="myFunction()">Set demo1</button>
<button onclick="myFunction()">Set demo2</button>
<button onclick="myFunction()">Set demo3</button>
<p id="demo1"></p>
<p id="demo2"></p>
<p id="demo3"></p>
This is the markup I have. I am trying to use just one function to update the <p> tags individually.
Example Scenario: Clicking Set demo1 button will only update the <p> which has id="demo1" but with only one function.
Help would be very much appreciated.
You can use following approach. Clicking on each button will affect corresponding p element.
var elems = document.getElementsByClassName('btn');
Array.from(elems).forEach(v => v.addEventListener('click', function(){
var index = this.innerHTML.match(/\d+/)[0];
var elem = document.getElementById('demo'+index);
// logic
elem.style.color = 'red'; // just an example
}));
<button class='btn'>Set demo1</button>
<button class='btn'>Set demo2</button>
<button class='btn'>Set demo3</button>
<p id="demo1">1</p>
<p id="demo2">2</p>
<p id="demo3">3</p>
If you change your markup slightly so that each button has a data-target attribute, then it can be easily done.
HTML:
<button onclick="myFunction()" data-target="#demo1">Set demo1</button>
<button onclick="myFunction()" data-target="#demo2">Set demo2</button>
<button onclick="myFunction()" data-target="#demo3">Set demo3</button>
JS
function myFunction() {
var pTag = document.getElementById(this.getAttribute('data-target'));
pTag.textContent = "Hello world"; // whatever you would like
}
I have buttons that are dynamically created , let say 5 buttons gets created button1, button2, button3, button4, button5. when I click on some button(let say, button1) a div(say div1) is created. And when i click on other button(say button2) another div(say div2) is created. I want to display one at a time. That is, when i click on button1 , div1 should be displayed and rest other div should not be displayed. But in my code when i click on button1, div1 gets created. And when i click on button2 div2 is appended. I want to replace div2 by div1.
I have tried using replaceWith() and checking for siblings also. But it didn't worked.
Here is my code:
javascript:
$(document).ready(function(){
var request = $.ajax({'url': '/FunctionName'});
request.done(function(response)
{
var output = document.getElementById('output');
response = JSON.parse(response)
response.forEach(function(item){
var button = document.createElement("input");
button.type = "button";
button.value = item[0];
button.name= item[0];
button.onclick = createDiv;
output.appendChild(button);
function createDiv() {
var div = document.createElement('div');
div.setAttribute("id", item[0]);
div.setAttribute("class","inner");
div.innerHTML = item[1];
showDiv.appendChild(div);
}
});
});
request.fail(function(jqXHR, textStatus)
{
alert('Request failed: ' + textStatus);
});
});
HTML:
<div id="regex_1" class="tab-pane fade">
<div id="output" class="panel panel-default" style="float:left; width: 30%" >
</div>
<div id="showDiv" class="panel panel-default" style="float:left; width: 70%" >
</div>
</div>
This is a simple replacement div code. Is your expectation?
$(".buttonShowDiv").on("click", function(){
$("#mainDiv .replaceDiv").replaceWith($(this).closest("div").find(".replaceDiv").clone());
$("#mainDiv .replaceDiv").show();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<div class="div1 replaceDiv" hidden="hidden">
<p>This is div 1</p>
</div>
<input type="button" class="buttonShowDiv" value="button 1"/>
</div>
<div>
<div class="div2 replaceDiv" hidden="hidden">
<p>This is div 2</p>
</div>
<input type="button" class="buttonShowDiv" value="button 2"/>
</div>
<div id="mainDiv">
<div class="replaceDiv">
<p>This is default div</p>
</div>
</div>
Add one more class to your divs like 'alldivs'.
So all of your divs will be hidden except for the one you are creating.
function createDiv() {
var alldives=document.getElementsByClassName('alldivs');
alldivs.display='none';
var div = document.createElement('div');
div.setAttribute("id", item[0]);
div.setAttribute("class","inner alldivs");
div.innerHTML = item[1];
showDiv.appendChild(div);
}
This way you can hide all of other divs that you have created before and only show to current one.
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>