开发者

Force a checkbox to always submit, even when unchecked

I have an html form and i would like ALWAYS to have 开发者_StackOverflow社区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() {
    // ...
});


if you have many checkbox, you can try this code:

<input type="checkbox" onclick="$(this).next().val(this.checked?1:0)"/> <input type="hidden" name="checkbox1[]"/>


If you have the following HTML:

<form id="myform" method="post" action="my/url">
    <input type="checkbox" id="checkbox1" name="checkbox1"/>
    <input type="checkbox" id="checkbox2" name="checkbox2"/>
    <input type="checkbox" id="checkbox3" name="checkbox3"/>
</form>

Normal form submit:

On form submit, before submitting, change all values of checkboxes to 0 and 1 based on if checkbox is unchecked or checked. Like so:

$('#myform').submit(function() {
    var $checkboxes = $('#myform').find('input[type="checkbox"]');// Select all checkboxes
    $checkboxes.filter(':checked').val(1);// Set value to 1 for checked checkboxes
    $checkboxes.not(':checked').val(0);// Set value to 0 for unchecked checkboxes
    $checkboxes.prop('checked', true);// Change all checkboxes to "checked" so all of them are submitted to server
});

Note: Ugly thing about this code, while form is submitting, all checkboxes will appear as "checked" for a moment. But if you apply same concept for ajax form submit, it would be better.

AJAX form submit:

$.post('my/url', {
    'checkbox1': $('#checkbox1').is(':checked') ? 1 : 0,
    'checkbox2': $('#checkbox2').is(':checked') ? 1 : 0,
    'checkbox3': $('#checkbox3').is(':checked') ? 1 : 0
}, function(response) {
    // Server JSON response..
}, 'json');
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