make checkbox behave like radio buttons with javascript - javascript

I need to manipulate the behavior of the check boxes with javascript. They should basically behave like radio buttons (only one selectable at a time, plus unselect any previous selections).
The problem is that I can't use plain radio buttons in first place, because the name attribute for each radio button would be different.
I know its not the ultimate and shiniest solutions to make an apple look like a pear, and w3c wouldn't give me their thumbs for it, but it would be a better solution right now than to change the core php logic of the entire cms structure ;-)
Any help is much appreciated!

HTML :
<label><input type="checkbox" name="cb1" class="chb" /> CheckBox1</label>
<label><input type="checkbox" name="cb2" class="chb" /> CheckBox2</label>
<label><input type="checkbox" name="cb3" class="chb" /> CheckBox3</label>
<label><input type="checkbox" name="cb4" class="chb" /> CheckBox4</label>
jQuery :
$(".chb").change(function() {
$(".chb").prop('checked', false);
$(this).prop('checked', true);
});
if you want user can unchecked selected item :
$(".chb").change(function() {
$(".chb").not(this).prop('checked', false);
});
Demo :
http://jsfiddle.net/44Zfv/724/

There are many ways to do this. This is a clickhandler (plain js) for a div containing a number of checkboxes:
function cbclick(e){
e = e || event;
var cb = e.srcElement || e.target;
if (cb.type !== 'checkbox') {return true;}
var cbxs = document.getElementById('radiocb')
.getElementsByTagName('input'),
i = cbxs.length;
while(i--) {
if (cbxs[i].type
&& cbxs[i].type == 'checkbox'
&& cbxs[i].id !== cb.id) {
cbxs[i].checked = false;
}
}
}
Here's a working example.

This is a better option as it allows unchecking also:
$(".cb").change(function () {
$(".cb").not(this).prop('checked', false);
});

I kept it simple...
<html>
<body>
<script>
function chbx(obj)
{
var that = obj;
if(document.getElementById(that.id).checked == true) {
document.getElementById('id1').checked = false;
document.getElementById('id2').checked = false;
document.getElementById('id3').checked = false;
document.getElementById(that.id).checked = true;
}
}
</script>
<form action="your action" method="post">
<Input id='id1' type='Checkbox' Name ='name1' value ="S" onclick="chbx(this)"><br />
<Input id='id2' type='Checkbox' Name ='name2' value ="S" onclick="chbx(this)"><br />
<Input id='id3' type='Checkbox' Name ='name3' value ="S" onclick="chbx(this)"><br />
<input type="submit" value="Submit" />
</form>
</body>
</html>

#DJafari's answer doesn't let unchecking the checkbox. So I've updated it like this:
$(".chb").change(function(e) {
//Getting status before unchecking all
var status = $(this).prop("checked");
$(".chb").prop('checked', false);
$(this).prop('checked', true);
//false means checkbox was checked and became unchecked on change event, so let it stay unchecked
if (status === false) {
$(this).prop('checked', false);
}
});
https://jsfiddle.net/mapetek/nLtb0q1e/4/

Just in case it helps someone else
I was having the same situation where my client needed to have a checkbox behaving like a radio button. But to me it was meaningless to use a checkbox and make it act like radio button and it was very complex for me as I was using so many checkboxes in a GridView Control.
My Solution: So, I styled a radio button look like a checkbox and took the help of grouping of radio buttons.

You could give the group of checkboxes you need to behave like this a common class, then use the class to attach the following event handler:
function clickReset ()
{
var isChecked = false,
clicked = $(this),
set = $('.' + clicked.attr ('class') + ':checked').not (clicked);
if (isChecked = clicked.attr ('checked'))
{
set.attr ('checked', false);
}
return true;
}
$(function ()
{
$('.test').click (clickReset);
});
Note: This is pretty me just shooting from the hip, I've not tested this and it might need tweaking to work.
I would advise that you do look into finding a way of doing this with radio buttons if you can, as radios are the proper tool for the job. Users expect checkboxes to behave like checkboxes, not radios, and if they turn javascript off they can force through input into the server side script that you weren't expecting.
EDIT: Fixed function so that uncheck works properly and added a JS Fiddle link.
http://jsfiddle.net/j53gd/1/

<html>
<body>
<form action="#" method="post">
Radio 1: <input type="radio" name="radioMark" value="radio 1" /><br />
Radio 2: <input type="radio" name="radioMark" value="radio 2" /><br />
<input type="submit" value="Submit" />
</form>
</body>
</html>
Ultimately you can use brackets with the name attribute to create an array of radio input like so:
<input type="radio" name="radioMark[]" value="radio1" />Radio 1
<input type="radio" name="radioMark[]" value="radio2" />Radio 2
<input type="radio" name="radioMark[]" value="radio3" />Radio 3
<input type="radio" name="radioMark[]" value="radio4" />Radio 4
What matters to transfer in the end are whats in the value attribute. Your names do not have to be different at all for each radio button. Hope that helps.

