Checkbox State Persistence before and after form submission - javascript

I am new to web developing. Apologies, if this is too simple but could not find the right way to fix this issue.
I have been asked to make a simple form with several checkboxes having a unique name and different values.
No problem for that. The issue I am encountering is that I have also been asked that I need to have all the checkboxes checked by default before submission and only to keep the checkboxes that remain checked, checked after the form submission. My code below does not make them all checked by default but save the results after form submission. Even adding the statement checked on the input tag does not change much.
<form onsubmit="return saveCheckboxValue();">
<label for="checkbox1">Option 1</label>
<input type="checkbox" id="checkbox1">
<br>
<label for="checkbox2">Option 2</label>
<input type="checkbox" id="checkbox2">
<br>
<label for="checkbox3">Option 3</label>
<input type="checkbox" id="checkbox3">
<br>
<input type="submit" value="Submit">
</form>
<script>
function saveCheckboxValue() {
// Get all checkbox elements
var checkboxes = document.querySelectorAll("input[type='checkbox']");
for (var i = 0; i < checkboxes.length; i++) {
if (checkboxes[i].checked) {
localStorage.setItem(checkboxes[i].id, true);
} else {
localStorage.removeItem(checkboxes[i].id);
}
}
return true;
}
window.onload = function() {
// Get all checkbox elements
var checkboxes = document.querySelectorAll("input[type='checkbox']");
for (var i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = JSON.parse(localStorage.getItem(checkboxes[i].id)) || false;
}
};
</script>
I tried to change the value to true
> window.onload = function() { // Get all checkbox elements var
> checkboxes = document.querySelectorAll("input[type='checkbox']");
>
> for (var i = 0; i < checkboxes.length; i++) {
> checkboxes[i].checked = JSON.parse(localStorage.getItem(checkboxes[i].id)) || true; } };
But by doing this, the checkboxes will be checked by default which is good, but if I uncheck some and submit the form, even the unchecked ones will be checked after the form submission.

From what I understood you want the boxes to be checked by default only at the first load, then the values to be persistent.
Would that work for you ?
in the saveCheckboxValue function, change the else condition to set the item to false instead of deleting it.
window.onload = function () {
// Get all checkbox elements
var checkboxes = document.querySelectorAll("input[type='checkbox']");
var val;
for (var i = 0; i < checkboxes.length; i++) {
val = JSON.parse(localStorage.getItem(checkboxes[i].id))
if (val == null) {
checkboxes[i].checked = true;
} else{
checkboxes[i].checked = val;
}
}
};

Related

validation on checkbox not working

