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;
}
}
}
}
Related
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;
}
}
};
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
}
How can I make the checkbox disabled when they are populated with an array.
<c:forEach var="item" items="${flightItems}">
<c:set var="k" value="${k+1}"/>
<tr>
<td><c:out value="${k}"/></td>
<td>${item.startPoint}</td>
<td>${item.endPoint}</td>
<td><input id="cb" type="checkbox" name="itemId" value="${item.id}" onchange="check(this)"disabled/></td>
</tr>
</c:forEach>
I need to make that by clicking on one checkbox the rest are disabled. While all my attempts led to the fact that all the checkboxes become disabled. Here is my method for checkboxes. I understand my mistake, but I do not know how to fix it. Can you suggest something?
function check(self) {
var a = document.getElementById('cb');
var checkValue = self.checked;
for (i = 1; i < a.length; i++) {
if (a[i].type == 'checkbox')
a[i].checked = checkValue;
}
}
Something like this should point you in right direction.
First, change from id to class. IDs are always unique, while class can be same for logical components like this:
<c:forEach var="item" items="${flightItems}">
<c:set var="k" value="${k+1}"/>
<tr>
<td><c:out value="${k}"/></td>
<td>${item.startPoint}</td>
<td>${item.endPoint}</td>
<td><input class="cb" type="checkbox" name="itemId" value="${item.id}" onchange="check(this)"disabled/></td>
</tr>
</c:forEach>
Second,
function check(self) {
var a = document.getElementsByClassName('cb'); // get elements by class name
var checkValue = self.checked;
for (i = 0; i < a.length; i++) { // iterate from 0 instead of 1
if (a[i] != self && self.checked) // if checkbox is selected.
a[i].disabled = true; // disable others
}
}
Example:
<input class='cb' type='checkbox' onchange="check(this)" value="1">One
<input class='cb' type='checkbox' onchange="check(this)" value="2">Two
<input class='cb' type='checkbox' onchange="check(this)" value="3">Three
<input class='cb' type='checkbox' onchange="check(this)" value="4">Four
<script>
function check(self) {
var a = document.getElementsByClassName('cb'); // get elements by class name
var checkValue = self.checked;
for (i = 0; i < a.length; i++) { // iterate from 0 instead of 1
if (a[i] != self && self.checked) // if checkbox is selected.
a[i].disabled = true; // disable others
}
}
</script>
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);
});
}
})();
I have the following code. I need to see how many checkboxes have been checked in my form and if there are more than four display error and uncheck the last check box,everything is working but how can I uncheck the last check box, thanks
function SetHiddenFieldValue()
{
var checks = document.getElementById('toppings').getElementsByTagName('input');
var toppings = new Array();
var randomNumber = Math.floor((Math.random() * 9000) + 100);
var totalChecked = 0;
var itemPrice = 5.99;
for (i = 0; i < checks.length; i++)
{
if (checks[i].checked)
{
toppings[i] = checks[i].value;
totalChecked += 1;
}
}
if (totalChecked > 4) {
alert("You can only choose up to Max of 4 Toppings");
} else {
itemPrice = itemPrice + (totalChecked * 0.99);
document.getElementById('my-item-name').value = toppings.join("\t");
document.getElementById('my-item-id').value = randomNumber;
document.getElementById('my-item-price').value = itemPrice;
}
}
And my form is:
<form id="pizza" name="pizza" method="post" action="" class="jcart">
<input type="hidden" name="my-item-id" id="my-item-id" value="" />
<input type="hidden" name="my-item-name" id="my-item-name" value="" />
<input type="hidden" name="my-item-price" id="my-item-price" value="" />
<input type="hidden" name="my-item-qty" value="1" />
<input type="submit" name="my-add-button" value=" add " />
</form>
I think that I would handle this differently. I'd have a click handler on each checkbox that counts the number of checked boxes (including the current if it is being checked) to see if it is greater than 4. If it is, then I would stop the current event, pop the alert, and reset the state of the checkbox causing the alert. This way it would always popup when clicking the fourth checkbox.
To handle the case where javascript is disabled, you'd need to make sure that your server-side code validates that no more than 4 checkboxes have been checked.
JQuery example:
$(':checkbox').click( function() {
if ($(this).val() == 'on') { // need to count, since we are checking this box
if ($(':checkbox:checked').length > 4) {
alert( "You can only choose up to a maximum of 4 toppings." );
$(this).val('off');
}
}
});
Note if you had other types of checkboxes on the page you could use a class to distinguish them. In that case, the selector becomes (':checkbox.topping') and (':checkbox.topping:checked').
Keep track of the last checked checkbox and set its checked property to false:
// ...
var lastChecked; // Will be used in loop below
for (i = 0; i < checks.length; i++)
{
if (checks[i].checked)
{
toppings[i] = checks[i].value;
totalChecked += 1;
lastChecked = i; // Store the checkbox as last checked
}
}
if (totalChecked > 4) {
alert("You can only choose up to Max of 4 Toppings");
checks[lastChecked].checked = false; // Uncheck the last checked checkbox
} else {
// ...
If you want to uncheck all but the four first ones, do it like this:
// ...
for (i = 0; i < checks.length; i++)
{
if (checks[i].checked)
{
toppings[i] = checks[i].value;
totalChecked += 1;
if (totalChecked > 4) checks[i].checked = false; // Uncheck checkbox
}
}
Well you'll need to somehow pass into this method which particular checkbox was just checked, and then if the total checked count test fails, then just set that checkbox's .checked property to false.
What if the user checked more than five?
One way to do it is create a javascript function that returns false if more than four checkboxes are checked. In each checkbox, hook the new function like this:
<input type="checkbox" onclick="return myNewFunction(this);">
This will inhibit the user from checking any checkbox that is the fifth one.
Alternatively, you could prevent the user from making an invalid action in the first place, by disabling all the other boxes once four of them are checked, and displaying a message like "Choose up to four of these." This way, you don't let the user do something you know is invalid and then scold them.