Do checkbox inputs only post data if they're checked?
Yes, standard behaviour is the value is only sent if the checkbox is checked. This typically means you need to have a way of remembering what checkboxes you are expecting on the server side since not all the data comes back from the form.
The default value is always "on", this should be consistent across browsers.
This is covered in the W3C HTML 4 recommendation:
Checkboxes (and radio buttons) are on/off switches that may be toggled by the user. A switch is "on" when the control element's checked attribute is set. When a form is submitted, only "on" checkbox controls can become successful.
In HTML, each <input />
element is associated with a single (but not unique) name and value pair. This pair is sent in the subsequent request (in this case, a POST request body) only if the <input />
is "successful".
So if you have these inputs in your <form>
DOM:
<input type="text" name="one" value="foo" />
<input type="text" name="two" value="bar" disabled="disabled" />
<input type="text" name="three" value="first" />
<input type="text" name="three" value="second" />
<input type="checkbox" name="four" value="baz" />
<input type="checkbox" name="five" value="baz" checked="checked" />
<input type="checkbox" name="six" value="qux" checked="checked" disabled="disabled" />
<input type="checkbox" name="" value="seven" checked="checked" />
<input type="radio" name="eight" value="corge" />
<input type="radio" name="eight" value="grault" checked="checked" />
<input type="radio" name="eight" value="garply" />
Will generate these name+value pairs which will be submitted to the server:
one=foo
three=first
three=second
five=baz
eight=grault
Notice that:
-
two
andsix
were excluded because they had thedisabled
attribute set. -
three
was sent twice because it had two valid inputs with the same name. -
four
was not sent because it is acheckbox
that was notchecked
-
six
was not sent despite beingchecked
because thedisabled
attribute has a higher precedence. -
seven
does not have aname=""
attribute sent, so it is not submitted.
With respect to your question: you can see that a checkbox that is not checked will therefore not have its name+value pair sent to the server - but other inputs that share the same name will be sent with it.
Frameworks like ASP.NET MVC work around this by (surreptitiously) pairing every checkbox
input with a hidden
input in the rendered HTML, like so:
@Html.CheckBoxFor( m => m.SomeBooleanProperty )
Renders:
<input type="checkbox" name="SomeBooleanProperty" value="true" />
<input type="hidden" name="SomeBooleanProperty" value="false" />
If the user does not check the checkbox, then the following will be sent to the server:
SomeBooleanProperty=false
If the user does check the checkbox, then both will be sent:
SomeBooleanProperty=true
SomeBooleanProperty=false
But the server will ignore the =false
version because it sees the =true
version, and so if it does not see =true
it can determine that the checkbox was rendered and that the user did not check it - as opposed to the SomeBooleanProperty
inputs not being rendered at all.
If checkbox isn't checked then it doesn't contribute to the data sent on form submission.
HTML5 section 4.10.22.4 Constructing the form data set describes the way form data is constructed:
If any of the following conditions are met, then skip these substeps for this element: [...]
The field element is an input element whose type attribute is in the Checkbox state and whose checkedness is false.
and then the default valued on
is specified if value
is missing:
Otherwise, if the field element is an input element whose type attribute is in the Checkbox state or the Radio Button state, then run these further nested substeps:
If the field element has a value attribute specified, then let value be the value of that attribute; otherwise, let value be the string "on".
Thus unchecked checkboxes are skipped during form data construction.
Similar behavior is required under HTML4. It's reasonable to expect this behavior from all compliant browsers.