I am building a project on attendance management. In one of the forms of my project, I have multiple checkboxes. I want that at least one checkbox must be checked for form submission. I tried with Javascript but the problem is, it flag an alert even if one or more checkbox is checked.
Here is my js code :
function validat(){
var a = document.getElementsByTagName("checkbox");
var bool=false;
for(var i=0;i<a.length;i++){
if(a[i].checked==true){
bool=true;
}
}
if(bool){
return true;
}
else{
alert("Sorry!Please select checkbox corresponding to students involved in duty leaves.");
return false;
}
Here's my checkbox code :
echo "<input type='checkbox' name=duty[]' value='$row[university_roll_no]'></td></tr>";
Since you need at least one checkbox to be checked you don't have to loop through all the checkboxes in your form. In the first found checkkbox you can stop.
function validat(){
var checkboxes = document.getElementsByTagName("checkbox");
var atLeastOneCheckBoxIsChecked = false;
for( var i = 0; i < checkboxes.length; i++ ){
if( checkboxes[i].checked == true ){
atLeastOneCheckBoxIsChecked = true;
break;
}
}
if(atLeastOneCheckBoxIsChecked){
return true;
}
else {
alert("Sorry!Please select checkbox corresponding to students involved in duty leaves.");
return false;
}
}
A more functional way to do the same thing, is to be use Array.prototype.some method:
function validat(){
var atLeastOneCheckBoxIsChecked = document.getElementsByTagName("checkbox")
.some(checkbox => checkbox.checked == true);
if(atLeastOneCheckBoxIsChecked){
return true;
}
else {
alert("Sorry!Please select checkbox corresponding to students involved in duty leaves.");
return false;
}
}
Here you have an example:
function check() {
var checkboxes = document.querySelectorAll('input[type="checkbox"]');
var checkedOne = Array.prototype.slice.call(checkboxes).some(x => x.checked);
if (!checkedOne) {
console.log('please check at least one box!');
}
console.log(checkedOne);
}
<fieldset>
<legend>Choose some monster features</legend>
<div>
<input type="checkbox" id="scales" name="feature" onClick=check()
value="scales" checked />
<label for="scales">Scales</label>
</div>
<div>
<input type="checkbox" id="horns" name="feature" onClick=check()
value="horns" />
<label for="horns">Horns</label>
</div>
<div>
<input type="checkbox" id="claws" name="feature" onClick=check()
value="claws" />
<label for="claws">Claws</label>
</div>
</fieldset>
You need to get input elements and check if type is "checkbox":
var a = document.getElementsByTagName("input");
for(var i = 0; i < a.length; i++) {
if(inputs[i].type == "checkbox") {
if (inputs[i].checked) {
bool=true;
}
}
}
Change your line
var a = document.getElementsByTagName("checkbox");
to
var a = document.querySelectorAll('input[type="checkbox"]');
I would have preferred you to use jQuery but with what you currently have, you need to do this:
var a = document.getElementsByTagName("input");
And then:
if(a[i].type == 'checkbox' && a[i].checked==true){
// Checked alert
}

Pass the name and value to JavaScript onClick function?

I have function that originally should disable group of check boxes if they are not checked. This function was designed to work onClick() and I was passing one argument onClick(this) from check box element. Now I need this function to be triggered on page load and I would need to pass the value from database. Tricky part is that I have more than one group of check boxes. Here is example of my HTML layout:
<tr>
<td>
<input type="checkbox" name="o_outcomeCk" id="o_firstOutcome" value="1" tabIndex="1" <cfif Trim(myData.o_outcomeCk) EQ 1>checked</cfif> onClick="ckChange('o_outcomeCk', 1)">First Outcome
</td>
<td>
<input type="checkbox" name="o_outcomeCk" id="o_secondOutcome" value="2" tabIndex="1" <cfif Trim(myData.o_outcomeCk) EQ 2>checked</cfif> onClick="ckChange('o_outcomeCk', 2)">Second Outcome
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="o_progressCk" id="o_firstProgress" value="1" tabIndex="1" <cfif Trim(myData.o_progressCk) EQ 1>checked</cfif> onClick="ckChange('o_progressCk', 1)">First Progress
</td>
<td>
<input type="checkbox" name="o_progressCk" id="o_secondProgress" value="2" tabIndex="1" <cfif Trim(myData.o_progressCk) EQ 2>checked</cfif> onClick="ckChange('o_progressCk', 2)">Second Progress
</td>
</tr>
Above in each onClick function I have tried to pass the checkbox name and value. When user click on the check box I should disable one that is unchecked. Also when I load the page value from database will decide which check box is checked and one that is not check should be disabled at this time as well. Here is my Javascript function:
function ckChange(ckType, ckVal){
var ckName = document.getElementsByName(ckType);
var numChecked = 0;
var index = 0;
for(var i=0; i < ckName.length; i++){
if(ckName[i].checked){
numChecked++;
index = i;
}
}
for(var i=0; i < ckName.length; i++){
if(numChecked == 0){
ckName[i].disabled = false;
}else{
if(i != index){
ckName[i].disabled = true;
}
}
}
}
For some reason my function doesn't work as expected. I'm thinking also of passing the id each time I call this fucntion on click but then how that will work on page load? Here is what I do to call the function when user gets to the page:
<cfoutput>
ckChange('o_outcomeCk','#Trim(myData.o_outcomeCk)#');
ckChange('o_progressCk','#Trim(myData.o_progressCk)#');
</cfoutput>
Here I'm able to pass the name and value from database. I'm open for suggestions and different approach if that would be more efficient. My current code doesn't work. Thank you.
Here is a working solution. I had to remove your ColdFusion code, since the code editor doesn't support it, and I inserted some temporary JavaScript (the first four statements) to simulate some imported data.
If one of the check boxes is checked, the other will be disabled. If neither is checked, they will both be enabled. This solution should be scalable as well, if you add more check boxes to either group.
Try the example to make sure it does what you need it to. It's simulating the first box in o_outcomeCk and the second box in o_progressCk as being checked.
// simulate imported data & CF checkbox selecting
document.getElementsByName("o_outcomeCk")[0].checked = true;
document.getElementsByName("o_progressCk")[1].checked = true;
ckChange('o_outcomeCk',1);
ckChange('o_progressCk',2);
function ckChange(ckType, ckVal){
var ckName = document.getElementsByName(ckType);
var numChecked = 0; // counter
var index = 0; // which index is checked
for(var i = 0; i < ckName.length; i++){
// check which boxes in this set are checked
if (ckName[i].checked) {
// if the box that was clicked is checked
numChecked++;
index = i;
}
}
if (numChecked == 0) {
// enable both boxes
for (var i = 0; i < ckName.length; i++) {
ckName[i].disabled = false;
}
}
else {
// disable other box
for (var i = 0; i < ckName.length; i++) {
if (i != index) {
ckName[i].disabled = true;
}
}
}
}
<table>
<tr>
<td>
<input type="checkbox" name="o_outcomeCk" id="o_firstOutcome" value="1" tabIndex="1" onClick="ckChange('o_outcomeCk', 1)">First Outcome
</td>
<td>
<input type="checkbox" name="o_outcomeCk" id="o_secondOutcome" value="2" tabIndex="1" onClick="ckChange('o_outcomeCk', 2)">Second Outcome
</td>
</tr>
<tr>
<td>
<input type="checkbox" name="o_progressCk" id="o_firstProgress" value="1" tabIndex="1" onClick="ckChange('o_progressCk', 1)">First Progress
</td>
<td>
<input type="checkbox" name="o_progressCk" id="o_secondProgress" value="2" tabIndex="1" onClick="ckChange('o_progressCk', 2)">Second Progress
</td>
</tr>
</table>
UPDATE: Below is an alternate version of the JavaScript, which uses only one for loop. If you want to use it, just swap it out for the JavaScript code above. The only HTML that needs to be changed is the onclick attribute for each checkbox, which should be changed to onClick="ckChange(this)".
// simulate imported data & CF checkbox selecting
document.getElementsByName("o_progressCk")[1].checked = true;
ckChange("o_outcomeCk", 0);
ckChange("o_progressCk", 2);
function ckChange(that, val){
var isChecked = false;
var wasClicked = false;
var index = 0;
var ckType = that;
if (!!that.type) { // if called from a click
ckType = that.name;
wasClicked = true;
if (!!that.checked) {
index = that.value - 1;
isChecked = true;
}
}
var ckName = document.getElementsByName(ckType);
for(var i=0; i < ckName.length; i++){
if (isChecked) {
// if called from click and box was checked
if (index != i) {
ckName[i].disabled = true;
}
}
else if (wasClicked) {
// if called from click and box was unchecked
ckName[i].disabled = false;
}
else {
// if on load
if (val != 0) {
// one is checked
if (i != val - 1) {
ckName[i].disabled = true;
}
}
else {
// none checked
ckName[i].disabled = false;
}
}
}
}

Javascript form validation checkbox and radio not working

I have a form that I need to validate with javascript to make sure at least one checkbox and one radio is checked. I know it would probably be easier to use jQuery but I'm trying to accomplish this with pure javascript. Here is the code:
<form name="bulbform" action="compute.php" onsubmit=" return validateForm()" method="post">
<p>Enter your name: <input type="text" name="name" size="20"></p>
<p><strong>Light Bulbs</strong></p>
<label><input type="checkbox" name="bulbs[]" value="2.39">Four 25-watt light bulbs for $2.39</label><br>
<label><input type="checkbox" name="bulbs[]" value="4.29">Eight 25-watt light bulbs for $4.29</label><br>
<label><input type="checkbox" name="bulbs[]" value="3.95">Four 25-watt long-life light bulbs $3.95</label><br>
<label><input type="checkbox" name="bulbs[]" value="7.49">Eight 25-watt long-life light bulbs $7.45</label><br>
<p><strong>Payment Method</strong></p>
<label><input type="radio" name="cc" value="Visa">Visa</label><br>
<label><input type="radio" name="cc" value="Master Card">Master Card</label><br>
<label><input type="radio" name="cc" value="Discover">Discover</label><br>
<p><input type="submit" value="Order" /> <input type="reset" value="Clear form"/></p></form>
Here is my javascript
var radios = document.getElementsByTagName('input');
var value;
for (var i = 0; i < radios.length; i++) {
if (radios[i].type === 'radio' && radios[i].checked) {
// get value, set checked flag or do whatever you need to
value = radios[i].value;
alert(value);
return true;
}
else{
alert("You must select a payment method.")
return false;
}
With the else removed I'm able to show the credit card selected but when I add the else it always says you must select a payment method and is never true... Thanks ahead of time for any advice you can give.
See this plunker: https://plnkr.co/edit/5NiIA1w9axvmOJEjXVlP
function validateForm() {
var radios = document.getElementsByTagName('input');
var value;
var paymentMethodSelected = false;
for (var i = 0; i < radios.length; i++) {
if (radios[i].type === 'radio' && radios[i].checked) {
// get value, set checked flag or do whatever you need to
value = radios[i].value;
alert(value);
paymentMethodSelected = true;
}
}
if (!paymentMethodSelected) {
alert("You must select a payment method.");
return false;
}
return true;
}
You don't have an ending form tag (not critical, but good practice)
You were returning from the validation function before you had checked all radio buttons
The check for an invalid form state should be handled outside the for loop
The variable radios contains checkboxes, textbox, and radio buttons.
A radio button and a textbox are not checkbox.
So the condition radios[i].type=='radio' && radios.type='checked' will evaluate to false and the else part will be evaluated.
The code below uses the variables checkedCB and checkedRadio to store if any checkbox or radio button is checked.
Try something like this:
function validateForm() {
var inputs = document.getElementsByTagName('input');
var valued;
var checkedCB=false,checkedRadio=false;
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type == 'checkbox' && inputs[i].checked) {
checkedCB=true;
}
else if(inputs[i].type == 'radio' && inputs[i].checked) {
checkedRadio=true;
}
if(checkedRadio && checkedCB) return true;
}
alert("You must select atleast one light bulb and a payment method.");
return false;
}
And you can put the attribute checked in any one radio button.
i.e.
<label><input type="radio" name="cc" value="Visa" checked>Visa</label><br>
If you would like to make sure at least one checkbox and one radio is checked before form submit then, you could introduce counters variable in your scripts that will count how many check box and radio button checked inside of the loop.
And before return just check at least one checkbox and one radio selected as follow:
if(checkbox_checked_count>=1&&radio_checked_count==1){
alert("Yahoo! You have successfully validated your form.")
return true;
}else{
alert("You must select a payment method.")
return false;
}
Your validateForm() function full script could like following one:
function validateForm(){
var inputs = document.getElementsByTagName('input');
var radio_checked_count=0;
var checkbox_checked_count=0;
var i;
for (i = 0; i < inputs.length; i++) {
if (inputs[i].type == "checkbox"&&inputs[i].checked) {
checkbox_checked_count++;
}
if (inputs[i].type == "radio"&&inputs[i].checked) {
radio_checked_count++;
}
}
if(checkbox_checked_count>=1&&radio_checked_count==1){
alert("Yahoo! You have successfully validated your form.")
return true;
}else{
alert("You must select a payment method.")
return false;
}
}
Here is what your javascript is doing.
It checks the first radio button, finds that it is NOT checked so it executes the else statement and alerts that you must choose a card or whatever. Then it hits the return false statement and exits the loop (doesn't matter what it's returning, a return statement will exit the loop). That's all.
If you had checked the first checkbox using an attribute checked, it will find that the first radio button IS checked and then alert it and return out of the loop without checking the rest. Your for loop is not closed in the question if you want to edit it.
You should prompt user for payment selection only after for-loop, try this code snippet:
function validateForm() {
var payments = document.getElementsByName("cc");
var count = payments.length;
var selected = false;
while (count--)
if (selected = payments[count].checked)
break;
if (!selected) {
alert('Choose payment method');
return false;
}
return true;
}
<form name="bulbform" action="compute.php" onsubmit=" return validateForm()" method="post">
<p><strong>Payment Method</strong>
</p>
<label>
<input type="radio" name="cc" value="Visa">Visa</label>
<br>
<label>
<input type="radio" name="cc" value="Master Card">Master Card</label>
<br>
<label>
<input type="radio" name="cc" value="Discover">Discover</label>
<br>
<p>
<input type="submit" value="Order" />
<input type="reset" value="Clear form" />
</p>
Thanks to Mahesh Bansod for the help I used their example and tweaked it to my needs. Below is my working validation code for a textbox, checkbox and radio.
function validateForm(){
//check to make sure the name is not blank
var cusName = document.forms["bulbform"]["name"].value;
if (cusName == null || cusName == ""){
alert("Your name must be filled out.");
return false;
}
//check to see that atleast one radio and checkbox are checked
var inputs = document.getElementsByTagName('input');
var checkCheckBox=false, checkRadio=false; //set both rado and checkbox to false
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].type == 'checkbox' && inputs[i].checked) {
checkCheckBox=true; //set checkbox true if one is checked
}
else if(inputs[i].type == 'radio' && inputs[i].checked) {
checkRadio=true; //set radio true if one is checked
}
if(checkRadio && checkCheckBox) return true; //if both are true return true
}
//if checkbox is false alert user and return false
if(!checkCheckBox){
alert("You must select atleast one item.");
return false; //
}
//if radio is false alert user and return false
if(!checkRadio){
alert("You must select a payment method.");
return false;
}
}

