Toggle Checkbox upon clicking on Span - javascript

I'm working on an assignment that needs to, upon the click of a span element's text in an input div, output the same text in an output div. That part I've done successfully, but to the left of each span element within the input div is a checkbox that needs to also be checked upon the click of said span element.
I am not allowed to target each individual checkbox with its own unique ID because I will be adding in newer checkboxes and span elements later with the press of a button and prompt. This is an assignment on event delegation.
I will then need to be able to uncheck the checkbox and remove the appended output, but first things first, I cannot figure out how to target the checkboxes. The only thing I can think of is to somehow say that whatever index number of said span element was clicked would be the index number of said checkbox is clicked, but I'm unsure if that is the best method as well as how to go about doing that.
Also, this assignment should not have any JQuery involved. My next project is actually to redo this assignment in JQuery. Any help would be appreciated!
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Canvas Document Object Model Exercise</title>
<link rel="stylesheet" href="canvas_stylesheet.css">
</head>
<body>
<div id="input">
<form>
<input class="checkbox" type="checkbox"><span class="values">Apple</span></br></br>
<input class="checkbox" type="checkbox"><span class="values">Mango</span></br></br>
<input class="checkbox" type="checkbox"><span class="values">Grape</span></br></br>
<input class="checkbox" type="checkbox"><span class="values">Strawberry</span></br></br>
<input class="checkbox" type="checkbox"><span class="values">Cherry</span>
</form>
</div>
<div id="output"></div>
CSS:
#input {
width: 250px;
height: 300px;
float: left;
padding: 20px 0 30px 15px;
border-style: solid;
border-color: black;
border-width: 1px;
}
.values {
display: inline;
}
/*
#input form input {
padding: 20px 20px 20px 20px;
}
*/
#output {
width: 225px;
height: 326px;
float: left;
border-top: 1px solid black;
border-right: 1px solid black;
border-bottom: 1px solid black;
padding: 4px 20px 20px;
}
JS:
window.onload = UncheckAll;
function UncheckAll() {
var w = document.getElementsByTagName('input');
for (var i = 0; i < w.length; i++) {
if (w[i].type == 'checkbox') {
w[i].checked = false;
}
}
}
document.getElementById("input").addEventListener("click", function(e){
if (e.target.nodeName === "SPAN") {
var node = document.createElement("P");
var textnode = document.createTextNode(e.target.innerHTML);
node.appendChild(textnode);
document.getElementById("output").appendChild(node);
node.setAttribute("class", "outputItem")
}
});

Just surround your checkboxes elements with label, like I did here.
Ps: plese never write a br element like this </br>, its <br> with no slash at all
window.onload = UncheckAll;
function UncheckAll() {
var w = document.getElementsByTagName('input');
for (var i = 0; i < w.length; i++) {
if (w[i].type == 'checkbox') {
w[i].checked = false;
}
}
}
document.getElementById("input").addEventListener("click", function(e){
if (e.target.nodeName === "SPAN") {
var node = document.createElement("P");
var textnode = document.createTextNode(e.target.innerHTML);
node.appendChild(textnode);
document.getElementById("output").appendChild(node);
node.setAttribute("class", "outputItem")
}
});
#input {
width: 250px;
height: 300px;
float: left;
padding: 20px 0 30px 15px;
border-style: solid;
border-color: black;
border-width: 1px;
}
.values {
display: inline;
}
/*
#input form input {
padding: 20px 20px 20px 20px;
}
*/
#output {
width: 225px;
height: 326px;
float: left;
border-top: 1px solid black;
border-right: 1px solid black;
border-bottom: 1px solid black;
padding: 4px 20px 20px;
}
<!DOCTYPE html>
<html>
<head>
<title>Canvas Document Object Model Exercise</title>
<link rel="stylesheet" href="canvas_stylesheet.css">
</head>
<body>
<div id="input">
<form>
<label>
<input class="checkbox" type="checkbox"><span class="values">Apple</span>
</label>
<br><br>
<label>
<input class="checkbox" type="checkbox"><span class="values">Mango</span>
</label>
<br><br>
<label>
<input class="checkbox" type="checkbox"><span class="values">Grape</span>
</label>
<br><br>
<label>
<input class="checkbox" type="checkbox"><span class="values">Strawberry</span>
</label>
<br><br>
<label>
<input class="checkbox" type="checkbox"><span class="values">Cherry</span>
</label>
</form>
</div>
<div id="output"></div>
</body>
</html>

