145

I have a checkbox that, given certain conditions, needs to be disabled. Turns out HTTP doesn't post disabled inputs.

How can I get around that? submitting the input even if it's disabled and keeping the input disabled?

TylerH
  • 20,799
  • 66
  • 75
  • 101
AnApprentice
  • 108,152
  • 195
  • 629
  • 1,012
  • I think this solution also helps here: https://stackoverflow.com/questions/12769664/how-to-make-html-select-element-look-like-disabled-but-pass-values – Sergej Fomin Oct 05 '17 at 12:49
  • I think this solution also helps here: https://stackoverflow.com/questions/12769664/how-to-make-html-select-element-look-like-disabled-but-pass-values – Sergej Fomin Oct 05 '17 at 12:49

18 Answers18

114

UPDATE: READONLY doesn't work on checkboxes

You could use disabled="disabled" but at this point checkbox's value will not appear into POST values. One of the strategy is to add an hidden field holding checkbox's value within the same form and read value back from that field

Simply change disabled to readonly

Francesco Laurita
  • 23,434
  • 8
  • 55
  • 63
  • 8
    To make it valid HTML, specifically set the value of readonly to readonly, i.e.: `` – Matt Huggins Jan 18 '11 at 19:20
  • 5
    To get the "readonly" input field to LOOK like the "disabled" field, set 'style="color: grey; background-color: #F0F0F0;"'. – Dan Nissenbaum Feb 28 '11 at 05:05
  • 3
    @MattHuggins Setting value for only-attribute-name attributes like checked, readonly etc... and end slash on non-pair attributes has nothing to do with HTML validity - these are needed for XHTML validity... – jave.web Sep 06 '13 at 12:32
  • Btw: Perhaps stumbles someone about this: DON'T USE IT for input type= button, they will not be "disabled", use "disabled='disabled'" – Meister Schnitzel Nov 25 '14 at 10:29
  • 2
    `readonly` won't work since you won't be able to post the value of a checkbox with such tag, use `disabled` along with hidden input element to hold checkbox's value, see how: http://stackoverflow.com/a/8274787/448816 – mikhail-t Apr 16 '15 at 19:38
105

I've solved that problem.