how to get all checkboxes from one of three forms?

I have three forms, each of them has checkboxes and submit button. I need to get all checkbox names or id by clicking on the submit button in only this form.
And for other two also.
function getCheckedBoxes(item) {
var checkboxes = document.getElementsByName(item);
var checkboxesChecked = [];
// loop over them all
for (var i=0; i<checkboxes.length; i++) {
// And stick the checked ones onto an array...
if (checkboxes[i].checked) {
checkboxesChecked.push(checkboxes[i]);
}
}
// Return the array if it is non-empty, or null
console.log(checkboxes);
return checkboxesChecked.length > 0 ? checkboxesChecked : null;
}
var inp = document.getElementsByName('send');
for(var i = 0; i < inp.length; i++){
inp[i].addEventListener('click', function(e) {
getCheckedBoxes("item");
e.preventDefault();
});
}
example of my checkboxes
<form>
<input id="check29" type="checkbox" name="item" value="29" />
<input class="lab-btn" type="submit" value="ADD ALL" name="send">
</form>
You can pass the form as a parameter to the function, then use querySelectorAll to get all of its inputs with the desired name.
So first, change the event handler to this:
inp[i].addEventListener('click', function(e) {
getCheckedBoxes(this.form, "item");
e.preventDefault();
});
Then the function itself to:
function getCheckedBoxes(oForm, item) {
var checkboxes = oForm.querySelectorAll('input[name="' + item + '"]');
//...
}
To select all checboxes on a page you can use:
var checkboxes = document.querySelectorAll("input[type=checkbox]");
// And for all checkboxes in a form:
var checkboxesInForm = form.querySelectorAll("input[type=checkbox]");
See https://developer.mozilla.org/nl/docs/Web/API/Document/querySelectorAll for documentation.
Does this answer your question?