I realized the answer was to use .previousSibling and .nextSibling after posting the question, so I went ahead and finished all the code for the input/output part of the assignment. Then, I realized someone else mentioned .previousSibling in response to the first answer attempt. Thanks everyone!
window.onload = UncheckAll;
function UncheckAll() {
var w = document.getElementsByTagName('input');
for (var i = 0; i < w.length; i++) {
if (w[i].type == 'checkbox') {
w[i].checked = false;
}
}
}
document.getElementById("input").addEventListener("click", function(e){
//Click Input Text - Box Checks and Output Text Appears
if (e.target.nodeName === "SPAN") {
if (e.target.previousSibling.checked === false) {
var node = document.createElement("P");
var textnode = document.createTextNode(e.target.innerHTML);
node.appendChild(textnode);
document.getElementById("output").appendChild(node);
node.setAttribute("class", "outputItem")
e.target.previousSibling.checked = true;
return;
}
}
//Click Input Text - Box Unchecks and Output Text Disappears
if (e.target.nodeName === "SPAN") {
if (e.target.previousSibling.checked === true) {
for (i = 0; i < document.getElementsByClassName("outputItem").length; i++) {
if (e.target.innerHTML === document.getElementsByClassName("outputItem")[i].innerHTML) {
document.getElementsByClassName("outputItem")[i].remove();
e.target.previousSibling.checked = false;
return;
}
}
}
}
//Check Box - Output Text Appears
if (e.target.type === "checkbox") {
if (e.target.checked === true) {
var node = document.createElement("P");
var textnode = document.createTextNode(e.target.nextSibling.innerHTML);
node.appendChild(textnode);
document.getElementById("output").appendChild(node);
node.setAttribute("class", "outputItem")
return;
}
}
//Uncheck Box - Output Text Disappears
if (e.target.type === "checkbox") {
if (e.target.checked === false) {
for (i = 0; i < document.getElementsByClassName("outputItem").length; i++) {
if (e.target.nextSibling.innerHTML === document.getElementsByClassName("outputItem")[i].innerHTML) {
document.getElementsByClassName("outputItem")[i].remove();
return;
}
}
}
}
});

Related

How to use an if statement with OR inside a for loop