In Simple JS.
Enjoy !
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function onChoiceChange(obj) {
// Get Objects
var that=obj,
triggerChoice = document.getElementById(that.id),
domChoice1 = document.getElementById("Choice1"),
domChoice2 = document.getElementById("Choice2");
// Apply
if (triggerChoice.checked && triggerChoice.id === "Choice1")
domChoice2.checked=false;
if (triggerChoice.checked && triggerChoice.id === "Choice2")
domChoice1.checked=false;
// Logout
var log = document.getElementById("message");
log.innerHTML += "<br>"+ (domChoice1.checked ? "1" : "0") + ":" + (domChoice2.checked ? "1" : "0");
// Return !
return that.checked;
}
</script>
</head>
<body>
<h1 id="title">Title</h1>
<label><input type="checkbox" onclick="onChoiceChange(this)" id="Choice1" />Choice #1</label>
<label><input type="checkbox" onclick="onChoiceChange(this)" id="Choice2" />Choice #2</label>
<hr>
<div id="message"></div>
</body>
</html>

try this
<form id="form" action="#">
<input name="checkbox1" type="checkbox" />
<input name="checkbox2" type="checkbox" />
<input name="checkbox3" type="checkbox" />
<input name="checkbox4" type="checkbox" />
<input name="checkbox5" type="checkbox" />
<input name="checkbox6" type="checkbox" />
<input name="checkbox7" type="checkbox" />
<input name="checkbox8" type="checkbox" />
<input name="checkbox9" type="checkbox" />
<input name="checkbox10" type="checkbox" />
<input type="submit" name="submit" value="submit"/>
</form>
and this is the javascript
(function () {
function checkLikeRadio(tag) {
var form = document.getElementById(tag);//selecting the form ID
var checkboxList = form.getElementsByTagName("input");//selecting all checkbox of that form who will behave like radio button
for (var i = 0; i < checkboxList.length; i++) {//loop thorough every checkbox and set there value false.
if (checkboxList[i].type == "checkbox") {
checkboxList[i].checked = false;
}
checkboxList[i].onclick = function () {
checkLikeRadio(tag);//recursively calling the same function again to uncheck all checkbox
checkBoxName(this);// passing the location of selected checkbox to another function.
};
}
}
function checkBoxName(id) {
return id.checked = true;// selecting the selected checkbox and maiking its value true;
}
window.onload = function () {
checkLikeRadio("form");
};
})();

I like D.A.V.O.O.D's Answer to this question, but it relies on classes on the checkbox, which should not be needed.
As checkboxes tend to be related in that they will have the same (field) name, or a name which make them part of an array, then using that to decide which other checkboxes to untick would be a better solution.
$(document)
.on('change','input[type="checkbox"]',function(e){
var $t = $(this);
var $form = $t.closest('form');
var name = $t.attr('name');
var selector = 'input[type="checkbox"]';
var m = (new RegExp('^(.+)\\[([^\\]]+)\\]$')).exec( name );
if( m ){
selector += '[name^="'+m[1]+'["][name$="]"]';
}else{
selector += '[name="'+name+'"]';
}
$(selector, $form).not($t).prop('checked',false);
});
This code on jsFiddle

Related

Remove part of form when checkbox is checked