display alert on each selected check box from a group of checkboxes

I have 3 checkboxes and I want them to do certain actions i.e display an alert box when they are checked and when one check box is checked, the others should be unchecked.
I've been able to get the second part to work where only one checkbox can be checked at a time but I can't seem to make the first part of displaying an alert box work.
js that ensures only one box is checked at any time:
function qtyBox(e) {
var c = document.getElementsByClassName("qty");
for (var i = 0; i < c.length; i++) {
c[i].checked = false;
}
e.checked = true;
}
html:
<input class="qty" type="checkbox" id="pails" onchange="qtyBox(this)"/>Pails
<input class="qty" type="checkbox" id="liters" onchange="qtyBox(this)"/>Liters
<input class="qty" type="checkbox" id="gallons" onchange="qtyBox(this)"/>Gallons
Now all that's left is when Pails is checked,I want an alert box to display pails. when liters is checked, an alert box to display liters and when gallons is checked, an alert box to display gallons.
You need to get reference to the input. Just add:
var currId = e.id;
if(currId === "pails") alert("Pails");
else if(currId === "liters") alert("Liters");
else if(currId === "gallons") alert("Gallons");
so it become:
function qtyBox(e) {
var c = document.getElementsByClassName("qty");
for (var i = 0; i < c.length; i++) {
c[i].checked = false;
}
e.checked = true;
var currId = e.id;
if(currId === "pails") alert("Pails");
else if(currId === "liters") alert("Liters");
else if(currId === "gallons") alert("Gallons");
}
Hope this help.
Use radio buttons with a common name (e.g. units) and a click listener to do the alert. Add a value attribute for the value, an ID seems redundant:
<input class="qty" name="units" type="radio" value="pails" onclick="alert(this.value)">Pails
<input class="qty" name="units" type="radio" value="litres" onclick="alert(this.value)">Litres
<input class="qty" name="units" type="radio" value="gallons" onclick="alert(this.value)">Gallons
Though I'd delegate the listener to an ancestor element.
You should remove the onclick from the html - and just use something like this. However, if you want to use jquery would easier, but here is vanilla javascript solution. ( in a js file or wrapped in script tags )
(function(){
var inputs = document.getElementsByClassName('qty');
for(i=0; i<inputs.length; i++){
var el = inputs[i];
el.addEventListener('click', function(){
for (var i = 0; i < inputs.length; i++) {
inputs[i].checked = false;
}
this.checked = true
alert(this.id);
});
}
})();

Categories