I want a variable (chanceoflive) to be stored with localStorage. Then, I have radio buttons. I want it so that depending on which radio button is selected, the variable chanceoflive will be changed. This is what I have:
var chanceoflive = 0;
var user;
function choose(choice){
user = choice;
}
function changechanceoflive(){
if (user == brick) {
chanceoflive += 1;
}
else if (user == wood) {
chanceoflive +=3
}
else if (user == stone) {
chanceoflive +=2
}
localStorage.setItem("chanceoflive", chanceoflive);
}
function test(click){
alert(chanceoflive);
}
<div id="radiobuttons" class="container" name="buttons" align=center>
<h2>I Want my Building to be Made of:</h2>
<ul>
<li>
<input type="radio" id="brick-option" name="material" value="1" onClick="choose('Bricks')">
<label for="brick-option">Bricks</label>
<div class="check"></div>
</li>
<li>
<input type="radio" id="wood-option" name="material" value="3" onClick="choose('Wood')">
<label for="wood-option">Wood</label>
<div class="check">
<div class="inside"></div>
</div>
</li>
<li>
<input type="radio" id="stone-option" name="material" value="2" onClick="choose('Stone')">
<label for="stone-option">Stone</label>
<div class="check">
<div class="inside"></div>
</div>
</li>
</ul>
</div>
<form action="chooseheight.html">
<div class="wrapper">
<button class="button" onClick="test();changechanceoflive()" align=center>Submit</button>
</div>
</form>
Although, it always just alerts 0. Is it a problem with localStorage or something else?
I fixed your code:
<ul>
<li>
<input type="radio" id="brick-option" name="material" value="1" onClick="choose('bricks')">
<label for="brick-option">Bricks</label>
<div class="check"></div>
</li>
<li>
<input type="radio" id="wood-option" name="material" value="3" onClick="choose('wood')">
<label for="wood-option">Wood</label>
<div class="check">
<div class="inside"></div>
</div>
</li>
<li>
<input type="radio" id="stone-option" name="material" value="2" onClick="choose('stone')">
<label for="stone-option">Stone</label>
<div class="check">
<div class="inside"></div>
</div>
</li>
JS
var chanceoflive = 0;
var user;
function choose(choice){
user = choice;
}
function changechanceoflive(){
if (user == 'bricks') {
chanceoflive += 1;
}
else if (user == 'wood') {
chanceoflive +=3
}
else if (user == 'stone') {
chanceoflive += 2
}
localStorage.setItem("chanceoflive", chanceoflive);
}
function test(click){
alert(chanceoflive);
alert(localStorage.chanceoflive);
}
But with your code, if the user reload the page and then didn't select any radio, the localStorage variable will be reset to 0 because your have
var chanceoflive = 0;
If you want to keep the last saved value, you must replace that line by:
var chanceoflive = localStorage.chanceoflive;
To answer your part about LocalStorage, just set/get your variables like a regular Javascript object. More info: mrkdown.io/t32iomd
Related
I am trying to get to <label> tag right under the <input> tag for later styling purposes. I tried with .firstElementChild, which gives me a null value. How can I get to label tag of clicked checkbox field? This is my code:
var checkboxes = document.querySelectorAll("input[type='checkbox']");
for (var i = 0; i < checkboxes.length; i++) {
console.log(checkboxes[i]);
checkboxes[i].addEventListener('change', (e) => {
var targetCb = e.target;
console.log(targetCb.firstElementChild);
});
}
<ul>
<li class="title mb-3">STYLISTIC SET</li>
<li>
<input type="checkbox" id="sSet1" name="sSet1" value="sSet1" />
<label for="sSet1">Stylistic set 1</label>
</li>
<li>
<input type="checkbox" id="sSet2" name="sSet2" value="sSet2" />
<label for="sSet2">Stylistic set 2</label>
</li>
<li>
<input type="checkbox" id="sSet3" name="sSet3" value="sSet3" />
<label for="sSet3">Stylistic set 3</label>
</li>
<li>
<input type="checkbox" id="sSet4" name="sSet4" value="sSet4" />
<label for="sSet4">Stylistic set 4</label>
</li>
</ul>
It seems like you quite don't know what child elements and siblings are.
Consider the following for children:
<div id="parent">
<div id="child">I'm the child of my parent.</div>
</div>
And the following for siblings:
<div id="sibling1"></div>
<div id="sibling2">I'm the sibling of sibling1.</div>
In your code, those labels are siblings of your input elements.
So in your script, change console.log(targetCb.firstElementChild); to console.log(targetCb.nextElementSibling);
var checkboxes = document.querySelectorAll("input[type='checkbox']");
for (var i = 0; i < checkboxes.length; i++) {
console.log(checkboxes[i]);
checkboxes[i].addEventListener('change', (e) => {
var targetCb = e.target;
console.log(targetCb.nextElementSibling);
});
}
<ul>
<li class="title mb-3">STYLISTIC SET</li>
<li>
<input type="checkbox" id="sSet1" name="sSet1" value="sSet1" />
<label for="sSet1">Stylistic set 1</label>
</li>
<li>
<input type="checkbox" id="sSet2" name="sSet2" value="sSet2" />
<label for="sSet2">Stylistic set 2</label>
</li>
<li>
<input type="checkbox" id="sSet3" name="sSet3" value="sSet3" />
<label for="sSet3">Stylistic set 3</label>
</li>
<li>
<input type="checkbox" id="sSet4" name="sSet4" value="sSet4" />
<label for="sSet4">Stylistic set 4</label>
</li>
</ul>
Change
var targetCb = e.target;
to var targetCb = e.target.nextElementSibling;
I am working on some code that takes the selected value of the radio button and passes it to the next group of radio buttons to be used as input. The code works well when passing the first time, but any subsequent time, instead of passing the value, it passes "on." I think it's just something silly, but I haven't been able to figure it out.
Link to JS Fiddle: https://jsfiddle.net/hc3bracf/6/
Here is the HTML and JS:
<div class="container">
<ul class="aaa">
<li>
<input type="radio" name="g1" id="i1" value="s#1" data-target="r65">
<label id="r1" for="i1">s#1</label>
<div class="check">
<div class="inside"></div>
</div>
</li>
<li>
<input type="radio" name="g1" id="i2" value="s#16" data-target="r65">
<label id="r2" for="i2">s#16</label>
<div class="check">
<div class="inside"></div>
</div>
</li>
</ul>
</div>
<div class="container">
<ul class="aaa">
<li>
<input type="radio" name="g2" id="i3" value="s#8" data-target="r66">
<label id="r3" for="i3">s#8</label>
<div class="check">
<div class="inside"></div>
</div>
</li>
<li>
<input type="radio" name="g2" id="i4" value="s#9" data-target="r66">
<label id="r4" for="i4">s#9</label>
<div class="check">
<div class="inside"></div>
</div>
</li>
</ul>
</div>
<div class="container">
<ul class="aaa">
<li>
<input type="radio" name="g33" id="i65" data-target="r97">
<label id="r65" for="i65"></label>
<div class="check">
<div class="inside"></div>
</div>
</li>
<li>
<input type="radio" name="g33" id="i66" data-target="r97">
<label id="r66" for="i66"></label>
<div class="check">
<div class="inside"></div>
</div>
</li>
</ul>
</div>
<div class="container">
<ul class="aaa">
<li>
<input type="radio" name="g49" id="i97" data-target="r113">
<label id="r97"></label>
<div class="check">
<div class="inside"></div>
</div>
</li>
<li>
<input type="radio" name="g49" id="i98" data-target="r113">
<label id="r98"></label>
<div class="check">
<div class="inside"></div>
</div>
</li>
</ul>
</div>
JS
const inputs = document.querySelectorAll("input[type=radio]");
for (let inp of inputs) {
inp.addEventListener("change", function() {
let targetLabel = document.getElementById(inp.dataset.target);
let targetRadio = targetLabel.previousSibling;
targetLabel.innerHTML = inp.value;
targetRadio.value = inp.value;
targetRadio.checked = false;
//while there is a next target clear it
while (targetLabel.previousSibling.hasAttribute) {
targetLabel = document.getElementById(targetRadio.dataset.target);
targetRadio = targetLabel.previousSibling;
targetRadio.checked = false;
targetLabel.innerHTML = '';
}
});
}
The previousSibling property returns the previous node of the specified node, in the same tree level.
The returned node is returned as a Node object.
The difference between this property and previousElementSibling, is that previousSibling returns the previous sibling node as an element node, a text node or a comment node, while previousElementSibling returns the previous sibling node as an element node (ignores text and comment nodes).
const inputs = document.querySelectorAll("input[type=radio]");
for (let inp of inputs) {
inp.addEventListener("change", function() {
let targetLabel = document.getElementById(inp.dataset.target);
console.log(targetLabel);
let targetRadio = targetLabel.previousElementSibling;
targetRadio.value = inp.value;
targetLabel.innerHTML = inp.value;
targetRadio.checked = false;
//while there is a next target clear it
while (targetLabel.previousElementSibling.hasAttribute) {
targetLabel = document.getElementById(targetRadio.dataset.target);
targetRadio = targetLabel.previousSibling;
targetRadio.checked = false;
targetLabel.innerHTML = '';
}
});
}
I am developing form.
What I need is when a user tries to go to another page with empty VISIBLE fields/checkboxes/radios these fields/checkboxes/radios should become red.
Filters for checkboxes: min 1, max 5.
My jQuery
const max = 5;
const min = 1;
const minCheckedCheckboxes = 1;
$('input.checkbox').on('click', function(evt) {
const checkboxes = $(this).closest('.cd-form-list-inner').find('input:checked');
if(checkboxes.length > max) {
alert('You can select only 5 checkboxes');
return false;
}
});
$('.next').click(function() {
let error = false;
$(['input[required]:visible', 'textarea[required]:visible']).each(function(index, selector) {
$(selector).each(function(index, input) {
error = error == true ? error : $(input).val() == '';
});
});
$('.parent:visible').each(function(index, group){
if(error == true) {
error = error;
}
else {
error = $('input:checked', group).length < minCheckedCheckboxes;
}
});
if(error == false) {
error =! $('input[type=radio]:required').is(':checked');
}
if(error) {
$('input[required]:visible, textarea[required]:visible').removeClass("error");
$('input[required]:visible, textarea[required]:visible').filter(function() {
return !this.value;
}).addClass('error');
return alert('Not all required fields are filled');
}
alert('All required fields are filled');
});
Here is jsFiddle
Check if below code works for you!
Looped on all desired inputs.
Checked the input type while looping, accordingly created the condition to add the error class, also maintained the elem on which error class needs to be added.
Then if condition is true then added error class to elem.
const max = 5;
const min = 1;
$('.next').click(function() {
$('input[required]:visible,textarea[required]:visible,input[type="checkbox"]:visible').each(function(index, selector) {
var elem;
if ($(this).is(":checkbox") || $(this).is(":radio")) {
var pDiv = $(this).parents("div").first();
var condition = false;
elem = pDiv;
if ($(this).is(":radio")) {
condition = pDiv.find("[type='radio']:checked").length <= 0
} else {
condition = pDiv.find("[type='checkbox']:checked").length < min || pDiv.find("[type='checkbox']:checked").length > max;
}
} else {
condition = !$(this).val();
elem = $(this);
}
if (condition) {
elem.addClass('error');
} else {
elem.removeClass('error');
}
});
});
.error {
background-color: pink;
border-color: red;
}
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
<p>press button</p>
<input type="text" required/>
<input type="text" required style="display: none" />
<div>
<textarea cols="5" required placeholder="textarea"></textarea>
</div>
<div>
<textarea cols="5" required placeholder="textarea" style="display:none"></textarea>
</div>
<div class="parent">
<p>this div should be red</p>
<div>
<input type="radio" required>
</div>
</div>
<div class="parent" display: none>
<p>this div shouldn't be red</p>
<div>
<input type="radio" checked required>
</div>
</div>
<div style="display:none">
<p>this div shouldn't be red</p>
<input type="radio" required>
</div>
<div class="parent">
<p>this div shouldn't be red</p>
<div class="cd-form-list-inner checkboxes">
<input type="checkbox" class="checkbox" checked>
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
</div>
</div>
<div class="parent" style="display: none;">
<p>this div shouldn't be red</p>
<div class="cd-form-list-inner checkboxes">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
</div>
</div>
<div class="parent">
<p>this div should be red</p>
<div class="cd-form-list-inner checkboxes">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
<input type="checkbox" class="checkbox">
</div>
</div>
<div>
<button class="next">Next page</button>
</div>
I have 5 if else conditions under function getRadioButtonValue. The function does not go through all the conditions even after clicking the right button combinations.
I have tried to debug the script using Chrome Developer tools but the problem still exists. Where is the code breaking?
Some information regarding the page, I am using Javascript to hide the div's and headers so that at any one time there is only one question seen.
Only the first if conditions work, but nothing else
The results are seen after Get Result button is clicked on the last page which should redirect to the appropriate page.
[DELETED CODE]
[UPDATED CODE]
I am unable to auto hide my div's based on the response given below by Keith.
FYI: His code works as expected.
<!DOCTYPE html>
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<style>
.hidden {
display: none;
}
.visible {
display: block;
margin: 0 auto;
width: 650px;
height: 445px;
background: #EFDFBC;
}
</style>
</head>
<body>
<div id="first-question" class="visible">
<h3>How?</h3>
<ul>
<li>abc</li>
<li>def</li>
</ul>
<hr>
<input type="radio" name="quiz-question-one" id="quiz-question-one-yes" value="yes" />
<label for="quiz-question-one-yes" id="oneYes">Yes</label>
<input type="radio" name="quiz-question-one" id="quiz-question-one-no" value="no" />
<label for="quiz-question-one-no" id="oneNo">No</label>
</div>
<div id="second-question" class="hidden">
<h3>To</h3>
<hr>
<input type="radio" name="quiz-question-two" id="quiz-question-two-yes" value="yes" />
<label for="quiz-question-two-yes" id="twoYes">Yes</label>
<input type="radio" name="quiz-question-two" id="quiz-question-two-no" value="no" />
<label for="quiz-question-two-yes" id="twoNo">No</label>
</div>
<div id="third-question" class="hidden">
<h3>Make </h3>
<hr>
<input type="radio" name="quiz-question-three" id="quiz-question-three-yes" value="yes" />
<label for="quiz-question-three-yes" id="threeYes">Yes</label>
<input type="radio" name="quiz-question-three" id="quiz-question-three-no" value="no" />
<label for="quiz-question-three-yes" id="threeNo">No</label>
</div>
<div id="fourth-question" class="hidden">
<h3>This</h3>
<hr>
<input type="radio" name="quiz-question-four" id="quiz-question-four-yes" value="yes" />
<label for="quiz-question-four-yes" id="fourYes">Yes</label>
<input type="radio" name="quiz-question-four" id="quiz-question-four-no" value="no" />
<label for="quiz-question-four-yes" id="fourNo">No</label>
</div>
<div id="fifth-question" class="hidden">
<h3>Work?</h3>
<hr>
<input type="radio" name="quiz-question-five-yes" id="quiz-question-five-yes" value="yes" />
<label for="quiz-question-five-yes" id="fiveYes">Yes</label>
<input type="radio" name="quiz-question-five-no" id="quiz-question-five-no" value="no" />
<label for="quiz-question-five-yes" id="fiveNo">No</label>
</div>
<div class="page result">
<label>Results</label>
<div id="result"></div>
</div>
</body>
</html>
<script type="text/javascript">
var results = {};
function updateResult() {
var r = results,
rt = $('#result');
if (r.quiz-question-one && r.quiz-question-two && r.quiz-question-three && r.quiz-question-four && r.quiz-question-five) {
rt.text('All Yes');
} else if (!r.quiz-question-one && !r.quiz-question-two && !r.quiz-question-three && !r.quiz-question-four && !r.quiz-question-five) {
rt.text('All No');
} else {
rt.text('We have a mixed response');
}
}
$(function () {
$('body').on('click', '[name]', function () {
var $this = $(this),
page = $this.closest('.hidden'),
next_page = $(page.next());
results[$this.attr('name')] = $(this).val() === 'yes';
page.removeClass('visible');
next_page.addClass('visible');
if (next_page.hasClass('result')) updateResult();
});
});
</script>
I've created an example below that I think you can work from. The values from the radio I don't think get updated until you submit, instead I've captured the results in the onclick. You can now add back you CSS styling etc. Hope that helps.
var results = {};
function updateResult() {
var r = results,
rt = $('#result');
if (r.q1 && r.q2 && r.q3) {
rt.text('All Yes');
} else if (!r.q1 && !r.q2 && !r.q3) {
rt.text('All No');
} else {
rt.text('We have a mixed response');
}
}
$(function () {
$('body').on('click', '[name]', function () {
var $this = $(this),
page = $this.closest('.page'),
next_page = $(page.next());
results[$this.attr('name')] = $(this).val() === 'yes';
page.removeClass('active');
next_page.addClass('active');
if (next_page.hasClass('result')) updateResult();
});
});
.page {
display: none;
}
.page.active {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="page active">
<div>Question 1</div>
<label for="q1yes">Yes</label>
<input id="q1yes" type="radio" name="q1" value="yes">
<label for="q1no">No</label>
<input id="q1no" type="radio" name="q1" value="no">
</div>
<div class="page">
<div>Question 2</div>
<label for="q2yes">Yes</label>
<input id="q2yes" type="radio" name="q2" value="yes">
<label for="q2no">No</label>
<input id="q2no" type="radio" name="q2" value="no">
</div>
<div class="page">
<div>Question 3</div>
<label for="q3yes">Yes</label>
<input id="q3yes" type="radio" name="q3" value="yes">
<label for="q3no">No</label>
<input id="q3no" type="radio" name="q3" value="no">
</div>
<div class="page result">
<label>Results</label>
<div id="result"></div>
</div>
<input type="radio" id="quiz-question-one-yes" value="yes" />
<label for="quiz-question-one-yes" id="oneYes">Yes</label>
<input type="radio" id="quiz-question-one-no" value="no" />
<label for="quiz-question-one-no" id="oneNo">No</label>
In the above you are using type="radio", that means all type="radio" with the same name will group together, and not just these two. To group together just give them a name on the input. eg.
<input type="radio" name="quiz-question-one" id="quiz-question-one-yes" value="yes" />
<label for="quiz-question-one-yes" id="oneYes">Yes</label>
<input type="radio" name="quiz-question-one" id="quiz-question-one-no" value="no" />
<label for="quiz-question-one-no" id="oneNo">No</label>
Above you can see I've given the 2 inputs the name="quiz-question-one", and then for the next question maybe give them a name="quiz-question-two" etc..
On another note, there are lots of places where your code could be simplified, but hopefully this will solve your current problem.
Hope someone can help.
I have a dynamically generated form that ends up looking like this
<form>
<header><h2 id="title">This is a Survey Title</h2></header>
<ul class="Question_list">
<li class="question">
<div id="sm_survey_question_0">
<fieldset>
<div class="question_text">is this a test?</div>
<input type="radio" name="0" value="1">yes<br>
<input type="radio" name="0" value="2">no<br>
<input type="radio" name="0" value="3">maybe<br>
</fieldset>
</div>
</li>
<li class="question">
<div id="sm_survey_question_1">
<fieldset>
<div class="question_text">Is Batman the best?</div>
<input type="radio" name="1" value="1">yes<br>
<input type="radio" name="1" value="2">no<br>
</fieldset>
</div></li>
<li>
<div id="sm_survey_question_2">
<fieldset>
<div class="question_text">best colors</div>
<input type="radio" name="2" value="1">red<br>
<input type="radio" name="2" value="2">blue<br>
<input type="radio" name="2" value="3">green<br>
</fieldset>
</div>
</li>
</ul>
</form>
and I would like that when the submit button is clicked i can generate a "report", a string would work with the question and the answers selected.
I cant wrap my mind around how to do that.
so far im able to cycle through the questions, check what answers are checked but its the end when i have to create a sting with the questions + its checked
module.createReport = function() {
console.log('reporting');
var questions = document.getElementsByClassName('question');
console.log(questions.length+1,"questions");
var StringAnswers="";
for (var i = questions.length ; i >= 0; i--) {
var textq= document.getElementById('sm_survey_question_'+i).getElementsByClassName("question_text")[0].innerHTML;
var answers = document.getElementById('sm_survey_question_'+i).getElementsByTagName('input');
for (var j = answers.length-1; j >= 0; j--) {
if (answers[j].checked) {
var isanswerC= answers[j].value;
};
var conc= textq+" "+isanswerC;
StringAnswers.concat(conc);
};
};
console.log(conc);
};