I want when the user clicks to goto the next page or previous page that an if statement checks all checkboxes whether they are ticked or not and only if all is ticked then show the alert("yay") message im struggling to use an if statement with the OR inside a for loop iteration whereby i tick checkbox 1 only and it displays the alert("yay") message which i dont want i need it to check all checkboxes first then display the alert("yay") message,thank you
/* This function basically gets the element id name for each checkbox*/
function getText(j){
var j = document.getElementById("text"+j).name;
return j;
}
/* This function basically gets the element id of each checkbox thats passed into y
as a number and returns either that checkbox is true or false*/
function getBoolean(y){
var y = document.getElementById("text"+y).checked;
return y;
}
/* This function basically counts how many Li elements excluding the second level Li elements*/
function getLengthLi(){
var e = document.querySelectorAll('#list > li').length;
return e;
}
function checkTicks(){
for(i = 1;i < getLengthLi()+1;i++){
console.log(getText([i])+"="+getBoolean([i]));
if (!getBoolean([i]) ){
alert("Please read and check all boxes");
break;
}else
alert("yay you read each point and ticked all boxes");
break;
}
}
body{
background-image: linear-gradient(#66ff33, yellow);
}
#footer{
font-weight: bold;
font-size:36px;
border: 2px solid black;
background-image: linear-gradient(#ccdae6, #eaead5);
}
a{
border: 2px solid black;
text-decoration:none;
font-size:36px;
background-color:orange;
}
a:hover{
background-color:black;
//background-color:#ccdae6;
}
h1{
border: 2px solid black;
background-image: linear-gradient(#ccdae6, #eaead5);
}
h2{
border: 2px solid black;
background-image: linear-gradient(#ccdae6, #eaead5);
}
#menu{
border: 2px solid black;
line-height: 1.6;
top:0;
left:0;
overflow-wrap: break-word;
float:left;
word-wrap: break-word;
hyphens: auto;
height:auto;
}
ol {
list-style-type: none;
counter-reset: item;
margin: 0;
padding: 0;
}
ol > li {
display: table;
counter-increment: item;
margin-bottom: 0.6em;
}
ol > li:before {
content: counters(item, ".") ". ";
display: table-cell;
padding-right: 0.6em;
}
li ol > li {
margin: 0;
}
li ol > li:before {
content: counters(item, ".") " ";
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=page-width, initial-scale=1.0">
<title>Simple item checkbox</title>
<link rel="stylesheet" href="textpages.css" />
<script src="page6.js"></script>
</head>
<body>
<center>
<div id="menu">
<h1>Page 6</h1>
<h2>Please tick all checkboxes to proceed to the next page<h2>
<ol id="list">
<input type="checkbox" name="text1" id="text1"><li>list1</li>
<input type="checkbox" name="text2" id="text2"><li>list2</li>
<input type="checkbox" name="text3" id="text3"><li>list3</li>
<input type="checkbox" name="text4" id="text4"><li>list4</li>
<input type="checkbox" name="text5" id="text5"><li>list5</li>
<input type="checkbox" name="text6" id="text6"><li>list6</li>
<input type="checkbox" name="text7" id="text7"><li>list7</li>
<input type="checkbox" name="text8" id="text8"><li>list8</li>
</ol>
</div>
<a onclick="checkTicks()">Previous Page</a>
<a onclick="checkTicks()">Next Page</a>
You should try with a While loop:
function checkTicks(){
bool check = 1;
int i = 1;
while(check==1 && i< getLengthLi()+1){
console.log(getText([i])+"="+getBoolean([i]));
if (!getBoolean([i]))check = 0;
i++;
}
if(!check) alert("Please read and check all boxes");
else alert("yay you read each point and ticked all boxes");
}
Simply put:
Return on fail from within the loop (thus short circuiting it)
If you exit the loop, then everything is checked, and you can display the success message.
function checkTicks(){
for(i = 1;i < getLengthLi()+1;i++){
console.log(getText([i])+"="+getBoolean([i]));
if (!getBoolean([i]) ){
alert("Please read and check all boxes");
return; // Exits the function
}
}
alert("yay you read each point and ticked all boxes");
}

Open new Tab window in Radio Button?

please anyone can help me I am stuck in radio buttons.
when user click on submit button under the radio buttons they should be redirected into new window like target="_blank"
please help me if there is any solution available.
then I change window.location.href
two window.open the code is not working properly
function getCheckedValue(radioObj) {
if(!radioObj)
return "";
var radioLength = radioObj.length;
if(radioLength == undefined)
if(radioObj.checked)
return radioObj.value;
else
return "";
for(var i = 0; i < radioLength; i++) {
if(radioObj[i].checked) {
return radioObj[i].value;
}
}
return "";
}
// set the radio button with the given value as being checked
// do nothing if there are no radio buttons
// if the given value does not exist, all the radio buttons
// are reset to unchecked
function setCheckedValue(radioObj, newValue) {
if(!radioObj)
return;
var radioLength = radioObj.length;
if(radioLength == undefined) {
radioObj.checked = (radioObj.value == newValue.toString());
return;
}
for(var i = 0; i < radioLength; i++) {
radioObj[i].checked = false;
if(radioObj[i].value == newValue.toString()) {
radioObj[i].checked = true;
}
}
}
input[type=radio] {
-webkit-appearance: radio;
-O-appearance: radio;
-moz-appearance: radio;
opacity:1;
}
#header .bottom-header.blog h1 {
font-size: 64px;
color: red
}
input[type=radio]:hover + label {
border: solid 1px white; padding: 5px; border-radius: 1px;
border-color : red;
color : red;
opacity:1;
}
input[type=radio]:checked + label {
border: solid 2px white; padding: 5px; border-radius: 1px;
border-color : red;
color : red;
opacity:1;
}
input[type=text] {
font-weight:bold;
}
input[type=text]:hover {
}
input[type=email]:hover {
}
<form name="radioExampleForm" method="get" action="" onsubmit="return false;">
<p> <label for="number0"><input type="radio" value="http://www.google.com" name="number" id="number0"> Zero</label></br>
<label for="number1"><input type="radio" value="http://www.ebay.com" name="number" id="number1"> One</label></br>
<label for="number2"><input type="radio" value="http://www.gamestop.com" name="number" id="number2"> Two</label></br>
</p>
<input type="button" onclick="window.location.href = (getCheckedValue(document.forms['radioExampleForm'].elements['number']));" value="Buy Now">
</form>
You should use window.open(url, '_blank') which will open the url in new tab. Again I would say opening in new tab will get certainly get struck by a popup blocker. I would recommend you using an anchor tag with target="_blank" in place of button (and change a tag's href in onchange of radio button) which will not get blocked by a popup blocker
function getCheckedValue(radioObj) {
if(!radioObj)
return "";
var radioLength = radioObj.length;
if(radioLength == undefined)
if(radioObj.checked)
return radioObj.value;
else
return "";
for(var i = 0; i < radioLength; i++) {
if(radioObj[i].checked) {
return radioObj[i].value;
}
}
return "";
}
// set the radio button with the given value as being checked
// do nothing if there are no radio buttons
// if the given value does not exist, all the radio buttons
// are reset to unchecked
function setCheckedValue(radioObj, newValue) {
if(!radioObj)
return;
var radioLength = radioObj.length;
if(radioLength == undefined) {
radioObj.checked = (radioObj.value == newValue.toString());
return;
}
for(var i = 0; i < radioLength; i++) {
radioObj[i].checked = false;
if(radioObj[i].value == newValue.toString()) {
radioObj[i].checked = true;
}
}
}
input[type=radio] {
-webkit-appearance: radio;
-O-appearance: radio;
-moz-appearance: radio;
opacity:1;
}
#header .bottom-header.blog h1 {
font-size: 64px;
color: red
}
input[type=radio]:hover + label {
border: solid 1px white; padding: 5px; border-radius: 1px;
border-color : red;
color : red;
opacity:1;
}
input[type=radio]:checked + label {
border: solid 2px white; padding: 5px; border-radius: 1px;
border-color : red;
color : red;
opacity:1;
}
input[type=text] {
font-weight:bold;
}
input[type=text]:hover {
}
input[type=email]:hover {
}
<form name="radioExampleForm" method="get" action="" onsubmit="return false;">
<p> <label for="number0"><input type="radio" value="http://www.google.com" name="number" id="number0"> Zero</label></br>
<label for="number1"><input type="radio" value="http://www.ebay.com" name="number" id="number1"> One</label></br>
<label for="number2"><input type="radio" value="http://www.gamestop.com" name="number" id="number2"> Two</label></br>
</p>
<input type="button" onclick="window.open(getCheckedValue(document.forms['radioExampleForm'].elements['number']), '_blank');" value="Buy Now">
</form>
Use the below script to do your task
$("input[type='button']").click(function(){
var numbers = document.getElementsByName('number');
var num_value;
for(var i = 0; i < numbers.length; i++){
if(numbers[i].checked){
num_value = numbers[i].value;
// alert(num_value);
window.open(num_value, '_blank');
}
}
});

Checking if checked radio button is returning true but should be false

This question is NOT like this. The problem here is stemming from an if condition that is retaining a prior value, while the other question is asking how to determine what type of input is shown on screen.
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script type="text/javascript">
function displayquestion(a, ignore){
var b = a-1;
var currentInput = '';
var questions = document.getElementsByClassName("questionholder");
var showRequired = document.getElementById("requiredMessage");
function showNext (){
showRequired.style.display = "none";
for(var i=0; i < questions.length; i++) {
questions[i].style.display = "none";
}
var nextQuestion = document.getElementById("question" + a);
if(nextQuestion !== null) {
nextQuestion.style.display = "block";
}
}
// Check if question should ignore inputs
if (ignore == 1) { // yes, ignore the inputs so move on to next question
console.log("path 1");
showNext();
} else { //no, don't ignore the inputs
if (document.querySelector('input.input' + b).type == "radio") { //this is a radio input
if (document.querySelector('input[type=radio]:checked')) { //a radio option is selected
console.log("path 2");
showNext();
} else { // no radio option is selected so show error
console.log("path 3");
showRequired.style.display = "block";
}
} else { // not a radio input
if (document.querySelector('input.input' + b) !== null) {
var currentInput = document.querySelector('input.input' + b).value;
}
if (currentInput == '') { // the input is blank so show error
console.log("path 4");
showRequired.style.display = "block";
} else { // the input is not blank so move on to next question
console.log("path 5");
showNext();
}
}
}
}
</script>
</head>
<body>
<div id="requiredMessage" style="display:none">
<p>This field is required.</p>
</div>
<form id="TheForm" style="display:block;">
<div data-toggle="buttons" class="questionholder multiplechoice" id="question13" style="display:block">
<h5>The world is... </h5>
<input class="input13" type="radio" id="round" name="isPrevRel" value="round">
<label for="round">
<p class="radioChoice">round</p>
</label>
<br>
<input class="input13" type="radio" id="square" name="isPrevRel" value="square">
<label for="birthcombo">
<p class="radioChoice">Square</p>
</label>
<br>
<a class="text2button radio" onclick="displayquestion(14)">Next</a>
</div>
<div data-toggle="buttons" class="questionholder multiplechoice" id="question14" style="display:none">
<h5>Do you like snow?</h5>
<input class="input14" type="radio" id="yes" name="snow" value="yes">
<label for="yes">
<p class="radioChoice">Yes. If you'd like, explain why</p>
</label>
<input class="input14" type="radio" id="no" name="snow" value="no">
<label for="no">
<p class="radioChoice">No</p>
</label>
<br>
<input name="relSNonID1"><br>
<a class="text2button radio" onclick="displayquestion(15)">Next</a>
</div>
</form>
</body>
</html>
I have issues with my javascript function, which works as intended with input text fields AND with radio buttons, but not when the two are combined.
In short, I have a div that asks a questions and contains a pair of radio buttons, a text input, and a next button. When the user click next, the function displayquestion(a) fires.
The function checks to see if it is told to ignore the current question. If so, it hides the div and displays the next question.
If not, it checks to see if the document contains an input with a class of input# (where # corresponds to the div id question#) is a radio input. If it is, it checks to see if an of the radio options is selected. If none are selected, it shows an error message.
Otherwise, if the input is not a radio input, it checks to see if the input is blank. If it is blank, it shows an error message. If it is not blank, it hides the div.
It works as intended but only if the shown div contains ONLY a radio option set OR a text input.
As you can see, I have one question where a radio option must be made, with an optional text input.
The intended result should be that the error message displays until the user makes a radio selection. it does not matter if the text input is completed. Only if a radio option is selected and when the user clicks next, it should hide the div.
Instead, what happens is that the div hides whether the user does nothing at all, or makes a choice.
From what I've gathered, the issue is stemming from
document.querySelector('input[type=radio]:checked')
Where it appears that the condition is retaining its value from question 13 (the first div) even when the user sees question 14 (the second div). I know this because the console log is printing the same values when clicking next on both divs.
I believe it is because i'm not checking for input + b but I am unable to add the varible. What is the proper integration?
jsfiddle
Your primary issue is that when you are testing for checked radio buttons, it checks across all radio buttons in the page, not just the ones which are in the currently visible question. It's not a case of the variable "retaining" its value, it's simply that the scope of the selector is too broad, and it will return the first selected checkbox it finds - in this case, there happens to already be one from a previous question, so it returns that.
A couple of small changes can a) make your code a bit more efficient (less repeated querying of the same thing, and b) resolve your issue
1) for efficiency and readability, put the result of document.querySelector('input.input' + b); into a variable so you don't have to run the same query repeatedly in the if statements
2) to check if a radio button is selected within the current question, add a restriction to the selector to narrow the scope into the current question: document.querySelector("#question" + b + " input[type=radio]:checked")
3) There was an error which prevented the "Square" option from being selected in the first question - the accompanying label's for attribute was wrong, it should be <label for="square">
By the way I don't think it's possible or desirable to combine the two tests (as you mention in the comments) because they don't do the same thing. The first test checks what kind of input the first input in the question is, and the second test checks the status of that input (once we know it's definitely a radio button).
Demo:
function displayquestion(a, ignore) {
var b = a - 1;
var currentInput = '';
var questions = document.getElementsByClassName("questionholder");
var showRequired = document.getElementById("requiredMessage");
function showNext() {
showRequired.style.display = "none";
for (var i = 0; i < questions.length; i++) {
questions[i].style.display = "none";
}
var nextQuestion = document.getElementById("question" + a);
if (nextQuestion !== null) {
nextQuestion.style.display = "block";
}
}
// Check if question should ignore inputs
if (ignore == 1) { // yes, ignore the inputs so move on to next question
console.log("path 1");
showNext();
} else { //no, don't ignore the inputs
var input = document.querySelector('input.input' + b);
if (input.type == "radio") { //this is a radio input
if (document.querySelector("#question" + b + " input[type=radio]:checked")) { //a radio option is selected
console.log("path 2");
showNext();
} else { // no radio option is selected so show error
console.log("path 3");
showRequired.style.display = "block";
}
} else { // not a radio input
if (input !== null) {
var currentInput = input.value;
}
if (currentInput == '') { // the input is blank so show error
console.log("path 4");
showRequired.style.display = "block";
} else { // the input is not blank so move on to next question
console.log("path 5");
showNext();
}
}
}
}
body {
font-family: arial;
}
h1 {
font-size: 0.75em;
}
h5 {
font-size: 0.5em;
line-height: 1.5em;
margin-block-start: 0;
margin-block-end: 0;
}
h6 {
font-size: 0.35em;
margin-block-start: 0;
margin-block-end: 0;
}
br {
line-height: 0.2em;
}
p {
display: block;
margin-block-start: 0;
margin-block-end: 0;
margin-inline-start: 0px;
margin-inline-end: 0px;
}
.Title {
text-align: center;
font-size: 3em;
text-decoration: underline;
}
form {
margin: 0 auto;
width: 75%;
text-align: center;
font-size: 3em;
}
form#filledForm {
display: table;
table-layout: fixed;
margin: 0 auto;
width: 100%;
font-size: 1em;
}
form#filledForm th {
text-align: left;
}
form#filledForm td {
width: auto;
font-size: 0.75em;
vertical-align: bottom;
}
form#filledForm tr.aligncenter td {
font-size: 0.75em;
vertical-align: initial;
}
form#filledForm input[name=relSNonID1] {
margin-top: 0;
}
form#filledForm input[name=relSNonID2] {
margin-top: 0;
}
.questionholder {
display: none;
}
input {
line-height: 1em;
font-size: 1em;
text-align: center;
width: 100%;
margin-bottom: 0.5em;
}
input[name=relSNonID1] {
margin-top: 0.2em;
}
input[name=relSNonID2] {
margin-top: 0.2em;
}
input[type=radio] {
margin-bottom: 0;
visibility: hidden;
}
input[type="radio"]:checked+label {
border-style: solid;
padding: 10px;
}
div[data-toggle="buttons"] label.active {
color: #7AA3CC;
}
div[data-toggle="buttons"] label {
display: inline-block;
margin-bottom: 0;
vertical-align: top;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
div[data-toggle="buttons"] label:hover {
color: #7AA3CC;
}
div[data-toggle="buttons"] label:active,
div[data-toggle="buttons"] label.active {
-webkit-box-shadow: none;
box-shadow: none;
}
.text2button {
border-style: solid;
padding: 10px;
cursor: pointer;
}
.multiplechoice {
line-height: 0.5em;
}
.radio {
line-height: 2em;
}
.radioChoice {
font-size: 0.5em;
cursor: pointer;
}
#result p {
text-align: center;
font-size: 2em;
}
<div id="requiredMessage" style="display:none">
<p>This field is required.</p>
</div>
<form id="TheForm" style="display:block;">
<div data-toggle="buttons" class="questionholder multiplechoice" id="question13" style="display:block">
<h5>The world is... </h5>
<input class="input13" type="radio" id="round" name="isPrevRel" value="round"><label for="round"><p class="radioChoice">round</p></label><br>
<input class="input13" type="radio" id="square" name="isPrevRel" value="square"><label for="square"><p class="radioChoice">Square</p></label><br>
<a class="text2button radio" onclick="displayquestion(14)">Next</a>
</div>
<div data-toggle="buttons" class="questionholder multiplechoice" id="question14" style="display:none">
<h5>Do you like snow?</h5>
<input class="input14" type="radio" id="yes" name="snow" value="yes"><label for="yes"><p class="radioChoice">Yes. If you'd like, explain why</p></label>
<input class="input14" type="radio" id="no" name="snow" value="no"><label for="no"><p class="radioChoice">No</p></label><br>
<input name="relSNonID1"><br>
<a class="text2button radio" onclick="displayquestion(15)">Next</a>
</div>
</form>

