232

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.

Facundo Colombier
  • 3,487
  • 1
  • 34
  • 40
Zabba
  • 64,285
  • 47
  • 179
  • 207
  • 5
    This is a great question, and applies to any form input that is an array (including text inputs) where you want to have at least one item with a value or checked (but not any specific one). [Demo](http://jsfiddle.net/wesley_murch/d7B2L/) I think there may not be a way to do this, but I hope there is. (BTW it doesn't matter what language or framework or library, it's strictly HTML5) – Wesley Murch Jun 02 '11 at 20:10
  • Thanks for adding that JSFiddle demo. Hopefully there is some HTML5-way to do this, otherwise will probably have to roll up some solution using JQuery and a hidden field or something. – Zabba Jun 02 '11 at 20:53
  • If you want to fall back to javascript (and you're using jQuery), no need to "roll up" anything, use the highly established validation plugin: http://bassistance.de/jquery-plugins/jquery-plugin-validation/ – Wesley Murch Jun 02 '11 at 20:58
  • I don't think that the required attribute is being used correctly here. A required attribute would be something like 'Read the terms of service'. What is described here is either the function of a radio button set or a multiple selection box. – natedavisolds Jun 03 '11 at 01:58
  • 6
    @natedavisolds, I would argue that the usage is useful in some UIs - IMO, selecting multiple checkboxes is more intuitive to the end-user, especially when the number of checkboxes is small - rather than a click+select as is the case with a multiple selection box. – Zabba Jun 03 '11 at 02:03
  • @zabba, I completely agree and use checkboxes in this way. However, it is departing from the intended purpose of the tag and so we must manipulate it using an outside source. Your question is about HTML solutions and there is one, just not the way we both want it to work. – natedavisolds Jun 03 '11 at 02:13
  • @natedavisolds, you're right. I will look at the plugin @Wesley Murch mentioned. Question remains open! :) – Zabba Jun 03 '11 at 02:18
  • @Zabba thanks for sharing that document you found. Strange that they only considered checkboxes in particular, and not simply fields grouped by brackets. I hope one day that HTML validation will be more flexible to accommodate to a variety of use cases, and hope you're enjoying the validation plugin. – Wesley Murch Jun 13 '11 at 22:38
  • 1
    As a side note, you don't need that whole required='required' bit; simply putting 'required' is sufficient. – William Jun 21 '11 at 17:53

17 Answers17

121

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.

Luca Fagioli
  • 12,722
  • 5
  • 59
  • 57
  • @Clijsters the question is about a HTML5 way to do it - not with Javascript (of course, various solutions are possible in Javascript) – Zabba Apr 10 '18 at 00:18
  • 11
    @Zabba But this answer says. how to do it in html5 by writing _Unfortunately HTML5 does not provide an out-of-the-box way to do that_ – Clijsters Apr 11 '18 at 07:54
  • 1
    Fair enough @Clijsters – Zabba Jun 18 '18 at 22:24
  • Here's the best implementation with `setCustomValidity` https://stackoverflow.com/a/30222924/ – Alex78191 Nov 17 '21 at 14:03
25

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!

BeRT2me
  • 12,699
  • 2
  • 13
  • 31
Brian Woodward
  • 363
  • 3
  • 7
  • I like this solution because it can more easily be used to validate separate groups of checkboxes on the same form. – chillywilly Nov 11 '21 at 00:41
  • How is this clean, exactly? It pollutes the window with variables like `i` and `el`, doesn't use proper spacing around operators, uses outdated idioms and has distracting verbosity like `=== true` in conditions. – ggorlen Apr 29 '22 at 05:44
  • Your function name has typo. Please correct. In HTML it's deRequire and in Javascript it's deRequireCb. – Sushank Dahiwadkar Nov 23 '22 at 09:08
  • I like this method but made a few changes. Since all checkboxes in the group has the same name I'm using name instead of adding a class. I also rewrote deRequire as follows: ~~~ function deRequire(name){ let elements = document.getElementsByName(name); var someChecked = false; elements.forEach(element => someChecked = someChecked || element.checked); elements.forEach(element => element.required = !someChecked); } ~~~ – skymatt70 Jul 07 '23 at 21:37
24

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
});
thegauraw
  • 5,428
  • 2
  • 21
  • 14
  • While it is possible to do via Javascript, I was looking for a solution without using Javascript. – Zabba Jun 15 '16 at 15:48
  • 3
    I think this is the best answer so far. Yes, it uses javascript, but it uses HTML5's validation instead of having a JavaScript alert pop up. Other answers uses JS and a JS pop up window. – Cruz Nunez Jun 27 '16 at 21:55
  • 1
    This is really good. Make sure to choose one or the other on those first two jQuery lines (the second cancels out the first). Also make sure you change "option" to the name of the option. – Allen Gingrich Nov 29 '17 at 22:57
  • Given this is not supported natively in HTML5, this really should be the accepted answer! I don't want to implement my own validation library just for one set of checkbox fields on a single form on my site. – JamesWilson Apr 03 '19 at 13:46
