Reputation: 1155
I am creating a simple help page for my app. In it, you'll get some basic documentation on how to navigate and use the site. For each talking point, I am adding a simple questionnaire ("was this helpful?") where the user clicks on the radio buttons (yes or no) and an action generates based on their selection. I was able to successfully add one to the first talking point (see snippet), but when I tried adding it to others, it won't work as when I select "no" the textarea will not appear, nor will the user get a response if they select "yes" (see snippet). I gave the second one it's own ID's and it still will not generate an action. Can someone tell me what I am doing wrong?
<div>
<form id="myForm">
<h4> This is the first one I was able to implement.</h4>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample1" name="groupOfDefaultRadios" value="yes">
<label class="custom-control-label" for="defaultGroupExample1">Yes</label>
</div>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample2" name="groupOfDefaultRadios" value="no">
<label class="custom-control-label" for="defaultGroupExample2">No</label>
</div>
<input class="button" type="button" name="groupOfDefaultRadios" value="Submit">
</form>
</div>
<div id="result" style="display:none"></div>
<div>
<form id="myForm">
<h4> This one does not work</h4>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample3" name="groupOfDefaultRadios" value="yes">
<label class="custom-control-label" for="defaultGroupExample2">Yes</label>
</div>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample4" name="groupOfDefaultRadios" value="no">
<label class="custom-control-label" for="defaultGroupExample3">No</label>
</div>
<input class="button" type="button" name="groupOfDefaultRadios" value="Submit">
</form>
</div>
<div id="result" style="display:none"></div>
<script>
let button = document.querySelector("input.button");
button.addEventListener("click", question1);
function question1() {
var selection = document.querySelector("input[name='groupOfDefaultRadios']:checked");
var result = document.getElementById("result");
if (selection.value == 'yes') {
result.innerHTML = "We're glad you found this helpful.";
result.style.display = "block";
} else {
var output = "";
output += "We're sorry! Please tell us how we can better serve you.<br />";
output += "<textarea style='width: 500px; height 200px;'></textarea><br />";
output += "<button>Submit</button>";
result.innerHTML = output;
result.style.display = "block";
}
}
</script>
Upvotes: 1
Views: 84
Reputation: 5708
Your forms had the same id
and you were assigning an eventListener
to only the first button element that is found on the page. As opposed to .querySelector()
, .querySelectorAll()
finds all the elements on the page that fit the query.
Also since the input buttons
are completely the same (id
, class
, etc.) I used a different approach to obtain the wanted radio buttons
... By finding out the parent
of the clicked button
we can find the radio buttons
within that parent
.
Edit: OP asked if response and textarea can appear for each form separately.
First change is to eliminate more than one element having the same id
on the page (both result divs have the same id
). If really necessary for both to have the same identifier then having the same class
would make sense, not id
. For the purpose of this example we will add a different id
to each result div
and have the id
correlate to the id
of its form
(e.g. form
id is myForm1
while it's respective result div
could have an id
like myForm1Result
).
Try it out below:
let button = document.querySelectorAll("input.button");
button.forEach(function(elem) {
elem.addEventListener("click", question1);
});
function question1() {
let parent = this.parentElement;
let parentId = parent.id;
let resultDivId = parent.id + "Result";
let radioBtns = parent.querySelectorAll('input[type="radio"]');
let yesIsChecked = false;
// find out which one is checked
for(let i=0; i < radioBtns.length; i++) {
let radio = radioBtns[i];
if(radio.value == "yes" && radio.checked) {
yesIsChecked = true;
}
}
let result = document.getElementById(resultDivId);
if (yesIsChecked) {
result.innerHTML = "We're glad you found this helpful.";
result.style.display = "block";
} else {
let output = "";
output += "We're sorry! Please tell us how we can better serve you.<br />";
output += "<textarea style='width: 500px; height 200px;'></textarea><br />";
output += "<button>Submit</button>";
result.innerHTML = output;
result.style.display = "block";
}
}
<div>
<form id="myForm1">
<h4> This is the first one I was able to implement.</h4>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample1" name="groupOfDefaultRadios" value="yes">
<label class="custom-control-label" for="defaultGroupExample1">Yes</label>
</div>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample2" name="groupOfDefaultRadios" value="no">
<label class="custom-control-label" for="defaultGroupExample2">No</label>
</div>
<input class="button" type="button" name="groupOfDefaultRadios" value="Submit">
</form>
</div>
<div id="myForm1Result" style="display:none"></div>
<div>
<form id="myForm2">
<h4> This one does not work</h4>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample3" name="groupOfDefaultRadios" value="yes">
<label class="custom-control-label" for="defaultGroupExample2">Yes</label>
</div>
<div class="custom-control custom-radio">
<input type="radio" class="custom-control-input" id="defaultGroupExample4" name="groupOfDefaultRadios" value="no">
<label class="custom-control-label" for="defaultGroupExample3">No</label>
</div>
<input class="button" type="button" name="groupOfDefaultRadios" value="Submit">
</form>
</div>
<div id="myForm2Result" style="display:none"></div>
Upvotes: 0
Reputation: 104
The document.querySelector(); function only returns the first element match, hence the event listener is only attached to the first button. Try the following code:
let buttons = document.querySelectorAll("input.button");
buttons.forEach(function (button){
button.addEventListener("click", question1);
});
Upvotes: 1