Javascript array issue with HTML radio boxes - javascript

I have a basic JS question about arrays.
I just can't seem to wrap my brain around the following code. I understand that you need the following code in order for the program to understand that its checked, but can someone please walk me though the JS line by line?...
var sex = document.getElementsByName("sex");
var sex_value = "";
//here is where my confusion starts
for (var i=0; i < sex.length; i++)
{
if (sex[i].checked)
sex_value = sex[i].value;
}
// where my confusion ends
if(sex_value == 0)
{
alert("What is your sex?...");
return false;
}
// buttons and what not go here
<input type="radio" name="sex" value="male">Male
<input type="radio" name="sex" value="female">Female

As it is currently, when ever the page loads, you will always see the "What is your sex?..." alert as none of the checkboxes are selected on page load. If you add checked to one of the radio input elements, on page load, the sex_value variable should contain the value of the corresponding checked input element.
Here's the line-commented code.
// Gets all elements on the page that have a name="sex"
var sex = document.getElementsByName("sex");
// Sets a blank string to be updated later (or remain blank)
var sex_value = "";
// This loop runs through all of the [name="sex"] elements
for (var i=0; i < sex.length; i++)
{
// If the value is selected, set sex_value to the value of the input
if (sex[i].checked)
sex_value = sex[i].value;
}
// Really should be if( sex_value === '' )
if(sex_value == 0)
{
alert("What is your sex?...");
return false;
}
And here's an example of what happens when you set the checked element: http://jsfiddle.net/529kx4co/

var sex = document.getElementsByName("sex");
Here sex is a collection of DOM elements having name="sex" defined.
And this one:
for (var i=0; i < sex.length; i++)
{
if (sex[i].checked) {
sex_value = sex[i].value;
break;
}
}
is: for each DOM element in that collection check if element is checked. If it is so get its value property and assign it to sex_value variable.
That value will be the value of the whole radio group (collection of input|radio having the same name).

Related

Validation function nested in another function not running