12

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...

Ura
  • 2,173
  • 3
  • 24
  • 41
Tyler Rick
  • 9,191
  • 6
  • 60
  • 60
6

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?

BeRT2me
  • 12,699
  • 2
  • 13
  • 31
ewall
  • 27,179
  • 15
  • 70
  • 84
6

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');
        }
    });
});
XNicON
  • 153
  • 1
  • 6
Juned Ansari
  • 5,035
  • 7
  • 56
  • 89
5

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/

Codus
  • 1,433
  • 1
  • 14
  • 18
  • This is a great solution. Works like a charm. However, in Firefox, I get a big red outline around the radio button box when it is set to required on all form controls using this radio button. Is there a way to style the outline to not be red when invalid (radio button not checked when required) except when the user hits submit and validation is carried out? – gib65 Sep 10 '19 at 22:02
  • We can set `radio`'s `opacity` to 0, and set `opacity` to 1 when submitted, so that we can control whether red outline appears or not. – Codus Sep 13 '19 at 13:59
  • This solution is genius!! In my case it didn't work if i use either `visibility: hidden` or `display: none` just to avoid getting the usability a little dirty. Because screen readers and other accessibility tools will probably find the hidden radio button. – hoorider Mar 09 '20 at 14:52
  • Why not just use JavaScript, which is intended for that, rather than *hidden* HTML elements, which aren't? – reformed Apr 06 '21 at 14:20
  • Yeah, `input type="radio"` doesn't seem to work so great unfortunately (even in Firefox 98.0.1), but changing it to `input type="text"` works quite nicely. Of course, you end up getting the message "Please fill out this field" instead of "Please select one of these options" when one of the boxes aren't checked (assuming you don't also implement custom validation messages). But at least in my case, the former message still makes a lot of sense for a checkbox group since the checkboxes are contained in a field with a border like you might see on a physical (paper) form. – user966939 Dec 04 '22 at 02:18
3

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/

Zoe
  • 27,060
  • 21
  • 118
  • 148
Passalini
  • 101
  • 6
  • `inputs.on('change', function () { this.setCustomValidity(''); });` is useless https://jsfiddle.net/d8r2146j/ – Alex78191 Nov 17 '21 at 14:01
  • 1
    `$('#submit').click(verifyPaymentType);` this si plain wrong and something a lot of juniors do, this for me disqualified the entire answer. Please always listen to the form's submit event. – Edgar Griñant Mar 11 '22 at 12:22
2

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>
Sean Kendle
  • 3,538
  • 1
  • 27
  • 34
2

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>
ggorlen
  • 44,755
  • 7
  • 76
  • 106
  • How to continue submit if `allValid(checkboxGroupEls)` is true? I have one _action_: `action="includes/action.php"` in _form_ – Marlon Pereira Sep 03 '21 at 18:45
  • 2
    Make an AJAX request or only conditionally call `e.preventDefault()` on the form if validation fails. – ggorlen Sep 03 '21 at 19:39
1

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

BeRT2me
  • 12,699
  • 2
  • 13
  • 31
oluwatayo_
  • 31
  • 1
  • 2
1

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.

myeongkil kim
  • 2,465
  • 4
  • 16
  • 22
javajaba
  • 75
  • 2
  • 11
1

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(); })
});
Dmitry Shashurov
  • 1,148
  • 13
  • 11
0

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.

Abijith
  • 9
  • 1
0

A general Solution without change the submit event or knowing the name of the checkboxes

  1. Build a Function, which marks the Checkbox as HTML5-Invalid
  2. 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>
0

JavaScript Synchronous way. Extended version of Luca.

let checkboxGroups = $('.my-checkbox-group.checkbox-required');

// Loop through each checkbox group
let numGroups = checkboxGroups.length;

for (var i = 0; i < numGroups; i++) {
    var isChecked = $(checkboxGroups[i]).find(':checkbox:checked').length > 0;

    if (!isChecked) {
        var firstCheckbox = $(checkboxGroups[i]).find(':checkbox:first');
        if (firstCheckbox.length > 0) {
            firstCheckbox.focus();
            return false; // Exit the loop after focusing on the first empty group
        }
    }
}


<div class="my-checkbox-group checkbox-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>
Arun Prasad E S
  • 9,489
  • 8
  • 74
  • 87
-3

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
Gjison Giocf
  • 145
  • 1
  • 11
  • Could you maybe elaborate on your answer a bit more? – Twenty Feb 08 '20 at 22:48
  • 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 – Gjison Giocf Feb 08 '20 at 23:32
  • Please edit your question with the information in your comment above and I'll be happy to remove the downvote. – Twenty Feb 08 '20 at 23:44
  • Thanks for editing your post, but a bit more courtesy would be appropriate. – Twenty Feb 11 '20 at 12:18
  • 4
    seems totally unrelated to the question. Is asking about html validation, and the solution here is python. The question is not even asking about server side validation, is asking is there is a way to validate checkbox groups to check if at least 1 is checked. – Octavioamu May 01 '20 at 00:32