Force a checkbox to always submit, even when unchecked

I have an html form and i would like ALWAYS to have checkboxes to submit a value. How can i do that? I have one idea but i havent tried it and i am unsure if its the best way to do it (jquery to check if the box is checked or not, then set the value to 0/1 and check it off so it will submit)


Thanks to @Lazarus' idea, also mentioned by @BalusC, you can add an additional control to the form:

<input type="hidden" name="checkbox1" value="off">
<input type="checkbox" name="checkbox1" value="on"> My checkbox

Checkbox and the hidden fields must have the same name. The hidden input is always submitted as a default value. If the checkbox is checked then also it's submitted. So you have a list of 2 values for parameter "checkbox1", that you have to treat at server side.

...maybe a <select> tag would be more handy.


There is a legitimate reason for asking for something like this, although the behaviour envisioned here is not the right way to go about it. There is a problem with the checkbox when used correctly when editing existing data and that's that there is no way to determine whether no value was submitted because the field was not present on the form or because the user cleared all of the values. You can run into this sort of problem any time you include fields conditionally.

One could go to the trouble of maintaining a "view state", of course, but it's much easier to include a hidden "companion field" whenever a checkbox or select with the multiple option (which is also excluded when all selections are cleared) is displayed. The field should have a related but different name (a name from which the actual field name can be extracted). The Lotus Domino server has used fields named %%Surrogate_FieldNameHere for this purpose since (I believe) version 7 for exactly the reason I described here.


To tell you the truth, this feels like a big no-no.

Anyway here goes:

<script type="text/javascript">
$(document).ready(function () {
    $('form').submit(function() {
        $(this).find('input[type=checkbox]').each(function () {
            $(this).attr('value', $(this).is(':checked') ? '1' : '0');
            $(this).attr('checked', true);
        });
    });
});
</script>

HTML doesn't work that way. HTML checkboxes are specified as follows: if checked, then its name=value will be sent as request parameter. If unchecked, then its name=value will not be sent as request parameter. Note that when the value is unspecified, then most browsers default to "on". It's easier if you give all checkboxes the same name but a different and fixed value. This way you can obtain the checked ones as an array/collection.

If all checkboxes are already known beforehand in server side, you can just apply basic math to obtain the unchecked checkboxes:

uncheckedCheckboxes = allCheckboxes - checkedCheckboxes

If those checkboxes are created dynamically at the client side and therefore unknown beforehand in server side, then add for each checkbox a <input type="hidden"> field containing information about the dynamically created checkbox, so that the server side knows which checkboxes are all present as the moment of submission.


Although this goes against the HTML spec, if you know what you are doing, using this you no longer have to cater checkboxes which are handled completely differently when submitted - and for example naming fields with_brackets[] can actually be useable.

Complete solution

$(document).on('submit', 'form', function() {
    $(this).find('input[type=checkbox]').each(function() {
        var checkbox = $(this);

        // add a hidden field with the same name before the checkbox with value = 0
        if ( !checkbox.prop('checked') ) {
            checkbox.clone()
                .prop('type', 'hidden')
                .val(0)
                .insertBefore(checkbox);
        }
    });
});

Take note: the non-checked checkboxes now submit a value of "0"


Additionally, if you want to change the behaviour of a single form only, just alter the first line in the above snippet:

$(document).on('submit', 'form.your-class-name', function() {
    // ...
});