How to show/hide menu based on checkbox(s) value with JavaScript?

Update 10/4/18: I've updated the Snippet to reflected changes for anyone who may stumble upon this thread in seek of help. Existing check-boxes and newly added check-boxes will open/close the menu.
var statusChangeMenu, activeList, itemCheckBox, activeItems;
statusChangeMenu = document.getElementById("status-change-menu");
activeList = document.getElementById("active-items");
itemCheckBox = activeList.getElementsByClassName("item-checkbox");
activeItems = activeList.getElementsByClassName("active-item-text");
function addNewItem(event) {
event.preventDefault();
activeList.insertAdjacentHTML("afterbegin", "\
<li class=\"item\">\
<input class=\"item-checkbox\" type=\"checkbox\" name=\"checkbox\" />\
<span class=\"active-item-text\"></span>\
<button class=\"btn-complete\">complete</button>\
</li>");
activeItems[0].textContent = document.getElementById("new-item-text").value;
}
document.getElementById("btn-add-item").addEventListener("click", addNewItem, false);
activeList.addEventListener("change", function() {
var i, len;
for (i = 0, len = itemCheckBox.length; i < len || (i = 0); ++i) {
if (itemCheckBox[i].checked) {
i = 40;
break;
}
}
statusChangeMenu.style.height = i + "px";
}, false);
*{
margin: 0;
padding: 0;
}
body{
background-color: #393F4D;
}
header{
background-color: #1D1E22;
color: #FEDA6A;
text-align: center;
font-size: 10px;
}
main{
background-color: #707070;
max-width: 700px;
margin: auto;
margin-top: 20px;
padding: 15px;
}
#status-change-menu{
background-color: rgb(218, 123, 123);
margin-top: 10px;
height: 0px;
overflow: hidden;
transition: all .25s ease-in-out;
}
#status-change-menu>button>img{
height: 40px;
}
form{
background-color: #D4D4DC;
padding: 10px;
text-align: right;
box-shadow: 1px 1px 3px;
}
#new-item-text{
width: 100%;
}
#btn-add-item{
padding: 5px;
box-shadow: 1px 1px 3px;
}
.item-list-container{
background-color: #D4D4DC;
margin-top: 20px;
box-shadow: 1px 1px 3px;
}
.item{
background-color: rgb(165, 233, 222);
list-style: none;
display: grid;
grid-template-columns: auto 1fr max-content;
grid-template-rows: 30px;
margin-top: 10px;
}
.item-checkbox{
grid-column: 1/2;
width: 30px;
margin:auto;
}
.active-item-text{
grid-column: 2/3;
background: rgb(252, 252, 252);
overflow: hidden;
}
.btn-complete{
grid-column: 3/4;
}
.item>input{
height: 20px;
}
<body id="the-list">
<header>
<h1>The List V4</h1>
</header>
<main>
<form action="#">
<textarea name="textbox" id="new-item-text" cols="30" rows="1"></textarea>
<button type="submit" id="btn-add-item">Add</button>
</form>
<div id="status-change-menu" class="change-menu">
<h3>Status Change Menu</h3>
<button class="btn-bar-hold">BTN1<img src="img/btn_hold.svg" alt=""></button>
<button class="btn-bar-delete">BTN2<img src="img/btn_delete.svg" alt=""></button>
</div>
<div class="item-list-container">
<ul id="active-items" class="item-list">
<li class="item">
<input class="item-checkbox" type="checkbox" name="checkbox">
<span class="active-item-text">random text text random</span>
<button class="btn-complete">complete</button>
</li>
<li class="item">
<input class="item-checkbox" type="checkbox" name="checkbox">
<span class="active-item-text">random text text random</span>
<button class="btn-complete">complete</button>
</li>
</ul>
</div>
</main>
</body>
I'm working on a simple checklist web app using pure vanilla HTML, CSS, javascript. I've been stuck in one part all weekend. Hoping someone can shed some light on what I'm missing or doing wrong. Here's where I'm at.
My Goal
Whenever an item in the checklist (ul) is selected (via checkbox), a hidden menu slides out with various options to manipulate the selected item(s). The menu must stay visible if any of the checkboxes on the list are checked. The menu must close if no checkboxes are checked.
Where I'm Stuck
I'm able to get the menu to slide out during a 'change' event of the checkbox, but I can't get the menu element to react after the initial change event. During debugging, it also appears the menu element is not reacting to the checkbox is in a 'checked' state, but simply just reacting to the checkbox being changed in general. Here's the JS code I have, but I've tested various other configurations with no success.
Code Pen with Full Code & Snippet of related JS code below.
Updated Codepen 10/4/18
https://codepen.io/skazx/pen/mzeoEO?
var itemCheckBox = document.querySelectorAll('input[type="checkbox"]')
var statusChangeMenu = document.getElementById("status-change-menu")
for(var i = 0 ; i < itemCheckBox.length; i++){
itemCheckBox[i].addEventListener("change", function(){
if (!itemCheckBox.checked)
{statusChangeMenu.style.height = "40px";}
else
{statusChangeMenu.style.height = "0px";}
})}
I've read a few dozen different post and articles, but most were related to only having 1 checkbox or used jquery. Let me know if you need any further details. Thank you!
itemCheckBox refers to a NodeList returned by querySelectorAll, not an individual element, so saying itemCheckBox.checked doesn't really make sense.
You should be checking if any checkbox in the list is checked, which you can use with the .some() function, like so:
Here's a working demo
for (var i = 0; i < itemCheckBox.length; i++) {
itemCheckBox[i].addEventListener("change", function(event) {
if (!event.target.checked) {
statusChangeMenu.style.height = "40px";
} else {
statusChangeMenu.style.height = "0px";
}
});
}
var itemCheckBox = document.querySelectorAll('input[type="checkbox"]');
var statusChangeMenu = document.getElementById("status-change-menu");
function changeHandler (event) {
// get the list of checkboxes in real time in case any were added to the DOM
var checkboxes = document.querySelectorAll('input[type="checkbox"]');
var anyChecked = [].some.call(checkboxes, function(checkbox) { return checkbox.checked; });
// alternatively (instead of using .some()):
// var anyChecked = false;
// checkboxes.forEach(function (checkbox) {
// if (checkbox.checked) {
// anyChecked = true;
// }
// });
if (anyChecked) {
statusChangeMenu.style.height = "40px";
} else {
statusChangeMenu.style.height = "0px";
}
}
for (var i = 0; i < itemCheckBox.length; i++) {
itemCheckBox[i].addEventListener("change", changeHandler);
}
for (var i = itemCheckBox.length; i < itemCheckBox.length + 2; i++) {
// add some checkboxes dynamically
var newCheckbox = document.createElement("input");
var newLabel = document.createElement("label");
newLabel.innerText = "Checkbox " + (i + 1);
newCheckbox.type = "checkbox";
// -- IMPORTANT-- bind event listener on dynamically added checkbox
newCheckbox.addEventListener("change", changeHandler);
newLabel.appendChild(newCheckbox);
newLabel.appendChild(document.createElement("br"));
document.body.appendChild(newLabel);
}
#status-change-menu {
height: 0;
background-color: red;
overflow: hidden;
color: white;
font-weight: bold;
}
<div id="status-change-menu">I should be visible if any checkboxes are checked</div>
<label>Checkbox 1<input type="checkbox"/></label><br/>
<label>Checkbox 2<input type="checkbox"/></label><br/>
<label>Checkbox 3<input type="checkbox"/></label><br/>
mhodges is correct in that itemCheckBox is a NodeList, not an individual element. Another issue is that you are trying to test if the box that changed is checked, and if it isn't, you are closing the menu. As you described, that is not what you want.
You need another way to check to see if all check boxes are unchecked before you close the menu. A simple way to do that is just another inner loop in the onChange function:
for(var i = 0 ; i < itemCheckBox.length; i++){
itemCheckBox[i].addEventListener("change", function(){
showMenu = false
for(var j = 0; j < itemCheckBox.length; j++)
{
if(itemCheckBox[j].checked)
showMenu = true
}
if (showMenu)
{statusChangeMenu.style.height = "40px";}
else
{statusChangeMenu.style.height = "0px";}
})}
Heres a modified Snippet