I'm trying to make a form that will hide and show some parts of the form. It working correctly in some tries. But when the user chooses and checks an option with class badCheckbox which is showing badField subsequently then user checks option without class badCheckbox which should showing 'goodField' than 'badField' is not hiding and still is shown.
And when a user tries to check options separately all work correctly only in upper mentioned case.
Is there any way to do it?
//Script to hide and show div
$('.badCheckbox').change(function() {
let checked = 0;
$('.badCheckbox').each(function() {
if (this.checked) {
checked += 1;
}
});
if (checked != 0) {
$('#badField').show();
$('#goodField').hide();
} else {
$('#badField').hide();
$('#goodField').show();
}
});
//script to check only one of three
$(".oneChecked").on('click', function() {
// in the handler, 'this' refers to the box clicked on
var $box = $(this);
if ($box.is(":checked")) {
var group = "input:checkbox[name='" + $box.attr("name") + "']";
$(group).prop("checked", false);
$box.prop("checked", true);
} else {
$box.prop("checked", false);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input name="checkin" type="checkbox" class="oneChecked badCheckbox" />
<input name="checkin" type="checkbox" class="oneChecked badCheckbox" />
<input name="checkin" type="checkbox" class="oneChecked" />
<div id="badField" style="display:none;">
<p>:((</p>
<input type="submit" />
</div>
<div id="goodField">
<p>NICE!!!</p>
<input type="submit" />
</div>
here is a short version
$('#checks').on('change', 'input[name="checkin"]', function (){
if( $(this).is(':checked') ){
$('#checks .oneChecked:checked').prop('checked', false);
$(this).prop('checked', true);
} else {
$('#checks .oneChecked:checked').prop('checked', false);
$(this).prop('checked', false);
}
if( $('#checks .badCheckbox:checked').is(':checked') ){
$('#badField').show();
$('#goodField').hide();
} else {
$('#badField').hide();
$('#goodField').show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="checks">
<input name="checkin" type="checkbox" class="oneChecked badCheckbox"/>
<input name="checkin" type="checkbox" class="oneChecked badCheckbox"/>
<input name="checkin" type="checkbox" class="oneChecked"/>
</div>
<div id="badField" style="display:none;">
<p>:((</p>
<input type="submit"/>
</div>
<div id="goodField">
<p>NICE!!!</p>
<input type="submit"/>
</div>
Consider the following improvements.
$(function() {
function checkStuff(checked) {
if (checked) {
$('#badField').show();
$('#goodField').hide();
} else {
$('#badField').hide();
$('#goodField').show();
}
}
//script to check only one of three
$(".boxes").on('change', ".oneChecked", function() {
if ($(this).is(":checked")) {
$(".boxes input[type='checkbox']").prop("checked", false);
$(this).prop("checked", true);
checkStuff($(this).is(".badCheckbox"));
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="boxes">
<input name="checkin" type="checkbox" class="oneChecked badCheckbox" />
<input name="checkin" type="checkbox" class="oneChecked badCheckbox" />
<input name="checkin" type="checkbox" class="oneChecked" />
</div>
<div id="badField" style="display:none;">
<p>:((</p>
<input type="submit" />
</div>
<div id="goodField">
<p>NICE!!!</p>
<input type="submit" />
</div>
it's because you don't have an event when user click and the third checkbox.
Your function to show/hide message work when there are an update (change) on an input with the class .badCheckbox but when you click on the third (where doesn't have the class) your function is not called.
I think you should have a class on all your checkbox and use it in your function who lister the change.
Something like this :
$('.checkbox').change(function() {
let checked = 0;
$('.badCheckbox').each(function() {
// ...
});
And your html
<input name="checkin" type="checkbox" class="checkbox oneChecked badCheckbox"/>
<input name="checkin" type="checkbox" class="checkbox oneChecked badCheckbox"/>
<input name="checkin" type="checkbox" class="checkbox oneChecked"/>
There is a lot of optimization that can be done to improve your code, like using the radio to remove your oneChecked function or printing the right message when the checkbox is checked instead of using show/hide two div but i think you should see it in the future
I hope this can help you and welcome to StackOverflow
First of all, obviously your checkboxes have to act like radios. As I understand, that is what you want to do. So, I modifyed your script a little bit to make checkboses to act as they are radio inputs, and in the same time to show/hide paragraph, depending on if clicked element has class badCheckbox and it's state (checkd or not). Here is the result:
//Script to hide and show div
$('.oneChecked').click( (everyOne) => {
//handles click (and change) on every element with class oneChecked
//they all has it in your example
$('.oneChecked').each( (ind, currentOne) => {
//iterate to all elements with class oneChecked
//and compare if matches clicked one
if ( !$(currentOne).is($(everyOne.target)) ) {
//other instance, not clisked one, so clear it
//to simulate behaviour of radio input
$(currentOne).prop('checked', false);
}
});
//checks if clicked element is bad or not and show/hide your p
if ($(everyOne.target).hasClass('badCheckbox') && $(everyOne.target).prop('checked')){
console.log('b-s/h');
$('#badField').show();
$('#goodField').hide();
} else {
console.log('s/b-h');
$('#badField').hide();
$('#goodField').show();
}
});
Here is an workign example in CodePen: https://codepen.io/kalatchev/pen/gOpJBOv

Uncheck a checkbox and another checkbox will untick

I have two checkboxes in a form. onclick if a checkbox called email is unchecked how can I get the other checkbox to also uncheck (if it is checked) ?
document.getElementById('email').onclick = function() {
if (!this.checked) {
!document.getElementById("other").checked;
} else {
// if not checked ...
}
};
Am I completey barking up the wrong tree? Any help appriciated
To synchronize the checking of the both at the same time you need just to use this.checked of the first clicked one on the checked attribute of the second one like :
document.getElementById("other").checked = this.checked;
NOTE : That will work on one way, what means the check will be synchronized just when you click on the first checkbox that you've attached the click event to.
document.getElementById('email').onclick = function() {
document.getElementById("other").checked = this.checked;
};
<input id="email" type="checkbox" /> CHECKBOX 1
<br>
<input id="other" type="checkbox" /> CHECKBOX 2
You can make it like :
<form id="test" action="#" method="post">
<div>
<input type="checkbox" name="check" id="check"/>
</div>
<div>
<input type="checkbox" name="check2" id="check2"/>
</div>
</form>
document.getElementById('check').onclick = function() {
if (!this.checked) {
document.getElementById("check2").checked = false;
} else {
// other logic ...
}};
Test it online on jsfiddle : https://jsfiddle.net/3dtq0w8x/
In your test code you are not setting the checked property of "other" to any value.
You are just reading its value, then inverting it (with !).
You could try:
document.getElementById("other").checked = false;
You can add event listener to email checkbox (which is a good practice) and then check if it is check or not and deal with the other checkbox according to that
For example
var ckb = document.getElementById('email')
ckb.addEventListener("click", function(e){
if(!e.target.checked)
document.getElementById('ot').checked = false;
})
<input type="checkbox" name="na" value="email" id="email">Email<br>
<input type="checkbox" name="na" value="other" id="ot">Other
This should help
function check() {
if(document.getElementById("email").checked){
document.getElementById("other").checked = true;
}else{
document.getElementById("other").checked = false;
}
}
HTML
<input type='checkbox' id='email' name='checkbox' onclick="check()" >email
<input type='checkbox' id='other' name='checkbox'>other

Problems with checkbox required php-js [duplicate]

When using the newer browsers that support HTML5 (FireFox 4 for example);
and a form field has the attribute required='required';
and the form field is empty/blank;
and the submit button is clicked;
the browsers detects that the "required" field is empty and does not submit the form; instead browser shows a hint asking the user to type text into the field.
Now, instead of a single text field, I have a group of checkboxes, out of which at least one should be checked/selected by the user.
How can I use the HTML5 required attribute on this group of checkboxes?
(Since only one of the checkboxes needs to be checked, I can't put the required attribute on each and every checkbox)
ps. I am using simple_form, if that matters.
UPDATE
Could the HTML 5 multiple attribute be helpful here? Has anyone use it before for doing something similar to my question?
UPDATE
It appears that this feature is not supported by the HTML5 spec: ISSUE-111: What does input.#required mean for #type = checkbox?
(Issue status: Issue has been marked closed without prejudice.)
And here is the explanation.
UPDATE 2
It's an old question, but wanted to clarify that the original intent of the question was to be able to do the above without using Javascript - i.e. using a HTML5 way of doing it. In retrospect, I should've made the "without Javascript" more obvious.
Unfortunately HTML5 does not provide an out-of-the-box way to do that.
However, using jQuery, you can easily control if a checkbox group has at least one checked element.
Consider the following DOM snippet:
<div class="checkbox-group required">
<input type="checkbox" name="checkbox_name[]">
<input type="checkbox" name="checkbox_name[]">
<input type="checkbox" name="checkbox_name[]">
<input type="checkbox" name="checkbox_name[]">
</div>
You can use this expression:
$('div.checkbox-group.required :checkbox:checked').length > 0
which returns true if at least one element is checked.
Based on that, you can implement your validation check.
Its a simple trick. This is jQuery code that can exploit the html5 validation by changing the required properties if any one is checked. Following is your html code (make sure that you add required for all the elements in the group.)
<input type="checkbox" name="option[]" id="option-1" value="option1" required/> Option 1
<input type="checkbox" name="option[]" id="option-2" value="option2" required/> Option 2
<input type="checkbox" name="option[]" id="option-3" value="option3" required/> Option 3
<input type="checkbox" name="option[]" id="option-4" value="option4" required/> Option 4
<input type="checkbox" name="option[]" id="option-5" value="option5" required/> Option 5
Following is jQuery script, which disables further validation check if any one is selected. Select using name element.
$cbx_group = $("input:checkbox[name='option[]']");
$cbx_group = $("input:checkbox[id^='option-']"); // name is not always helpful ;)
$cbx_group.prop('required', true);
if($cbx_group.is(":checked")){
$cbx_group.prop('required', false);
}
Small gotcha here: Since you are using html5 validation, make sure you execute this before the it gets validated i.e. before form submit.
// but this might not work as expected
$('form').submit(function(){
// code goes here
});
// So, better USE THIS INSTEAD:
$('button[type="submit"]').on('click', function() {
// skipping validation part mentioned above
});
HTML5 does not directly support requiring only one/at least one checkbox be checked in a checkbox group. Here is my solution using Javascript:
HTML
<input class='acb' type='checkbox' name='acheckbox[]' value='1' onclick='deRequire("acb")' required> One
<input class='acb' type='checkbox' name='acheckbox[]' value='2' onclick='deRequire("acb")' required> Two
JAVASCRIPT
function deRequireCb(elClass) {
el = document.getElementsByClassName(elClass);
var atLeastOneChecked = false; //at least one cb is checked
for (i = 0; i < el.length; i++) {
if (el[i].checked === true) {
atLeastOneChecked = true;
}
}
if (atLeastOneChecked === true) {
for (i = 0; i < el.length; i++) {
el[i].required = false;
}
} else {
for (i = 0; i < el.length; i++) {
el[i].required = true;
}
}
}
The javascript will ensure at least one checkbox is checked, then de-require the entire checkbox group. If the one checkbox that is checked becomes un-checked, then it will require all checkboxes, again!
I guess there's no standard HTML5 way to do this, but if you don't mind using a jQuery library, I've been able to achieve a "checkbox group" validation using webshims' "group-required" validation feature:
The docs for group-required say:
If a checkbox has the class 'group-required' at least one of the
checkboxes with the same name inside the form/document has to be
checked.
And here's an example of how you would use it:
<input name="checkbox-group" type="checkbox" class="group-required" id="checkbox-group-id" />
<input name="checkbox-group" type="checkbox" />
<input name="checkbox-group" type="checkbox" />
<input name="checkbox-group" type="checkbox" />
<input name="checkbox-group" type="checkbox" />
I mostly use webshims to polyfill HTML5 features, but it also has some great optional extensions like this one.
It even allows you to write your own custom validity rules. For example, I needed to create a checkbox group that wasn't based on the input's name, so I wrote my own validity rule for that...
we can do this easily with html5 also, just need to add some jquery code
Demo
HTML
<form>
<div class="form-group options">
<input type="checkbox" name="type[]" value="A" required /> A
<input type="checkbox" name="type[]" value="B" required /> B
<input type="checkbox" name="type[]" value="C" required /> C
<input type="submit">
</div>
</form>
Jquery
$(function(){
var requiredCheckboxes = $('.options :checkbox[required]');
requiredCheckboxes.change(function(){
if(requiredCheckboxes.is(':checked')) {
requiredCheckboxes.removeAttr('required');
} else {
requiredCheckboxes.attr('required', 'required');
}
});
});
Inspired by the answers from #thegauraw and #Brian Woodward, here's a bit I pulled together for JQuery users, including a custom validation error message:
$cbx_group = $("input:checkbox[name^='group']");
$cbx_group.on("click", function () {
if ($cbx_group.is(":checked")) {
// checkboxes become unrequired as long as one is checked
$cbx_group.prop("required", false).each(function () {
this.setCustomValidity("");
});
} else {
// require checkboxes and set custom validation error message
$cbx_group.prop("required", true).each(function () {
this.setCustomValidity("Please select at least one checkbox.");
});
}
});
Note that my form has some checkboxes checked by default.
Maybe some of you JavaScript/JQuery wizards could tighten that up even more?
I added an invisible radio to a group of checkboxes.
When at least one option is checked, the radio is also set to check.
When all options are canceled, the radio is also set to cancel.
Therefore, the form uses the radio prompt "Please check at least one option"
You can't use display: none because radio can't be focused.
I make the radio size equal to the entire checkboxes size, so it's more obvious when prompted.
HTML
<form>
<div class="checkboxs-wrapper">
<input id="radio-for-checkboxes" type="radio" name="radio-for-required-checkboxes" required/>
<input type="checkbox" name="option[]" value="option1"/>
<input type="checkbox" name="option[]" value="option2"/>
<input type="checkbox" name="option[]" value="option3"/>
</div>
<input type="submit" value="submit"/>
</form>
Javascript
var inputs = document.querySelectorAll('[name="option[]"]')
var radioForCheckboxes = document.getElementById('radio-for-checkboxes')
function checkCheckboxes () {
var isAtLeastOneServiceSelected = false;
for(var i = inputs.length-1; i >= 0; --i) {
if (inputs[i].checked) isAtLeastOneCheckboxSelected = true;
}
radioForCheckboxes.checked = isAtLeastOneCheckboxSelected
}
for(var i = inputs.length-1; i >= 0; --i) {
inputs[i].addEventListener('change', checkCheckboxes)
}
CSS
.checkboxs-wrapper {
position: relative;
}
.checkboxs-wrapper input[name="radio-for-required-checkboxes"] {
position: absolute;
margin: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
-webkit-appearance: none;
pointer-events: none;
border: none;
background: none;
}
https://jsfiddle.net/codus/q6ngpjyc/9/
I had the same problem and I my solution was this:
HTML:
<form id="processForm.php" action="post">
<div class="input check_boxes required wish_payment_type">
<div class="wish_payment_type">
<span class="checkbox payment-radio">
<label for="wish_payment_type_1">
<input class="check_boxes required" id="wish_payment_type_1" name="wish[payment_type][]" type="checkbox" value="1">Foo
</label>
</span>
<span class="checkbox payment-radio">
<label for="wish_payment_type_2">
<input class="check_boxes required" id="wish_payment_type_2" name="wish[payment_type][]" type="checkbox" value="2">Bar
</label>
</span>
<span class="checkbox payment-radio">
<label for="wish_payment_type_3">
<input class="check_boxes required" id="wish_payment_type_3" name="wish[payment_type][]" type="checkbox" value="3">Buzz
</label>
<input id='submit' type="submit" value="Submit">
</div>
</form>
JS:
var verifyPaymentType = function () {
var checkboxes = $('.wish_payment_type .checkbox');
var inputs = checkboxes.find('input');
var first = inputs.first()[0];
inputs.on('change', function () {
this.setCustomValidity('');
});
first.setCustomValidity(checkboxes.find('input:checked').length === 0 ? 'Choose one' : '');
}
$('#submit').click(verifyPaymentType);
https://jsfiddle.net/oywLo5z4/
You don't need jQuery for this. Here's a vanilla JS proof of concept using an event listener on a parent container (checkbox-group-required) of the checkboxes, the checkbox element's .checked property and Array#some.
const validate = el => {
const checkboxes = el.querySelectorAll('input[type="checkbox"]');
return [...checkboxes].some(e => e.checked);
};
const formEl = document.querySelector("form");
const statusEl = formEl.querySelector(".status-message");
const checkboxGroupEl = formEl.querySelector(".checkbox-group-required");
checkboxGroupEl.addEventListener("click", e => {
statusEl.textContent = validate(checkboxGroupEl) ? "valid" : "invalid";
});
formEl.addEventListener("submit", e => {
e.preventDefault();
if (validate(checkboxGroupEl)) {
statusEl.textContent = "Form submitted!";
// Send data from e.target to your backend
}
else {
statusEl.textContent = "Error: select at least one checkbox";
}
});
<form>
<div class="checkbox-group-required">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
</div>
<input type="submit" />
<div class="status-message"></div>
</form>
If you have multiple groups to validate, add a loop over each group, optionally adding error messages or CSS to indicate which group fails validation:
const validate = el => {
const checkboxes = el.querySelectorAll('input[type="checkbox"]');
return [...checkboxes].some(e => e.checked);
};
const allValid = els => [...els].every(validate);
const formEl = document.querySelector("form");
const statusEl = formEl.querySelector(".status-message");
const checkboxGroupEls = formEl.querySelectorAll(".checkbox-group-required");
checkboxGroupEls.forEach(el =>
el.addEventListener("click", e => {
statusEl.textContent = allValid(checkboxGroupEls) ? "valid" : "invalid";
})
);
formEl.addEventListener("submit", e => {
e.preventDefault();
if (allValid(checkboxGroupEls)) {
statusEl.textContent = "Form submitted!";
}
else {
statusEl.textContent = "Error: select at least one checkbox from each group";
}
});
<form>
<div class="checkbox-group-required">
<label>
Group 1:
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
</label>
</div>
<div class="checkbox-group-required">
<label>
Group 2:
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
</label>
</div>
<input type="submit" />
<div class="status-message"></div>
</form>
I realize there are a ton of solutions here, but I found none of them hit every requirement I had:
No custom coding required
Code works on page load
No custom classes required (checkboxes or their parent)
I needed several checkbox lists to share the same name for submitting Github issues via their API, and was using the name label[] to assign labels across many form fields (two checkbox lists and a few selects and textboxes) - granted I could have achieved this without them sharing the same name, but I decided to try it, and it worked.
The only requirement for this one is jQuery, which could easily be eliminated if you wanted to rewrite it in vanilla JS. You can combine this with #ewall's great solution to add custom validation error messages.
/* required checkboxes */
jQuery(function ($) {
var $requiredCheckboxes = $("input[type='checkbox'][required]");
/* init all checkbox lists */
$requiredCheckboxes.each(function (i, el) {
//this could easily be changed to suit different parent containers
var $checkboxList = $(this).closest("div, span, p, ul, td");
if (!$checkboxList.hasClass("requiredCheckboxList"))
$checkboxList.addClass("requiredCheckboxList");
});
var $requiredCheckboxLists = $(".requiredCheckboxList");
$requiredCheckboxLists.each(function (i, el) {
var $checkboxList = $(this);
$checkboxList.on("change", "input[type='checkbox']", function (e) {
updateCheckboxesRequired($(this).parents(".requiredCheckboxList"));
});
updateCheckboxesRequired($checkboxList);
});
function updateCheckboxesRequired($checkboxList) {
var $chk = $checkboxList.find("input[type='checkbox']").eq(0),
cblName = $chk.attr("name"),
cblNameAttr = "[name='" + cblName + "']",
$checkboxes = $checkboxList.find("input[type='checkbox']" + cblNameAttr);
if ($checkboxList.find(cblNameAttr + ":checked").length > 0) {
$checkboxes.prop("required", false);
} else {
$checkboxes.prop("required", true);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" action="post.php">
<div>
Type of report:
</div>
<div>
<input type="checkbox" id="chkTypeOfReportError" name="label[]" value="Error" required>
<label for="chkTypeOfReportError">Error</label>
<input type="checkbox" id="chkTypeOfReportQuestion" name="label[]" value="Question" required>
<label for="chkTypeOfReportQuestion">Question</label>
<input type="checkbox" id="chkTypeOfReportFeatureRequest" name="label[]" value="Feature Request" required>
<label for="chkTypeOfReportFeatureRequest">Feature Request</label>
</div>
<div>
Priority
</div>
<div>
<input type="checkbox" id="chkTypeOfContributionBlog" name="label[]" value="Priority: High" required>
<label for="chkPriorityHigh">High</label>
<input type="checkbox" id="chkTypeOfContributionBlog" name="label[]" value="Priority: Medium" required>
<label for="chkPriorityMedium">Medium</label>
<input type="checkbox" id="chkTypeOfContributionLow" name="label[]" value="Priority: Low" required>
<label for="chkPriorityMedium">Low</label>
</div>
<div>
<input type="submit" />
</div>
</form>
Really simple way to verify if at least one checkbox is checked:
function isAtLeastOneChecked(name) {
let checkboxes = Array.from(document.getElementsByName(name));
return checkboxes.some(e => e.checked);
}
Then you can implement whatever logic you want to display an error.
Here is another simple trick using Jquery!!
HTML
<form id="hobbieform">
<div>
<input type="checkbox" name="hobbies[]">Coding
<input type="checkbox" name="hobbies[]">Gaming
<input type="checkbox" name="hobbies[]">Driving
</div>
</form>
JQuery
$('#hobbieform').on("submit", function (e) {
var arr = $(this).serialize().toString();
if(arr.indexOf("hobbies") < 0){
e.preventDefault();
alert("You must select at least one hobbie");
}
});
That's all.. this works because if none of the checkbox is selected, nothing as regards the checkbox group(including its name) is posted to the server
Pure JS solution:
const group = document.querySelectorAll('[name="myCheckboxGroup"]');
function requireLeastOneChecked() {
var atLeastOneChecked = false;
for (i = 0; i < group.length; i++)
if (group[i].checked)
atLeastOneChecked = true;
if (atLeastOneChecked)
for (i = 0; i < group.length; i++)
group[i].required = false;
else
for (i = 0; i < group.length; i++)
group[i].required = true;
}
requireLeastOneChecked(); // onload
group.forEach(function ($el) {
$el.addEventListener('click', function () { requireLeastOneChecked(); })
});
Hi just use a text box additional to group of check box.When clicking on any check box put values in to that text box.Make that that text box required and readonly.
A general Solution without change the submit event or knowing the name of the checkboxes
Build a Function, which marks the Checkbox as HTML5-Invalid
Extend Change-Event and check validity on the start
jQuery.fn.getSiblingsCheckboxes = function () {
let $this = $(this);
let $parent = $this.closest('form, .your-checkbox-listwrapper');
return $parent.find('input[type="checkbox"][name="' + $this.attr('name')+'"]').filter('*[required], *[data-required]');
}
jQuery.fn.checkRequiredInputs = function() {
return this.each(function() {
let $this = $(this);
let $parent = $this.closest('form, .your-checkbox-list-wrapper');
let $allInputs = $this.getSiblingsCheckboxes();
if ($allInputs.filter(':checked').length > 0) {
$allInputs.each(function() {
// this.setCustomValidity(''); // not needed
$(this).removeAttr('required');
$(this).closest('li').css('color', 'green'); // for debugging only
});
} else {
$allInputs.each(function() {
// this.reportValidity(); // not needed
$(this).attr('required', 'required');
$(this).closest('li').css('color', 'red'); // for debugging only
});
}
return true;
});
};
$(document).ready(function() {
$('input[type="checkbox"][required="required"], input[type="checkbox"][required]').not('*[data-required]').not('*[disabled]').each(function() {
let $input = $(this);
let $allInputs = $input.getSiblingsCheckboxes();
$input.attr('data-required', 'required');
$input.removeAttr('required');
$input.on('change', function(event) {
$input.checkRequiredInputs();
});
});
$('input[type="checkbox"][data-required="required"]').checkRequiredInputs();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
</head>
<form>
<ul>
<li><input type="checkbox" id="checkbox1" name="countries" value="Argentina" required="required">Argentina</li>
<li><input type="checkbox" id="checkbox2" name="countries" value="France" required="required">France</li>
<li><input type="checkbox" id="checkbox3" name="countries" value="Germany" required="required">Germany</li>
<li><input type="checkbox" id="checkbox4" name="countries" value="Japan" required="required">Japan</li>
<li><input type="checkbox" id="checkbox5" name="countries" value="Australia" required="required">Australia</li>
</ul>
<input type="submit" value="Submit">
</form>
Try:
self.request.get('sports_played', allow_multiple=True)
or
self.request.POST.getall('sports_played')
More specifically:
When you are reading data from the checkbox array, make sure array has:
len>0
In this case:
len(self.request.get('array', allow_multiple=True)) > 0

Check/Uncheck using jQuery not working

I am trying to make the check boxes behave like radio buttons in my ASP .NET MVC Web Application. I have got about 20-30 check boxes grouped in two. For Example:
<input type="checkbox" id="#riggingType.RiggingTypeId 1" name="RiggingTypePlus"
value="#riggingType.RiggingTypeId"
checked="#riggingTypeIds.Contains(riggingType.RiggingTypeId)" />
<input type="checkbox" id="#riggingType.RiggingTypeId 2" name="RiggingTypeMinus"
value="#riggingType.RiggingTypeId"
checked="#riggingTypeIds.Contains(riggingType.RiggingTypeId)" />
Goal:
I want to make the check boxes to behave in such a way that if a Plus Check box is checked then the Minus is unchecked automatically and vice versa. I have written following code to try and achieve this functionality:
$(":checkbox").change(function () {
var inputs = $(this).parents("form").eq(0).find(":checkbox");
var idx = inputs.index(this);
if (this.name.substring(this.name.length - 4, this.name.length) === "Plus") {
// just trying to check if I am getting the right it
// and I am getting the right id
// alert(inputs[idx + 1].id);
// But this does not work
$("#" + inputs[idx + 1].id).prop('checked', false);
}
});
Am I doing something wrong here:
$("#" + inputs[idx + 1].id).prop('checked', false);
Any help will be appreciated.
I know that I can use the radio buttons and group them by same name but I am rendering the elements in a loop so they all have the same name but different values and I don't want to name them differently because I am using this data on the server side... Is there a better way to do this?
Answer:
Got this working using the following:
$(document).ready(function(){
$(":checkbox").on('click', function () {
var $this = $(this);
var inputs = $this.closest("form").find(":checkbox");
if ($this.attr('name').substring(this.name.length - 4, this.name.length) === "Plus" && $this.attr('checked')) {
$this.next().prop('checked', false);
}
else
{
$this.prev().prop('checked', false);
}
});
});
Fiddle Link
fiddle: https://jsfiddle.net/24gmnjwm/1/
$(document).ready(function(){
$(":checkbox").on('click', function () {
var $this = $(this);
var inputs = $this.closest("form").find(":checkbox");
if ($this.attr('name').substring(this.name.length - 4, this.name.length) === "Plus") {
$this.next().prop('checked', false);
}
});
});
If we can assume that the "plus" checkbox always appears immediately before its related "minus" checkbox then this will do the trick:
$(":checkbox").change(function () {
if ($(this).prop("name").match(/Plus$/)) {
$(this).next().prop("checked", !$(this).prop("checked"));
} else {
$(this).prev().prop("checked", !$(this).prop("checked"));
}
});
sample form:
<form>
<input type="checkbox" name="RiggingTypePlus" value="2" checked />
<input type="checkbox" name="RiggingTypeMinus" value="2" />
<input type="checkbox" name="RiggingTypePlus" value="3" />
<input type="checkbox" name="RiggingTypeMinus" value="3" />
<input type="checkbox" name="RiggingTypePlus" value="4" />
<input type="checkbox" name="RiggingTypeMinus" value="4" />
<input type="checkbox" name="RiggingTypePlus" value="5" />
<input type="checkbox" name="RiggingTypeMinus" value="5" />
</form>
fiddle

Javascript - If no radio buttons are selected, check the first one

I'm a beginner in JavaScript. I have several radio buttons on my dynamic page and I want to create a script to make the following:
HTML:
<input type="radio" id="elemainfoto">
<input type="radio" id="elemainfoto">
<input type="radio" id="elemainfoto">
JavaScript:
var radio = '#elemainfoto',
if(radd.value == 0) {
radd.checked the first radio element,
} else {
keep the way it is,
}
If none of the radio elements are marked, mark the first compulsory.
I your expectation is that the first item get selected by default, then you should use HTML and not javascript for that and please note that you should not use two HTML elements with the same id in your case you should either replace by a class and/or add unique Ids for elements.
<input type="radio" class="elemainfoto" id="item1" checked>
<input type="radio" class="elemainfoto" id="item2">
<input type="radio" class="elemainfoto" id="item3>
Updated the answer based on RobG comment.
Something like this in pure JS (I changed ids to classes id should be unique):
var radio = document.querySelectorAll('.elemainfoto'),
checked = false;
for (var i = 0; i < radio.length; i++) {
if (radio[i].checked) {
checked = true;
break;
}
}
if (!checked) {
radio[0].checked = true;
}
else {
alert('something is checked')
}
A little shorter with jQuery:
var $radio = $('.elemainfoto');
if (!$radio.filter(':checked').length) {
$radio[0].checked = true;
}
else {
alert('something is checked')
}
using 'id' attribute in html with the same value more than once is invalid, you should use "name" for an input.
HTML:
<input type="radio" name="elementinfoto" value="1" />
<input type="radio" name="elementinfoto" value="2" />
<input type="radio" name="elementinfoto" value="3" />
JavaScript:
var radio = document.getElementsByName('elementinfoto'); // get all radio buttons
var isChecked = 0; // default is 0
for(var i=0; i<radio.length;i++) { // go over all the radio buttons with name 'elementinfoto'
if(radio[i].checked) isChecked = 1; // if one of them is checked - tell me
}
if(isChecked == 0) // if the default value stayed the same, check the first radio button
radio[0].checked = "checked";
example: http://jsfiddle.net/yxm4N/2/
A radio button group is formed by giving radio buttons the same name. An ID is optional and usually not necessary. If an ID is provided, each should have a different value. And the buttons should have a value so that there's a point to their existence.
To have one button selected by default, simply set the chosen button's checked attribute:
<form id="foo">
<input type="radio" name="elemainfoto" valu="0" checked>0<br>
<input type="radio" name="elemainfoto" valu="1">1<br>
<input type="radio" name="elemainfoto" valu="2">2<br>
<input type="reset">
</form>
Now if no other button is selected, or the form is reset, one button will be selected. Note that if you do not set a button as the default selected, then once a user checks a button, the only way to deselect it is to select a different radio button in the same group, or use a reset button (if provided).
If you want to set the default checked button in script, there are a couple of options. One is:
var buttons = document.getElementsByName('elemainfoto');
buttons[0].defaultChecked = true;
If you really want to check if one is selected, add a button like the following to the form:
<input type="button" value="Check buttons" onclick="checkButtons(this);">
Then the checkButtons function can be:
function checkButtons(el) {
var buttons;
var form = el && el.form;
if (form) {
buttons = form.elemainfoto;
for (var i=0, iLen=buttons.length; i<iLen; i++) {
// If a button is checked, return its value
if (buttons[i].checked) {
return buttons[i].value;
}
}
}
// Otherwise, try to check the first one and return undefined
buttons && buttons[0].checked;
}
you need to know how to use radio element. Id is unique in html page. you should assign same name for each radio element.
<input type="radio" name="elemainfoto" id="first" value="1" />
element 1
<input type="radio" name="elemainfoto" id="second" value="2" />
element 2
<input type="radio" name="elemainfotor" id="thrid" value="3" />
element 3
if you want to check the first radio button as default, set it in input tag attribute.
<input type="radio" name="elemainfoto" id="first" value="1" checked="true"/>
element 1
or you can do it with javascript also,
$("input:radio[name=elemainfoto]:first").attr('checked', true);
you can perform action for each radio button click, to know which item is checked
$(function(){
$('input[type="radio"]').click(function(){
if ($(this).is(':checked'))
{
alert($(this).val());
}
});
});
if you want to perform a separate action for each radio button, try this below code
$(function () {
$('input[type="radio"]').click(function () {
if ($(this).is(':checked')) {
if ($(this).val() == '1') alert('first radio element is checked');
if ($(this).val() == '2') alert('second radio element is checked');
if ($(this).val() == '3') alert('third radio element is checked');
}
});
});
SEE THIS FIDDLE DEMO
Instead of selecting the first one, I prefered to use null
const radio = document.querySelectorAll('.timescale');
let timescale;
if (radio.checked) {
timescale = $('input[name=timescale_radio_buttons]:checked').val()
} else timescale = null;
You can write it like this with less code
HTML
<input type="radio" name="elementinfoto" value="1" />
<input type="radio" name="elementinfoto" value="2" />
<input type="radio" name="elementinfoto" value="3" />
JavaScript
const fields = document.getElementsByName('elementinfoto');
const value = fields.filter(el => el.checked).shift()?.value || null;
if(!value) {
fields.shift().checked = true;
}
You can replace the function shift() by [0] to get the first element if you prefer

Categories

Resources