I am creating a simple questionnaire where a user will answer all the questions and get answers calculated based on point values assigned to the response. A JavaScript function then calculates and displays the results on screen.
The calculation and responses work just fine, but I would like the form to put up an alert if all the questions haven't been answered (right now it just doesn't run the function). I have all the questions set with the "required" attribute, but nothing currently comes up to show that a required question has not been answered. It just doesn't run the function.
Right now I have a little validation function that should run when the user hits submit and if everything is check it will call the main function to calculate the results:
function validateForm() {
var radios = document.getElementsByTagName('input[type="radio"]');
for (var i = 0, len = radios.length; i < len; i++) {
if (radios[i].checked) {
GetRadio();
}
else{
alert("You must answer all of the questions.");
}
}
}
function GetRadio() {
var QS1 = document.querySelector('input[name = "radio1"]:checked').value,
QS2 = document.querySelector('input[name = "radio2"]:checked').value,
QS3 = document.querySelector('input[name = "radio3"]:checked').value,
QS4 = document.querySelector('input[name = "radio4"]:checked').value,
QS5 = document.querySelector('input[name = "radio5"]:checked').value;
selfPoints = Number(QS1) + Number(QS2) + Number(QS3) + Number(QS4) + Number(QS5);...
My expectation is that it should then run the validation before going on to run the rest of the function to calculate results, and put up the Alert box if any are left blank. Instead it doesn't run anything. Not all the questions are answered so it can't calculate, but it isn't putting up an alert either.
Update
OK, the updated code didn't want to work, but the first suggestion of using the querySelectorAll in my original code started working. (I must have done something differently the second time around but I have no clue what) so this is what I've got now:
function validateForm() {
var radios = document.querySelectorAll('input[type="radio"]');
for (var i = 0, len = radios.length; i < len; i++) {
if (radios[i].checked) {
GetRadio();
}
else{
alert("You must answer all of the questions.");
break;
}
}
}
This works, it puts up the alert and it will dismiss the alert, but now it's throwing up the alert even if all the questions are answered, and then when I dismiss it, it calculates my results. Why isn't it just running the GetRadio() function to calculate when all the boxes are checked?
Update 2
Alright, the code as it stands:
function validateForm() {
var radios = [document.getElementsByName("radio1"),
document.getElementsByName("radio2"),
document.getElementsByName("radio3"),
document.getElementsByName("radio4"),
document.getElementsByName("radio5"),
document.getElementsByName("radio1-2"),
document.getElementsByName("radio2-2"),
document.getElementsByName("radio3-2"),
document.getElementsByName("radio4-2"),
document.getElementsByName("radio5-2"),
document.getElementsByName("radio1-3"),
document.getElementsByName("radio2-3"),
document.getElementsByName("radio3-3"),
document.getElementsByName("radio4-3"),
document.getElementsByName("radio5-3"),
document.getElementsByName("radio1-4"),
document.getElementsByName("radio2-4"),
document.getElementsByName("radio3-4"),
document.getElementsByName("radio4-4"),
document.getElementsByName("radio5-4"),
document.getElementsByName("radio1-5"),
document.getElementsByName("radio2-5"),
document.getElementsByName("radio3-5"),
document.getElementsByName("radio4-5"),
document.getElementsByName("radio5-5"),];
for (var i = 0, len = radios.length; i < len; i++) {
if (!radios[i].checked) {
alert("You must answer all of the questions.");
return;
}
}
GetRadio();
}
It pulls the groups, but it looks like it still wants all the radio buttons to be selected before it will run the calculation. Even if there is an answer in for each group of radios I get the alert. What is the right way to say just one of the radios in each group needs to be checked?
Change
document.getElementsByTagName('input[type="radio"]')
to
document.querySelectorAll('input[type="radio"]')
Also try changing the validate function like below
function validateForm() {
var radios = document.querySelectorAll('input[type="radio"]')
if (!radios.filter(radio => !radio.checked).length) {
GetRadio();
} else {
alert("You must answer all of the questions.");
}
})
I see two issues with your code (and with the updated code).
The first issue that the other people seem to have missed is that the updated code continues as soon as it finds any value is selected for any question - it does not check that all individual questions have an answer as expected.
The second issue, is that the current code stops as soon as any radio is unchecked (so the very first element), without checking if another answer from the same question is chosen instead.
The solution is to group the answers within a question and to check one question at a time. Structure your HTML like the following, to group radios:
<input type="radio" name="Question1" value="a"> A
<input type="radio" name="Question1" value="b"> B
<input type="radio" name="Question1" value="c"> C
<input type="radio" name="Question2" value="a"> A
<input type="radio" name="Question2" value="b"> B
<input type="radio" name="Question2" value="c"> C
Then valid each question like this:
if (!document.querySelector('input[name="Question1"]:checked').value) {
//If nothing is checked, it will get undefined
return false;
}
So the complete loop looks like this:
//This part is the answer to your question
for (var i=1; i <= questions.length;i++) {
if (!document.querySelector('input[name="Question"' + i + ']:checked').value) {
//If nothing is checked, it will get undefined and false will be returned
return false;
}
}
As a bonus, you can check the results the same way:
function checkAnswer(questionNumber, correctAnswer) {
let checkedItem = document.querySelector('input[name="Question"' + questionNumber + ']:checked');
if (checkedItem.value === correctAnswer) {
return true;
}
return false;
//OR
// return checkedItem.value === correctAnswer
}
If i understand correctly, your code should look like this:
If any check wrong, raise alert, exit and don't even calculate
If all checked then calculate
function validateQuestion(container) {
var radios = container.querySelectorAll('input[type="radio"]');
for (var i = 0, len = radios.length; i < len; i++) {
if (radios[i].checked) {
return true;
}
}
return false;
}
function validateForm() {
var questions = document. querySelectorAll('.question');
var isValid = true;
for (var i = 0, len = questions.length; i < len; i++) {
isValid = isValid && validateQuestion(questions[i]);
if (!isValid) {
alert("You must answer all of the questions.");
return;
}
}
GetRadio();
}
You question html should look like this
<div class="question q-1">
Question 1:
<input type="radio" value="1-a">A
<input type="radio" value="1-b">B
<input type="radio" value="1-c">C
</div>
<div class="question q-2">
Question 2:
<input type="radio" value="2-a">A
<input type="radio" value="2-b">B
<input type="radio" value="2-c">C
</div>