showing div after activating a function

I need help on how to show a div that I'm suppose to hide. The idea is that when the object is dragged to the droppable, it will trigger the quiz which is stored on the div "wrapper". I can hide the div but how do I show it when the dragItem_ts(); is done. Please help.
dragItem_ts();
dragItem2();
function dragItem_ts() {
$(function() {
$("#draggable_ts, #draggable-nonvalid").draggable();
$("#droppable").droppable({
accept: "#draggable_ts",
drop: function(event, ui) {
$(this)
.addClass("ui-state-highlight")
.find("p")
.html("Correct!")
.alert("I am an alert box!");
}
});
});
}
function dragItem2() {
$(function() {
$("#draggable2, #draggable-nonvalid").draggable();
$("#droppable2").droppable({
accept: "#draggable2",
drop: function(event, ui) {
$(this)
.addClass("ui-state-highlight")
.find("p")
.html("Correct!");
}
});
});
}
function tabulateAnswers() {
// initialize variables for each choice's score
// If you add more choices and outcomes, you must add another variable here.
var c1score = 0;
var c2score = 0;
var c3score = 0;
var c4score = 0;
// get a list of the radio inputs on the page
var choices = document.getElementsByTagName('input');
// loop through all the radio inputs
for (i = 0; i < choices.length; i++) {
// if the radio is checked..
if (choices[i].checked) {
// add 1 to that choice's score
if (choices[i].value == 'c1') {
c1score = c1score + 1;
}
if (choices[i].value == 'c2') {
c2score = c2score + 1;
}
if (choices[i].value == 'c3') {
c3score = c3score + 1;
}
if (choices[i].value == 'c4') {
c4score = c4score + 1;
}
// If you add more choices and outcomes, you must add another if statement below.
}
}
// Find out which choice got the highest score.
// If you add more choices and outcomes, you must add the variable here.
var maxscore = Math.max(c1score, c2score, c3score, c4score);
// Display answer corresponding to that choice
var answerbox = document.getElementById('answer');
if (c1score == maxscore) { // If user chooses the first choice the most, this outcome will be displayed.
answerbox.innerHTML = "You are correct"
}
if (c2score == maxscore) { // If user chooses the second choice the most, this outcome will be displayed.
answerbox.innerHTML = "The correct answer is stvsp#am.sony.com"
}
if (c3score == maxscore) { // If user chooses the third choice the most, this outcome will be displayed.
answerbox.innerHTML = "The correct answer is stvsp#am.sony.com"
}
if (c4score == maxscore) { // If user chooses the fourth choice the most, this outcome will be displayed.
answerbox.innerHTML = "The correct answer is stvsp#am.sony.com"
}
// If you add more choices, you must add another response below.
}
// program the reset button
function resetAnswer() {
var answerbox = document.getElementById('answer');
answerbox.innerHTML = "Your result will show up here!";
}
#droppable,
#droppable2 {
width: 150px;
height: 150px;
padding: 0.5em;
float: left;
margin: 10px;
}
#draggable_ts,
#draggable2,
#draggable-nonvalid {
width: 100px;
height: 100px;
padding: 0.5em;
float: left;
margin: 10px 10px 10px 0;
}
body {
font-family: sans-serif;
background: green;
}
h2 {
margin: 5px 0;
}
#wrapper {
width: 600px;
margin: 0 auto;
background: white;
padding: 10px 15px;
border-radius: 10px;
}
input {
margin: 5px 10px;
}
button {
font-size: 18px;
padding: 10px;
margin: 20px 0;
color: white;
border: 0;
border-radius: 10px;
border-bottom: 3px solid #333;
}
#submit {
background: green;
}
#reset {
background: red;
}
#answer {
border: 1px dashed #ccc;
background: #eee;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Droppable - Accept</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" type="text/css" href="css/style.css">
<script src=javascript/functions.js>
</script>
</head>
<body>
<div id="draggable-nonvalid" class="ui-widget-content">
<p>I'm draggable but can't be dropped</p>
</div>
<div id="draggable_ts" class="ui-widget-content">
<img src="images/ts_image02.jpg">
</div>
<div id="draggable2" class="ui-widget-content">
<p>Drag me to my target</p>
</div>
<div id="droppable" class="ui-widget-header">
<p>accept: '#draggable'</p>
</div>
<div id="droppable2" class="ui-widget-header">
<p>accept: '#draggable2'</p>
</div>
<div id="droppable3" class="ui-widget-header">
<p>accept: '#draggable2'</p>
</div>
<div id="wrapper">
<h1>What is the email address that the customer should send them to?</h1>
<form id="quiz">
<!-- Question 1 -->
<!-- Here are the choices for the first question. Each input tag must have the same name. For this question, the name is q1. -->
<!-- The value is which answer the choice corresponds to. -->
<label><input type="radio" name="q1" value="c1">
stvsp#am
</label><br />
<label><input type="radio" name="q1" value="c2">
svtsp#am
</label><br />
<label><input type="radio" name="q1" value="c3">
mydocs#am
</label><br />
<label><input type="radio" name="q1" value="c4">
docs#am
</label><br />
<button type="submit" id="submit" onclick="tabulateAnswers()">Submit Your Answers</button>
<button type="reset" id="reset" onclick="resetAnswer()">Reset</button>
</form>
<div id="answer">Your result will show up here!</div>
</div>
</body>
</html>
in the css class of your div you need to set :
display : none;
when dragItem_ts(); is done. just call this function below :
var e = document.getElementsByClassName("your_div")[0];
e.style.display="block";

Categories

Resources