validate a multiple tabs with multiple radio buttons - javascript

I have a form, which has multiple tabs that displays 10 questions in each one and include (true/false) radio groups (generated by php code, so I don't know their names OR how many will appear), and I need to check whether they are checked or not on next button clicked. If not I want to show the user which question was not answered (no alert message, but it can be in a label with a green or red check icon).
I've tried googling the problem, but none of the previous answers were good to use in my case.
Edit:
This is a part of my code:
<form id="questionForm" action="" method="post" role="form">
<input type="hidden" name="login" value="<?php echo $_SESSION['login-user']?>"/>
<input type="hidden" name="pass_user" value="<?php echo $_SESSION['pass_user']; ?>"/>
<?php
$blocks_questions = array_chunk($questions, 10);
foreach($blocks_questions as $cle=>$question_block) {?>
<div class='tab'>
<?php
foreach ($question_block as $key => $question) {
$id_quiz_qst=$question['id_quiz'].",".$question['id_qst'];?>
<div class="form-group qst-row">
<div class="row">
<div class="col-sm-10"><p><?php echo $question['question'] ?></p>
</div>
<div class="col-sm-2">
<span class="question-rbtn" >
<span class="switch radio-switch fixed-width-lg">
<input name="<?php echo $id_quiz_qst?>" id="<?php echo $id_quiz_qst."_on";?>" value="Vrai" <?php if (isset($_POST[$id_quiz_qst]) && $_POST[$id_quiz_qst]=="Vrai") echo "checked";?> type="radio">
<label for="<?php echo $id_quiz_qst."_on";?>" class="radioCheck">Vrai</label>
<input name="<?php echo $id_quiz_qst?>" id="<?php echo $id_quiz_qst."_off";?>" value="Faux" type="radio" <?php if (isset($_POST[$id_quiz_qst]) && $_POST[$id_quiz_qst]=="Faux") echo "checked";?>>
<label for="<?php echo $id_quiz_qst."_off";?>" class="radioCheck">Faux</label>
<a class="slide-button btn"></a>
<label style="display:inline; float:right; position:absolute; font-size:18px;">
<i class="good icon_check_alt2" style="color:#17944d ;"></i>
<i class="not-good icon_close_alt2" style="color:#ff5032 ;"></i>
</label>
</span>
</span>
</div>
</div>
</div>
<?php } ?>
</div>
<?php
} ?>
<div style="overflow:auto;">
<div class="text-center">
<a class="next-prev" id="prevBtn" onclick="nextPrev(-1)"><i class="fa arrow_carrot-2left_alt "></i></a>
<a class="next-prev" id="nextBtn" onclick="nextPrev(1)"><i class="fa arrow_carrot-2right_alt"></i></a>
</div>
</div>
<!-- Circles which indicates the steps of the form: -->
<div style="text-align:center;margin-top:10px;">
<span class="step"></span><span class="step"></span><span class="step"></span><span class="step"></span><span class="step"></span>
</div>
<div id="submit-area" class="text-center">
<button id="submit_answers" name="submit_answers" type="submit" onclick="myfunc();" class="btn btn-primary btn-lg">Valider</button>
<button type="reset" class="btn btn-primary btn-lg">Annuler</button>
</div>
</form>
<script>
var currentTab = 0; // Current tab is set to be the first tab (0)
showTab(currentTab); // Display the current tab
function showTab(n) {
// This function will display the specified tab of the form...
var x = document.getElementsByClassName("tab");
x[n].style.display = "block";
//... and fix the Previous/Next buttons:
if (n == 0) {
document.getElementById("prevBtn").style.display = "none";
} else {
document.getElementById("prevBtn").style.display = "inline";
}
if (n == (x.length - 1)) {
document.getElementById("submit-area").style.display="block";
document.getElementById("nextBtn").style.display = "none";
} else {
document.getElementById("nextBtn").style.display = "inline";
}
//... and run a function that will display the correct step indicator:
fixStepIndicator(n)
}
function nextPrev(n) {
// This function will figure out which tab to display
var x = document.getElementsByClassName("tab");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
currentTab = currentTab + n;
// if you have reached the end of the form...
if (currentTab >= x.length) {
// ... the form gets submitted:
document.getElementById("questionForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
}
x = document.getElementsByClassName("tab");
y = x[currentTab].getElementsByTagName("input");
function changeColor(){
x = document.getElementsByClassName("tab");
y = x[currentTab].getElementsByTagName("input");
}
function validateForm() {
// This function deals with validation of the form fields
var x, y, i, good, not_good, valid = true;
x = document.getElementsByClassName("tab");
y = x[currentTab].getElementsByTagName("input");
good = document.getElementsByClassName("good");
not_good = document.getElementsByClassName("not-good");
// A loop that checks every input field in the current tab:
// alert(y[0].getElementById("btv").name);
var indexinc =0;
for (i = 0; i < y.length; i++) {
// If a field is empty...
//y[i].parentNode.className = y[i].parentNode.className.replace("invalid","");
if (!y[i].checked) {
indexinc++;
// add an "invalid" class to the field:
not_good[i].style.display="block";
// and set the current valid status to false
valid = false;
}
else{
good[i].style.display="block";
valid = true;
}
}
if(indexinc == 10)//Verify that he did answer all 22 questions and check that we have the 22 inputs not 44 inputs (vrai/faux)
valid = true;
// If the valid status is true, mark the step as finished and valid:
if (valid) {
document.getElementsByClassName("step")[currentTab].className += " finish";
}
return valid; // return the valid status
}
function fixStepIndicator(n) {
// This function removes the "active" class of all steps...
var i, x = document.getElementsByClassName("step");
for (i = 0; i < x.length; i++) {
x[i].className = x[i].className.replace(" active", "");
}
//... and adds the "active" class on the current step:
x[n].className += " active";
}
</script>

You can evaluate this with your html structure, using querySelectorAll and verifying that at least one radio button of a section is selected, this functions will work but I would recommend them to put them in a class, or a IIFE, to avoid declaring them in the global scope...
function nextTab(e) {
if (validate(e)){
console.log("go to next tab");
}
}
function validate(element) {
let val = true;
let select = element.closest("section");
select.querySelectorAll('.radio-container').forEach(function(container){
let radioChecked = container.querySelectorAll("input:checked");
container.style.backgroundColor = "white";
if(!radioChecked.length) {
val = val && false;
container.style.backgroundColor = "red";
}
});
return val;
}
<section id="tab1">
<div class="radio-container">
<input type="radio" name="gender" value="male"> Male
<input type="radio" name="gender" value="female"> Female
<input type="radio" name="gender" value="other"> Other
</div>
<div class="radio-container">
<input type="radio" name="gender1" value="male"> Male
<input type="radio" name="gender1" value="female"> Female
<input type="radio" name="gender1" value="other"> Other
</div>
<div class="radio-container">
<input type="radio" name="gender2" value="male"> Male
<input type="radio" name="gender2" value="female"> Female
<input type="radio" name="gender2" value="other"> Other
</div>
<button type="button" onclick="nextTab(this)">Continue</button>
</section>
UPDATE
You could use the same idea in your case you can get the tab section with your currentTab variable, within this tab you can get all your ".question-rbtn" elements, and with these elements you can verify if at least one radio button is checked...
function nextPrev(n) {
// Validate radio buttons
if(!validate()) return;
// This function will figure out which tab to display
var x = document.getElementsByClassName("tab");
// Exit the function if any field in the current tab is invalid:
if (n == 1 && !validateForm()) return false;
// Hide the current tab:
x[currentTab].style.display = "none";
// Increase or decrease the current tab by 1:
currentTab = currentTab + n;
// if you have reached the end of the form...
if (currentTab >= x.length) {
// ... the form gets submitted:
document.getElementById("questionForm").submit();
return false;
}
// Otherwise, display the correct tab:
showTab(currentTab);
}
function validate() {
let val = true;
let select = document.getElementsByClassName("tab")[currentTab];
select.querySelectorAll('.question-rbtn').forEach(function(container)
{
let radioChecked = container.querySelectorAll("input:checked");
container.style.backgroundColor = "white";
if(!radioChecked.length) {
val = val && false;
container.style.backgroundColor = "red";
}
});
return val;
}

Related

Problem with required warning message and submit form

I'm implemented the code taken from here to check if radio button is checked and if not, see a warning message.
My code works, but I have a button for submit with ajax (jQuery(function($)) that go ahead also if radio input is not checked.
Some idea to avoid to run function jQuery if function validateForm() is validated?
Here my code:
document.getElementById("filter").onsubmit = validateForm;
function validateForm() {
var validConsumo = validateConsumo();
//if all fields validate go to next page
return validConsumo;
}
function validateConsumo() {
var select = document.getElementById("filter").select,
errorSpan = document.getElementById("error_select"),
isChecked = false,
i;
errorSpan.innerHTML = "";
for (i = 0; i < select.length; i += 1) {
if (select[i].checked) {
isChecked = true;
break;
}
}
if (!isChecked) {
errorSpan.innerHTML = "* You must pick a value";
return false;
}
return true;
}
jQuery(function($) {
$('#filter').submit(function() {
var filter = $('#filter');
$.ajax({
url: filter.attr('action'),
data: filter.serialize(), // form data
type: filter.attr('method'), // POST
beforeSend: function(xhr) {
filter.find('button').text('Filtering...'); // changing the button label
},
success: function(data) {
filter.find('button').text('Filter'); // changing the button label back
$('#response').html(data); // insert data
}
});
return false;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" method="POST" id="filter">
<label class="toggler-wrapper style-19">
<input type="radio" name="select" onchange="changeThis1(this)">
<div class="toggler-slider">
<div class="toggler-knob"></div>
</div>
</label>
<div class="my"><strong>1</strong></div>
<label class="toggler-wrapper style-19">
<input type="radio" name="select" onchange="changeThis2(this)">
<div class="toggler-slider">
<div class="toggler-knob"></div>
</div>
</label>
<div class="my"><strong>2</strong></div>
<br>
<span id="error_select" class="error"></span>
<div class="buttonfiltra" id="buttonfiltra">
<button id="link-ida">Filter</button>
<input type="hidden" value="valuefilter" class="submit" id="link-id" name="action">
</div>
</form>
function validateForm() {
var validConsumo = validateConsumo();
//if all fields validate go to next page
return validConsumo;
}
function validateConsumo() {
var select = document.getElementById("filter").select,
errorSpan = document.getElementById("error_select"),
isChecked = false,
i;
errorSpan.innerHTML = "";
for (i = 0; i < select.length; i += 1) {
if (select[i].checked) {
isChecked = true;
break;
}
}
if (!isChecked) {
errorSpan.innerHTML = "* You must pick a value";
return false;
}
return true;
}
console.log(validateConsumo());
$(document).on("submit", "form#filter", function(e) {
e.preventDefault();
// Check for validations.
if (!validateConsumo()) {
console.log("Failed validation");
return;
}
console.log("Successful validation");
// Rest of the code here.
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="#" method="POST" id="filter">
<label class="toggler-wrapper style-19">
<input type="radio" name="select" />
<div class="toggler-slider">
<div class="toggler-knob"></div>
</div>
</label>
<div class="my"><strong>1</strong></div>
<label class="toggler-wrapper style-19">
<input type="radio" name="select" />
<div class="toggler-slider">
<div class="toggler-knob"></div>
</div>
</label>
<div class="my"><strong>2</strong></div>
<br />
<span id="error_select" class="error"></span>
<div class="buttonfiltra" id="buttonfiltra">
<button type="submit" id="link-ida">Filter</button>
<input type="hidden" value="valuefilter" class="submit" id="link-id" name="action" />
</div>
</form>
Remove document.getElementById("filter").onsubmit = validateForm;
and then update jQuery code like this:
$("#filter").on("submit", function (e) {
e.preventDefault();
// Check for validations.
if (!validateForm()) {
return;
}
// Rest of the code here.
});

How do I add an event listener for checking radio buttons using regular javascript?

As you can see below in the snippet if two buttons are checked an error is put in. I want to do this in real time without me having to do "checked = "checked". I'm not sure what to do with event listener to achieve this
function check(form) {
let count = 0
const boxes = form.querySelectorAll("input[type=checkbox]")
boxes.forEach(box => {
if(box.checked === true) {
count += 1
}
})
if(count > 1) {
const error = form.querySelector("span[class=error]")
error.innerHTML = "don't check more than 1"
}
}
check(document.querySelector("#form1"))
<form id="form1">
<label>A
<input type="checkbox" checked="checked">
</label> <br />
<label>B
<input type="checkbox" checked="checked">
</label> <br />
<label>C
<input type="checkbox">
</label> <br />
<span class="error"> </span>
</form>
You can simple use querySelectorAll method with foreach function wrap your change addEventListener inside forEeach.
Show error if checkbox is checked more then once. Else hide the error.
Run snippet below.
//Get all checkbox
const checkbox = document.querySelectorAll("input[type=checkbox]")
//Error
const error = document.querySelector(".error")
//Count
let count = 0
//Check all checkbox
checkbox.forEach(box => {
//Add event listener
box.addEventListener('change', (event) => {
//Increase count on checked
if (event.target.checked) {
count += 1
} else {
count -= 1
}
//Show error on count >= 1 / else nothing
if (count >= 1) {
error.textContent = "don't check more than 1"
} else {
error.textContent = ''
}
})
})
<form id="form1">
<label>A
<input type="checkbox" >
</label> <br />
<label>B
<input type="checkbox" >
</label> <br />
<label>C
<input type="checkbox" >
</label> <br />
<span class="error"> </span>
</form>
You can use the change event.
let count = 0
const boxes = form.querySelectorAll("input[type=checkbox]")
boxes.forEach(box => {
box.addEventListener("change", function(e){
if(box.checked) count++;
else count--;
if(count > 1) {
const error = form.querySelector("span[class=error]")
error.innerHTML = "don't check more than 1"
}
});
});

Get the values of column if checkbox/radio box is checked

I was wondering how to get the values in a certain column if the checkbox or radio button on that particular row is checked. I've already started and came up with this:
<script>
var Step = <?php echo $_SESSION['Step'] ?>;
if(Step == 3 || Step == 4 ) { setInterval(ScriptUpdate, 1000); }
function ScriptUpdate()
{
if(Step == 3)
{
var checked = $("input:checkbox:checked").length;
var radioButtonSelectedCount = $(document.querySelectorAll('input[type=radio]:checked')).parent().filter(function() {return $(this).text().trim()=="Yes"}).length;
var Counter = checked + radioButtonSelectedCount;
$('#ES3I').text(Counter + ' Items');
var price = 0;
$("#TextBookTB tr:gt(0) td:nth-child(6)").each(function(td){
var content = $(this).text();
if($.isNumeric(content)) {
price = price + Number(content);
console.log(price);
}
});
$("#ES3P").text(price);
}
}
</script>
The goal is that: when user checks the check box or answered 'yes' in the radio button it is the only time it will count the value. Apologies, I am really bad at jquery/javascript.
EDIT: html code as requested. The current output of the timer takes all of the values in all rows of that particular column.
<label class="radio-inline">
<input form="ES3S" type="radio" name="Textbook'.$i.'" value="'.$Result[$i]['ID'].'"> Yes
</label>
<label class="radio-inline">
<input form="ES3S" type="radio" name="Textbook'.$i.'" value="-1">No
</label>
<span class="d-inline-block" data-toggle="popover" title="Error" data-content="This book is required by the school. If you want to cancel this out, proceed to the principals office with the book for review." data-trigger="hover">
<input form="ES3S" required checked onclick="return false;" type="checkbox" value="'.$Result[$i]['ID'].'" name="Textbook'.$i.'">
</span>
try this if you are using table
var count = 0;
$('#TABLEID').find('tr').each(function () {
var tableRow = $(this);
if (tableRow.find('input[type="checkbox"]').is(':checked')) {
count += 1;
}
});
when user checks the check box or answered 'yes' in the radio button it is the only time it will count the value
$(function() {
var selector = 'input[name^="Textbook"]';
$(selector).on('click', function() {
var checked = $(selector + ':checked').map(function() {
return {
'type': this.type,
'value': this.value
};
}).get().filter(function(o) {
return '-1' !== o.value; // skip if value = -1(No)
});
console.log('checked inputs', checked);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<label><input type="radio" name="Textbook1" value="1"/>Yes</label>
<label><input type="radio" name="Textbook1" value="-1"/>No</label>
<input type="checkbox" name="Textbook1" value="1" />
</div>
<div>
<label><input type="radio" name="Textbook2" value="2"/>Yes</label>
<label><input type="radio" name="Textbook2" value="-1"/>No</label>
<input type="checkbox" name="Textbook2" value="2" />
</div>

Validate radio button in javascript

function validate()
{
var payment = checkRadio();
if (payment == false)
{
alert("Please select one button")
}
}
function checkRadio()
{
var payment = document.getElementsByName("payment");
for(i = 0; i < payment.length; i++)
{
if(payment[i].checked)
{
return true;
}
else
{
return false;
}
}
}
The html code below creates the radio buttons for the client to select one of the payment methods
<P> Payment Options:
<INPUT TYPE="Radio" Name="payment" Value="CC">Credit Card
<INPUT TYPE="Radio" Name="payment" Value="DC">Debit Card
<INPUT TYPE="Radio" Name="payment" Value="PP">PayPal
</P>
<INPUT TYPE="button" VALUE=" SUBMIT " onClick="validate()">
My problem is that when I execute this code and run it on chrome nothing happens. If someone could spot out where about I went wrong I would really appreciate it.
You need to surround your html code with <form>
<form>
Payment Options:
<INPUT TYPE="Radio" Name="payment" Value="CC">Credit Card
<INPUT TYPE="Radio" Name="payment" Value="DC">Debit Card
<INPUT TYPE="Radio" Name="payment" Value="PP">PayPal
<INPUT TYPE="button" VALUE=" SUBMIT " onClick="validate()">
</form>
And in your javascript change the checkRadio to:
function checkRadio()
{
var payment = document.getElementsByName('payment');
var paymentType = '';
for(i = 0; i < payment.length; i++)
{
if(payment[i].checked)
{
console.log(payment[i].value)
paymentType = payment[i].value;
}
}
return paymentType != '' ? true : false;
}
JSFiddle: https://jsfiddle.net/ttgrk8xj/16/
In your code you are checking only the first element is checked because you are returning from function in first iteration.
function checkRadio()
{
var payment = document.getElementsByName("payment");
for(i = 0; i < payment.length; i++)
{
if(payment[i].checked)
{
return true;
}
}
return false;
}

Multiple Radio Buttons that change Submit onclick location.href...possible syntax error

I'm using http://www.somacon.com/p143.php javascript for radio buttons to change the submit onclick location.href depending on which radio button is selected. But I think I may have an issue with my syntax as the button isn't working properly (I don't think it is pulling the value from the radio buttons properly). Thanks in advanced!
Here is the code:
<head>
<script type="text/javascript">
<!--
// return the value of the radio button that is checked
// return an empty string if none are checked, or
// there are no radio buttons
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;
}
}
}
//-->
</script>
</head>
<body>
<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>
<label for="number1"><input type="radio" value="http://www.ebay.com" name="number" id="number1"> One</label>
<label for="number2"><input type="radio" value="http://www.gamestop.com" name="number" id="number2"> Two</label>
<label for="number3"><input type="radio" value="http://www.amazon.com" name="number" id="number3"> Three</label>
<label for="number4"><input type="radio" value="http://www.usatoday.com" name="number" id="number4"> Four</label>
<p>
<input type="button" onclick="location.href='+getCheckedValue(document.forms['radioExampleForm'].elements['number']);" value="Show Checked Value">
ORIGNAL SUBMIT CODE THAT MADE AN ALERT BOX RATHER THAN location.href = <input type="button" onclick="alert('Checked value is: '+getCheckedValue(document.forms['radioExampleForm'].elements['number']));" value="Show Checked Value">
</form>
</body>
It's just a syntax error.
Change it to:
onclick="window.location.href = (getCheckedValue(document.forms['radioExampleForm'].elements['number']));"

Categories