3 state checkbox required=true but checked and unchecked are valid. Intermediate should be invalid

Viewed 872

I have this 3 state checkbox:

<div>
    <input required type="checkbox" id="effectiveness" name="effectiveness">
</div> 

and at the beginning the value is set to intermediate with jQuery like this:

$("#effectiveness").prop("indeterminate", true);

The required attribute checks if the attribute checked is true. But I want checked="true" and checked="false" to be valid. The only invalid state should be indeterminate.

How can I achieve this?

3 Answers

About indeterminate, here's a brief note from CSS Tricks:

The indeterminate state is visual only. The checkbox is still either checked or unchecked as a state. That means the visual indeterminate state masks the real value of the checkbox, so that better make sense in your UI! Like the checkboxes themselves, indeterminate state looks different in different browsers.

I don't think there's any browser supported validation for indeterminate. Since you're adding it yourself through jQuery, why not validate it as well?

Remove required attribute from your HTML and replace the code when effectiveness is 2 with:

$("#effectiveness").prop("indeterminate", true).prop("checked", false).attr("required", "true").on('change', function() {
    $(this).removeAttr('required');
});

Above code will effectively cause the browser to consider it invalid.

Full code here:

<tr tal:define="effectiveness view/get_effectiveness">
    <td tal:condition="python: training['released']">
       <div>
          <input type="checkbox" id="effectiveness" name="effectiveness" ng-checked="effectiveness/effectiveness == 1" disabled="disabled" >
          <label for="effectiveness">Wirksamkeit</label>
        </div>
        <script tal:condition="python: effectiveness['effectiveness'] == 2">
            $("#effectiveness").prop("indeterminate", true);
        </script>
    </td>
    <td tal:condition="python: not training['released']">
        <div>
          <input required type="checkbox" id="effectiveness" name="effectiveness" ng-checked="effectiveness/effectiveness == 1" >
          <label for="effectiveness">Wirksamkeit</label>
        </div>
        <script tal:condition="python: effectiveness['effectiveness'] == 2">
            $("#effectiveness").prop("indeterminate", true);
        </script>
        <script tal:condition="python: effectiveness['effectiveness'] == 1">
            $("#effectiveness").prop("checked", true);
        </script>
        <script tal:condition="python: effectiveness['effectiveness'] == 0">
            $("#effectiveness").prop("checked", false);
        </script>
    </td>
</tr>

I still have the issue to make the unchecked state (not the indeterminate one) valid. I tried:

<script tal:condition="python: effectiveness['effectiveness'] == 0">
      $("#effectiveness").removeProp('required').prop("checked", false);
</script>

but this workes only if the value of the checkbox was already unchecked respectively effectiveness['effectiveness'] == 0, befor opening the page. When the state was checked (1) or indeterminate (2) and i'm switching the states by clicking in the checkbox, the unchecked state is invalid.

Related