Since readonly="readonly" tag is not working (I've tried different browsers), you have to use disabled="disabled" instead. But your checkbox's value will not post then...

Here is my solution:

To get "readonly" look and POST checkbox's value in the same time, just add a hidden "input" with the same name and value as your checkbox. You have to keep it next to your checkbox or between the same <form></form> tags:

<input type="checkbox" checked="checked" disabled="disabled" name="Tests" value="4">SOME TEXT</input>

<input type="hidden" id="Tests" name="Tests" value="4" />

Also, just to let ya'll know readonly="readonly", readonly="true", readonly="", or just READONLY will NOT solve this! I've spent few hours to figure it out!

This reference is also NOT relevant (may be not yet, or not anymore, I have no idea): http://www.w3schools.com/tags/att_input_readonly.asp

mikhail-t
  • 4,103
  • 7
  • 36
  • 56
  • here must be same ids for hidden and checkbox inputs? – user2167382 Feb 13 '14 at 16:06
  • nope, Id can be whatever, but 'name' and 'value' must be the same. – mikhail-t Feb 13 '14 at 19:24
  • How reliable is this in various browsers? – Tim Mar 10 '14 at 19:36
  • this was tested and worked well in latest Chrome, Firefox, and IE 11, here is an implementation, try it in your browser: http://mvccbl.com/examples?PostedCities.CityIDs=2&PostedCities.CityIDs=3&PostedCities.CityIDs=6&PostedCities.CityIDs=7#fullExample – mikhail-t Apr 29 '15 at 19:40
77

If you're happy using JQuery then remove the disabled attribute when submitting the form:

$("form").submit(function() {
    $("input").removeAttr("disabled");
});
harpo
  • 41,820
  • 13
  • 96
  • 131
  • Will this make the control "enabled" in UI? – anar khalilov Jan 09 '14 at 09:30
  • It removes the disabled attribute so in theory yes. In practice I don't think the user can alter the field via the UI between this happening and the form being submitted... I'd be interested to know for sure. – Tristan Channing Jan 09 '14 at 18:34
  • A bit old, but as sidenote: If you use ` – El Gucs Dec 16 '16 at 05:12
12

create a css class eg:

.disable{
        pointer-events: none;
        opacity: 0.5;
}

apply this class instead of disabled attribute

Austin Rodrigues
  • 451
  • 5
  • 15
10

You could handle it this way... For each checkbox, create a hidden field with the same name attribute. But set the value of that hidden field with some default value that you could test against. For example..

<input type="checkbox" name="myCheckbox" value="agree" />
<input type="hidden" name="myCheckbox" value="false" />

If the checkbox is "checked" when the form is submitted, then the value of that form parameter will be

"agree,false"

If the checkbox is not checked, then the value would be

"false"

You could use any value instead of "false", but you get the idea.

Tobb
  • 11,850
  • 6
  • 52
  • 77
jessegavin
  • 74,067
  • 28
  • 136
  • 164
  • 6
    Don't you just hate it when you write up some complicated solution to a problem and then when you refresh, someone (like Francesco) goes and writes a simple one-liner? ;) – jessegavin Jan 18 '11 at 19:20
  • This is perfect for what I am trying to accomplish, I want the unchecked check-box to to submit a value instead of nothing, thanks :D. – Geoffrey Mar 14 '12 at 08:52
  • 1
    @jessegavin Given that his 'simple one liner' no longer works and he's updated his answer to include your one, no, I can't say that I do. – RyanfaeScotland Nov 27 '17 at 17:29
9

The simplest way to this is:

<input type="checkbox" class="special" onclick="event.preventDefault();" checked />

This will prevent the user from being able to deselect this checkbox and it will still submit its value when the form is submitted. Remove checked if you want the user to not be able to select this checkbox.

Also, you can then use javascript to clear the onclick once a certain condition has been met (if that's what you're after). Here's a down-and-dirty fiddle showing what I mean. It's not perfect, but you get the gist.

http://jsfiddle.net/vwUUc/

thatFunkymunkey
  • 111
  • 1
  • 2
8
<input type="checkbox" checked="checked" onclick="this.checked=true" />

I started from the problem: "how to POST/Submit an Input Checkbox that is disabled?" and in my answer I skipped the comment: "If we want to disable a checkbox we surely need to keep a prefixed value (checked or unchecked) and also we want that the user be aware of it (otherwise we should use a hidden type and not a checkbox)". In my answer I supposed that we want to keep always a checkbox checked and that code works in this way. If we click on that ckeckbox it will be forever checked and its value will be POSTED/Submitted! In the same way if I write onclick="this.checked=false" without checked="checked" (note: default is unchecked) it will be forever unchecked and its value will be not POSTED/Submitted!.

PaoloMarass
  • 81
  • 1
  • 2
  • this will simply duplicate what the checkbox already does, but if it has been disabled by javascript or soemthing it will still be disabled, could you explain a bit more what you were going for, maybe I mis understand since its just a line of code – ScottC Oct 10 '12 at 12:09
4

This works like a charm:

  1. Remove the "disabled" attributes
  2. Submit the form
  3. Add the attributes again. The best way to do this is to use a setTimeOut function, e.g. with a 1 millisecond delay.

The only disadvantage is the short flashing up of the disabled input fields when submitting. At least in my scenario that isn´t much of a problem!

$('form').bind('submit', function () {
  var $inputs = $(this).find(':input'),
      disabledInputs = [],
      $curInput;

  // remove attributes
  for (var i = 0; i < $inputs.length; i++) {
    $curInput = $($inputs[i]);

    if ($curInput.attr('disabled') !== undefined) {
      $curInput.removeAttr('disabled');
      disabledInputs.push(true);
    } else 
      disabledInputs.push(false);
  }

  // add attributes
  setTimeout(function() {
    for (var i = 0; i < $inputs.length; i++) {

      if (disabledInputs[i] === true)
        $($inputs[i]).attr('disabled', true);

    }
  }, 1);

});
MattAllegro
  • 6,455
  • 5
  • 45
  • 52
Andy R
  • 1,339
  • 10
  • 20
3

Don't disable it; instead set it to readonly, though this has no effect as per not allowing the user to change the state. But you can use jQuery to enforce this (prevent the user from changing the state of the checkbox:

$('input[type="checkbox"][readonly="readonly"]').click(function(e){
    e.preventDefault();
});

This assumes that all the checkboxes you don't want to be modified have the "readonly" attribute. eg.

<input type="checkbox" readonly="readonly">
Peter
  • 6,509
  • 4
  • 30
  • 34
3

Since:

  • setting readonly attribute to checkbox isn't valid according to HTML specification,
  • using hidden element to submit value isn't very pretty way and
  • setting onclick JavaScript that prevents from changing value isn't very nice too

I'm gonna offer you another possibility:

Set your checkbox as disabled as normal. And before the form is submitted by user enable this checkbox by JavaScript.

<script>
    function beforeSumbit() {
        var checkbox = document.getElementById('disabledCheckbox');
        checkbox.disabled = false;
    }
</script>
...
<form action="myAction.do" method="post" onSubmit="javascript: beforeSubmit();">
    <checkbox name="checkboxName" value="checkboxValue" disabled="disabled" id="disabledCheckbox" />
    <input type="submit />
</form>

Because the checkbox is enabled before the form is submitted, its value is posted in common way. Only thing that isn't very pleasant about this solution is that this checkbox becomes enabled for a while and that can be seen by users. But it's just a detail I can live with.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
sporak
  • 496
  • 5
  • 10
3

There is no other option other than a hidden field, so try to use a hidden field like demonstrated in the code below:

<input type="hidden" type="text" name="chk1[]" id="tasks" value="xyz" >
<input class="display_checkbox" type="checkbox" name="chk1[]" id="tasks" value="xyz" checked="check"  disabled="disabled" >Tasks
Tot Zam
  • 8,406
  • 10
  • 51
  • 76
Om R Kattimani
  • 105
  • 1
  • 9
2

Unfortunately there is no 'simple' solution. The attribute readonly cannot be applied to checkboxes. I read the W3 spec about the checkbox and found the culprit:

If a control doesn't have a current value when the form is submitted, user agents are not required to treat it as a successful control. (http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2)

This causes the unchecked state and the disabled state to result in the same parsed value.

  • readonly="readonly" is not a valid attribute for checkboxes.
  • onclick="event.preventDefault();" is not always a good solution as it's triggered on the checkbox itself. But it can work charms in some occasions.
  • Enabling the checkbox onSubmit is not a solution because the control is still not treated as a successful control so the value will not be parsed.
  • Adding another hidden input with the same name in your HTML does not work because the first control value is overwritten by the second control value as it has the same name.

The only full-proof way to do this is to add a hidden input with the same name with javascript on submitting the form.

You can use the small snippet I made for this:

function disabled_checkbox() {
  var theform = document.forms[0];
  var theinputs = theform.getElementsByTagName('input');
  var nrofinputs = theinputs.length;
  for(var inputnr=0;inputnr<nrofinputs;inputnr++) {
    if(theinputs[inputnr].disabled==true) {
      var thevalueis = theinputs[inputnr].checked==true?"on":"";
      var thehiddeninput = document.createElement("input");
      thehiddeninput.setAttribute("type","hidden");
      thehiddeninput.setAttribute("name",theinputs[inputnr].name);
      thehiddeninput.setAttribute("value",thevalueis);
      theinputs[inputnr].parentNode.appendChild(thehiddeninput);
    }
  }
}

This looks for the first form in the document, gathers all inputs and searches for disabled inputs. When a disabled input is found, a hidden input is created in the parentNode with the same name and the value 'on' (if it's state is 'checked') and '' (if it's state is '' - not checked).

This function should be triggered by the event 'onsubmit' in the FORM element as:

<form id='ID' action='ACTION' onsubmit='disabled_checkbox();'>
JPA
  • 490
  • 4
  • 8
2

You can keep it disabled as desired, and then remove the disabled attribute before the form is submitted.

$('#myForm').submit(function() {
    $('checkbox').removeAttr('disabled');
});
Sergej Fomin
  • 1,822
  • 3
  • 24
  • 42
1

Add onsubmit="this['*nameofyourcheckbox*'].disabled=false" to the form.

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
1

Adding onclick="this.checked=true"Solve my problem:
Example:

<input type="checkbox" id="scales" name="feature[]" value="scales" checked="checked" onclick="this.checked=true" />
berramou
  • 1,099
  • 9
  • 11
1

I just combined the HTML, JS and CSS suggestions in the answers here

HTML:

<input type="checkbox" readonly>

jQuery:

(function(){
    // Raj: https://stackoverflow.com/a/14753503/260665
    $(document).on('click', 'input[type="checkbox"][readonly]', function(e){
        e.preventDefault();
    });
})();

CSS:

input[type="checkbox"][readonly] {
  cursor: not-allowed;
  opacity: 0.5;
}

Since the element is not 'disabled' it still goes through the POST.

Raj Pawan Gumdal
  • 7,390
  • 10
  • 60
  • 92
0
<html>
    <head>
    <script type="text/javascript">
    function some_name() {if (document.getElementById('first').checked)      document.getElementById('second').checked=false; else document.getElementById('second').checked=true;} 
    </script>
    </head>
    <body onload="some_name();">
    <form>
    <input type="checkbox" id="first" value="first" onclick="some_name();"/>first<br/>
    <input type="checkbox" id="second" value="second" onclick="some_name();" />second
    </form>
    </body>
</html>

Function some_name is an example of a previous clause to manage the second checkbox which is checked (posts its value) or unchecked (does not post its value) according to the clause and the user cannot modify its status; there is no need to manage any disabling of second checkbox

aizaz
  • 3,056
  • 9
  • 25
  • 57
0

Here is another work around can be controlled from the backend.

ASPX

<asp:CheckBox ID="Parts_Return_Yes" runat="server" AutoPostBack="false" />

In ASPX.CS

Parts_Return_Yes.InputAttributes["disabled"] = "disabled";
Parts_Return_Yes.InputAttributes["class"] = "disabled-checkbox";

Class is only added for style purposes.

Mahib
  • 3,977
  • 5
  • 53
  • 62