Validating a checkbox after already validating other sections of a form [duplicate]

I have a form with multiple checkboxes and I want to use JavaScript to make sure at least one is checked. This is what I have right now but no matter what is chosen an alert pops up.
JS (wrong)
function valthis(){
if (document.FC.c1.checked) {
alert ("thank you for checking a checkbox")
} else {
alert ("please check a checkbox")
}
}
HTML
<p>Please select at least one Checkbox</p>
<br>
<br>
<form name = "FC">
<input type = "checkbox" name = "c1" value = "c1"/> C1
<br>
<input type = "checkbox" name = "c1" value = "c2"/> C2
<br>
<input type = "checkbox" name = "c1" value = "c3"/> C3
<br>
<input type = "checkbox" name = "c1" value = "c4"/> C4
<br>
</form>
<br>
<br>
<input type = "button" value = "Edit and Report" onClick = "valthisform();">
So what I ended up doing in JS was this:
function valthisform(){
var chkd = document.FC.c1.checked || document.FC.c2.checked||document.FC.c3.checked|| document.FC.c4.checked
if (chkd == true){
} else {
alert ("please check a checkbox")
}
}
I decided to drop the "Thank you" part to fit in with the rest of the assignment. Thank you so much, every ones advice really helped out.
You should avoid having two checkboxes with the same name if you plan to reference them like document.FC.c1. If you have multiple checkboxes named c1 how will the browser know which you are referring to?
Here's a non-jQuery solution to check if any checkboxes on the page are checked.
var checkboxes = document.querySelectorAll('input[type="checkbox"]');
var checkedOne = Array.prototype.slice.call(checkboxes).some(x => x.checked);
You need the Array.prototype.slice.call part to convert the NodeList returned by document.querySelectorAll into an array that you can call some on.
This should work:
function valthisform()
{
var checkboxs=document.getElementsByName("c1");
var okay=false;
for(var i=0,l=checkboxs.length;i<l;i++)
{
if(checkboxs[i].checked)
{
okay=true;
break;
}
}
if(okay)alert("Thank you for checking a checkbox");
else alert("Please check a checkbox");
}
If you have a question about the code, just comment.
I use l=checkboxs.length to improve the performance. See http://www.erichynds.com/javascript/javascript-loop-performance-caching-the-length-property-of-an-array/
I would opt for a more functional approach. Since ES6 we have been given such nice tools to solve our problems, so why not use them.
Let's begin with giving the checkboxes a class so we can round them up very nicely.
I prefer to use a class instead of input[type="checkbox"] because now the solution is more generic and can be used also when you have more groups of checkboxes in your document.
HTML
<input type="checkbox" class="checkbox" value=ck1 /> ck1<br />
<input type="checkbox" class="checkbox" value=ck2 /> ck2<br />
JavaScript
function atLeastOneCheckboxIsChecked(){
const checkboxes = Array.from(document.querySelectorAll(".checkbox"));
return checkboxes.reduce((acc, curr) => acc || curr.checked, false);
}
When called, the function will return false if no checkbox has been checked and true if one or both is.
It works as follows, the reducer function has two arguments, the accumulator (acc) and the current value (curr). For every iteration over the array, the reducer will return true if either the accumulator or the current value is true.
the return value of the previous iteration is the accumulator of the current iteration, therefore, if it ever is true, it will stay true until the end.
Check this.
You can't access form inputs via their name. Use document.getElements methods instead.
Vanilla JS:
var checkboxes = document.getElementsByClassName('activityCheckbox'); // puts all your checkboxes in a variable
function activitiesReset() {
var checkboxesChecked = function () { // if a checkbox is checked, function ends and returns true. If all checkboxes have been iterated through (which means they are all unchecked), returns false.
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) {
return true;
}
}
return false;
}
error[2].style.display = 'none'; // an array item specific to my project - it's a red label which says 'Please check a checkbox!'. Here its display is set to none, so the initial non-error label is visible instead.
if (submitCounter > 0 && checkboxesChecked() === false) { // if a form submit has been attempted, and if all checkboxes are unchecked
error[2].style.display = 'block'; // red error label is now visible.
}
}
for (var i=0; i<checkboxes.length; i++) { // whenever a checkbox is checked or unchecked, activitiesReset runs.
checkboxes[i].addEventListener('change', activitiesReset);
}
Explanation:
Once a form submit has been attempted, this will update your checkbox section's label to notify the user to check a checkbox if he/she hasn't yet. If no checkboxes are checked, a hidden 'error' label is revealed prompting the user to 'Please check a checkbox!'. If the user checks at least one checkbox, the red label is instantaneously hidden again, revealing the original label. If the user again un-checks all checkboxes, the red label returns in real-time. This is made possible by JavaScript's onchange event (written as .addEventListener('change', function(){});
You can check that atleast one checkbox is checked or not using this simple code. You can also drop your message.
Reference Link
<label class="control-label col-sm-4">Check Box 2</label>
<input type="checkbox" name="checkbox2" id="checkbox2" value=ck1 /> ck1<br />
<input type="checkbox" name="checkbox2" id="checkbox2" value=ck2 /> ck2<br />
<script>
function checkFormData() {
if (!$('input[name=checkbox2]:checked').length > 0) {
document.getElementById("errMessage").innerHTML = "Check Box 2 can not be null";
return false;
}
alert("Success");
return true;
}
</script>
< script type = "text/javascript" src = "js/jquery-1.6.4.min.js" > < / script >
< script type = "text/javascript" >
function checkSelectedAtleastOne(clsName) {
if (selectedValue == "select")
return false;
var i = 0;
$("." + clsName).each(function () {
if ($(this).is(':checked')) {
i = 1;
}
});
if (i == 0) {
alert("Please select atleast one users");
return false;
} else if (i == 1) {
return true;
}
return true;
}
$(document).ready(function () {
$('#chkSearchAll').click(function () {
var checked = $(this).is(':checked');
$('.clsChkSearch').each(function () {
var checkBox = $(this);
if (checked) {
checkBox.prop('checked', true);
} else {
checkBox.prop('checked', false);
}
});
});
//for select and deselect 'select all' check box when clicking individual check boxes
$(".clsChkSearch").click(function () {
var i = 0;
$(".clsChkSearch").each(function () {
if ($(this).is(':checked')) {}
else {
i = 1; //unchecked
}
});
if (i == 0) {
$("#chkSearchAll").attr("checked", true)
} else if (i == 1) {
$("#chkSearchAll").attr("checked", false)
}
});
});
< / script >
Prevent user from deselecting last checked checkbox.
jQuery (original answer).
$('input[type="checkbox"][name="chkBx"]').on('change',function(){
var getArrVal = $('input[type="checkbox"][name="chkBx"]:checked').map(function(){
return this.value;
}).toArray();
if(getArrVal.length){
//execute the code
$('#msg').html(getArrVal.toString());
} else {
$(this).prop("checked",true);
$('#msg').html("At least one value must be checked!");
return false;
}
});
UPDATED ANSWER 2019-05-31
Plain JS
let i,
el = document.querySelectorAll('input[type="checkbox"][name="chkBx"]'),
msg = document.getElementById('msg'),
onChange = function(ev){
ev.preventDefault();
let _this = this,
arrVal = Array.prototype.slice.call(
document.querySelectorAll('input[type="checkbox"][name="chkBx"]:checked'))
.map(function(cur){return cur.value});
if(arrVal.length){
msg.innerHTML = JSON.stringify(arrVal);
} else {
_this.checked=true;
msg.innerHTML = "At least one value must be checked!";
}
};
for(i=el.length;i--;){el[i].addEventListener('change',onChange,false);}
<label><input type="checkbox" name="chkBx" value="value1" checked> Value1</label>
<label><input type="checkbox" name="chkBx" value="value2"> Value2</label>
<label><input type="checkbox" name="chkBx" value="value3"> Value3</label>
<div id="msg"></div>
$('input:checkbox[type=checkbox]').on('change',function(){
if($('input:checkbox[type=checkbox]').is(":checked") == true){
$('.removedisable').removeClass('disabled');
}else{
$('.removedisable').addClass('disabled');
});
if(($("#checkboxid1").is(":checked")) || ($("#checkboxid2").is(":checked"))
|| ($("#checkboxid3").is(":checked"))) {
//Your Code here
}
You can use this code to verify that checkbox is checked at least one.
Thanks!!

Could someone please explain a piece of Javascript code?

I am doing a project in school, and as part of that I had to include radio buttons in my html form. Below is the Javascript code which some parts I don't quite understand. The code works fine. Could someone plz give me an explanation of how the code works.
var check = false;
for (var i=0; i < document.ExamEntry.Level.length; i++)
{
if (document.ExamEntry.Level[i].checked)
{
var radiovalue = document.ExamEntry.Level[i].value;
check =true;
var usermessage=confirm("You have chosen: ".concat(radiovalue));
if(usermessage == false)
{
var radiovalue = "";
check = false;
}
}
}
<!--I understand the code below, its just some parts of the above code.
if (check ==false)
{
msg+="ERROR:You must select an entry level \n";
document.getElementById ('Levelcell'). style.color = "red";
result = false;
}
I added comments to help explain this:
var check = false;
// set a variable 'i' from 0 up to the ExamEntry level length (so for each radio)
// if there are 10 items, this code will run 10 times, each time with 'i' a different value from 0 to 9
for (var i=0; i < document.ExamEntry.Level.length; i++)
{
// is the radio button checked? If so, do the stuff inside. If not, skip this part
if (document.ExamEntry.Level[i].checked)
{
// set variable radiovalue to the value of the particular radio button
var radiovalue = document.ExamEntry.Level[i].value;
// set the check variable to true
check =true;
// ask the user to confirm the value and set usermessage based on confirmation
var usermessage=confirm("You have chosen: ".concat(radiovalue));
// if the user hits no on confirm, it will reset the radiomessage to blank and check to false
if(usermessage == false)
{
var radiovalue = "";
check = false;
}
}
}
All form elements are bound to the global HTML document variable. So somewhere on the page there must be a form with the name of ExamEntry:
<form name='ExamEntry' id='ExamEntry` ...
The next part refers to an element in the form. Since they are expecting a radio button, Level must be an input of type radio:
<label name="Level" id="1" type="radio" ....
<label name="Level" id="2" type="radio" ....
The loop iterates through all radio buttons. If the the button is checked, it grabs the checked value, and shows that message. If it does not find a checked button, then it displays an error message.

validate a dynamicnumber of checkboxes using javascript

I have some ASP code which presents any where from 1-any number of checkboxes (which are named the same) on the page. This validation does work however I think its a bit weak:
if (document.getElementById('selectedDocs').checked)
{
//this is here to handle the situation where there is only one checkbox being displayed
}
else
{
var checked = false;
var field = myForm.selectedDocs;
for(var j = 0; j < field.length; j++)
{
if(field[j].checked == true)
{
checked = true;
break;
}
}
if(!checked)
{
alert("You have not ticked any options. At least one must be selected to proceed!")
return false;
}
}
I was working with the code in the else block but this only works when there is more than one checkbox. It ignores the fact I have ticked the one single option when there is only one. So I placed the code inside the if section......Although it woks its a bit of a hack, can someone kindly improve it for me?
Thanking you...
Use:
var field = myForm.getElementsByName('selectedDocs');
This always returns a NodeList that you can iterate over.
If they are in a form and all have the same name, they can be accessed as a collection that is a property of the form. So given:
<form id="f0" ...>
<input type="checkbox" name="cb0" ...>
<input type="checkbox" name="cb0" ...>
<input type="checkbox" name="cb0" ...>
...
</form>
All the following return a reference to the form:
var form = document.getElementById('f0');
var form = document.forms['f0'];
var form = document.forms[0]; // if first form in document
and and all the following return a collection of the checkboxes named "cb0":
var checkboxes = form.cb0
var checkboxes = form['cb0'];
var checkboxes = form.elements.['cb0'];

Simple JavaScript check not working?

I have this validate form function:
function ValidateForm() {
var chks = document.register.elements['sendto[]'];
var hasChecked = false;
for (var i=0;i<chks.length;i++){
if (chks[i].checked){
hasChecked = true;
break;
}
}
if (!hasChecked){
alert("Please select at least one friend.");
chks[0].focus();
return false;
}
}
html for this is:
<input type="checkbox" name="sendto[]" value="2" >
I know this is not full code. Full code is huge. But basically if i have only one checkbox in the code the above code gives a message undefined on ValidateForm(). Which is called when form is submitted and and above checkbox is checked.
But if i have two checkboxes in the code like this:
<input type="checkbox" name="sendto[]" value="2" >
<input type="checkbox" name="sendto[]" value="4" >
On submit when ValidateForm() function is called this works correctly. Am i doing something wrong that it is not working for 1 checkbox even if it is checked?
The statement
var chks = document.register.elements['sendto[]'];
gets the element (element*s*, if there are more then one) with namesendto[]
If there is only one element with name sendto[] then you have the reference of that element in chks.
If there are more than one element with name sendto[], then chks holds the reference to the array of those elements.
When you do this:
for (var i=0;i<chks.length;i++){
You try to loop based on chks.length. If chks is an array (see above: when there are multiple elements by name sendto[]), then chks.length will hold the number of elements in the array.
If there is only one sendto[] element, then chks will hold that element and since the element (<input type="checkbox" name="sendto[]" value="2" >) does not have a property called length, the browser says length is indefined
So you have o differentiate between two scenarios, when there is only one sendto[] checkbox and when there are more than one.:
var chks = document.register.elements['sendto[]'];
var hasChecked = false;
//Check whether there is one checkbox or whether there are more
if(chks.length)
{
for (var i=0;i<chks.length;i++)
{
if (chks[i].checked)
{
hasChecked = true;
break;
}
}
}
else
{
if(chks.checked)
{
haschecked = true;
}
}
PS:
code gives a message undefined on ValidateForm() does not convey much. Even for you it is not clear what this means right (That's why you have asked this question). Try to give more details. Any modern browser will give more details on the undefined, the what is undefined which line etc. Even pre-historic browsers will tell you the line number where the undefined error was thrown. With those details you can try to find the line and try to see what is happening. You most likely will find out. If you don't, post it to the community here with all these details.
<script language="javascript">
function validate() {
var chks = document.getElementsByName('sendto[]');
var hasChecked = false;
for (var i = 0; i < chks.length; i++) {
if (chks[i].checked) {
hasChecked = true;
break;
}
}
if (hasChecked == false) {
alert("Please select at least one friend.");
return false;
}
return true;
}
</script>
Here is how I would do it.
if(!validate()){
alert("Please select at least one.");
return false;
}
function validate(){
var els=document.getElementsByName('sendto[]');
for(var i=0;i<els.length;i++){
if(els[i].checked){
return true;
}
}
return false;
}
You could use validate as an anonymous function.

Categories

Resources