[html] Can HTML checkboxes be set to readonly?

I thought they could be, but as I'm not putting my money where my mouth was (so to speak) setting the readonly attribute doesn't actually seem to do anything.

I'd rather not use Disabled, since I want the checked check boxes to be submitted with the rest of the form, I just don't want the client to be able to change them under certain circumstances.

This question is related to html checkbox

The answer is


This presents a bit of a usability issue.

If you want to display a checkbox, but not let it be interacted with, why even a checkbox then?

However, my approach would be to use disabled (The user expects a disabled checkbox to not be editable, instead of using JS to make an enabled one not work), and add a form submit handler using javascript that enables checkboxes right before the form is submitted. This way you you do get your values posted.

ie something like this:

var form = document.getElementById('yourform');
form.onSubmit = function () 
{ 
    var formElems = document.getElementsByTagName('INPUT');
    for (var i = 0; i , formElems.length; i++)
    {  
       if (formElems[i].type == 'checkbox')
       { 
          formElems[i].disabled = false;
       }
    }
}

My solution is actually the opposite of FlySwat's solution, but I'm not sure if it will work for your situation. I have a group of checkboxes, and each has an onClick handler that submits the form (they're used for changing filter settings for a table). I don't want to allow multiple clicks, since subsequent clicks after the first are ignored. So I disable all checkboxes after the first click, and after submitting the form:

onclick="document.forms['form1'].submit(); $('#filters input').each(function() {this.disabled = true});"

The checkboxes are in a span element with an ID of "filters" - the second part of the code is a jQuery statement that iterates through the checkboxes and disables each one. This way, the checkbox values are still submitted via the form (since the form was submitted before disabling them), and it prevents the user from changing them until the page reloads.


<input type="checkbox" readonly="readonly" name="..." />

with jquery:

$(':checkbox[readonly]').click(function(){
            return false;
        });

it still might be a good idea to give some visual hint (css, text,...), that the control won't accept inputs.


Just use simple disabled tag like this below.

<input type="checkbox" name="email"  disabled>

I just don't want the client to be able to change them under certain circumstances.

READONLY itself won't work. You may be able to do something funky w/CSS but we usually just make them disabled.

WARNING: If they're posted back then the client can change them, period. You can't rely on readonly to prevent a user from changing something. The could always use fiddler or just chane the html w/firebug or some such thing.


@(Model.IsEnabled) Use this condition for dynamically check and uncheck and set readonly if check box is already checked.

 <input id="abc" name="abc"  type="checkbox" @(Model.IsEnabled ? "checked=checked onclick=this.checked=!this.checked;" : string.Empty) >

I happened to notice the solution given below. In found it my research for the same issue. I don't who had posted it but it wasn't made by me. It uses jQuery:

$(document).ready(function() {
    $(":checkbox").bind("click", false);
});

This would make the checkboxes read only which would be helpful for showing readonly data to the client.


Very late to the party but I found an answer for MVC (5) I disabled the CheckBox and added a HiddenFor BEFORE the checkbox, so when it is posting if finds the Hidden field first and uses that value. This does work.

 <div class="form-group">
     @Html.LabelFor(model => model.Carrier.Exists, new { @class = "control-label col-md-2" })
         <div class="col-md-10">
              @Html.HiddenFor(model => model.Carrier.Exists)
              @Html.CheckBoxFor(model => model.Carrier.Exists, new { @disabled = "disabled" })
              @Html.ValidationMessageFor(model => model.Carrier.Exists)
          </div>
 </div>

What none of you are thinking about here is that you are all using JavaScript, which can be very easily bypassed by any user.

Simply disabling it disables all JQuery/Return False statements.

Your only option for readonly checkboxes is server side.

Display them, let them change them but don't accept the new post data from them.


<input name="isActive" id="isActive" type="checkbox" value="1" checked="checked" onclick="return false"/>

No, but you might be able to use javascript events to achieve something similar


If anyone else is using MVC and an editor template, this is how I control displaying a read only property (I use a custom attribute to get the value in the if statement)

@if (true)
{
    @Html.HiddenFor(m => m)
    @(ViewData.Model ? Html.Raw("Yes") : Html.Raw("No"))
} 
else
{               
    @Html.CheckBoxFor(m => m)
}

Belated answer, but most answers seem to over complicate it.

As I understand it, the OP was basically wanting:

  1. Readonly checkbox to show status.
  2. Value returned with form.

It should be noted that:

  1. The OP preferred not to use the disabled attribute, because they 'want the checked check boxes to be submitted with the rest of the form'.
  2. Unchecked checkboxes are not submitted with the form, as the quote from the OP in 1. above indicates they knew already. Basically, the value of the checkbox only exists if it is checked.
  3. A disabled checkbox clearly indicates that it cannot be changed, by design, so a user is unlikely to attempt to change it.
  4. The value of a checkbox is not limited to indicating its status, such as yes or false, but can be any text.

Therefore, since the readonly attribute does not work, the best solution, requiring no javascript, is:

  1. A disabled checkbox, with no name or value.
  2. If the checkbox is to be displayed as checked, a hidden field with the name and value as stored on the server.

So for a checked checkbox:

_x000D_
_x000D_
<input type="checkbox" checked="checked" disabled="disabled" />_x000D_
<input type="hidden" name="fieldname" value="fieldvalue" />
_x000D_
_x000D_
_x000D_

For an unchecked checkbox:

_x000D_
_x000D_
<input type="checkbox" disabled="disabled" />
_x000D_
_x000D_
_x000D_

The main problem with disabled inputs, especially checkboxes, is their poor contrast which may be a problem for some with certain visual disabilities. It may be better to indicate a value by plain words, such as Status: none or Status: implemented, but including the hidden input above when the latter is used, such as:

_x000D_
_x000D_
<p>Status: Implemented<input type="hidden" name="status" value="implemented" /></p>
_x000D_
_x000D_
_x000D_


onclick="javascript: return false;"

If you want ALL your checkboxes to be "locked" so user can't change the "checked" state if "readonly" attibute is present, then you can use jQuery:

$(':checkbox').click(function () {
    if (typeof ($(this).attr('readonly')) != "undefined") {
        return false;
    }
});

Cool thing about this code is that it allows you to change the "readonly" attribute all over your code without having to rebind every checkbox.

It works for radio buttons as well.


If you need the checkbox to be submitted with the form but effectively read-only to the user, I recommend setting them to disabled and using javascript to re-enable them when the form is submitted.

This is for two reasons. First and most important, your users benefit from seeing a visible difference between checkboxes they can change and checkboxes which are read-only. Disabled does this.

Second reason is that the disabled state is built into the browser so you need less code to execute when the user clicks on something. This is probably more of a personal preference than anything else. You'll still need some javascript to un-disable these when submitting the form.

It seems easier to me to use some javascript when the form is submitted to un-disable the checkboxes than to use a hidden input to carry the value.


The following works if you know that the checkbox is always checked:

<input type="checkbox" name="Name" checked onchange='this.checked = true;'>

another "simple solution":

<!-- field that holds the data -->
<input type="hidden" name="my_name" value="1" /> 
<!-- visual dummy for the user -->
<input type="checkbox" name="my_name_visual_dummy" value="1" checked="checked" disabled="disabled" />

disabled="disabled" / disabled=true


Simplest (in my view):

onclick="javascript:{this.checked = this.defaultChecked;}"

The main reason people would like a read-only check-box and (as well) a read-only radio-group is so that information that cannot be changed can be presented back to the user in the form it was entered.

OK disabled will do this -- unfortunately disabled controls are not keyboard navigable and therefore fall foul of all accessibility legislation. This is the BIGGEST hangup in HTML that I know of.


<input type="checkbox" onclick="return false" /> will work for you , I am using this


I would have commented on ConroyP's answer, but that requires 50 reputation which I don't have. I do have enough reputation to post another answer. Sorry.

The problem with ConroyP's answer is that the checkbox is rendered unchangeable by not even including it on the page. Although Electrons_Ahoy does not stipulate as much, the best answer would be one in which the unchangeable checkbox would look similar, if not the same as, the changeable checkbox, as is the case when the "disabled" attribute is applied. A solution which addresses the two reasons Electrons_Ahoy gives for not wanting to use the "disabled" attribute would not necessarily be invalid because it utilized the "disabled" attribute.

Assume two boolean variables, $checked and $disabled :

if ($checked && $disabled)
    echo '<input type="hidden" name="my_name" value="1" />';
echo '<input type="checkbox" name="my_name" value="1" ',
    $checked ? 'checked="checked" ' : '',
    $disabled ? 'disabled="disabled" ' : '', '/>';

The checkbox is displayed as checked if $checked is true. The checkbox is displayed as unchecked if $checked is false. The user can change the state of the checkbox if and only if $disabled is false. The "my_name" parameter is not posted when the checkbox is unchecked, by the user or not. The "my_name=1" parameter is posted when the checkbox is checked, by the user or not. I believe this is what Electrons_Ahoy was looking for.


Building on the above answers, if using jQuery, this may be an good solution for all inputs:

<script>
    $(function () {
        $('.readonly input').attr('readonly', 'readonly');
        $('.readonly textarea').attr('readonly', 'readonly');
        $('.readonly input:checkbox').click(function(){return false;});
        $('.readonly input:checkbox').keydown(function () { return false; });
    });
</script>

I'm using this with Asp.Net MVC to set some form elements read only. The above works for text and check boxes by setting any parent container as .readonly such as the following scenarios:

<div class="editor-field readonly">
    <input id="Date" name="Date" type="datetime" value="11/29/2012 4:01:06 PM" />
</div>
<fieldset class="flags-editor readonly">
     <input checked="checked" class="flags-editor" id="Flag1" name="Flags" type="checkbox" value="Flag1" />
</fieldset>

<input name="testName" type="checkbox" disabled>

Or just:

$('your selector').click(function(evt){evt.preventDefault()});

Some of the answers on here seem a bit roundabout, but here's a small hack.

<form id="aform" name="aform" method="POST">
    <input name="chkBox_1" type="checkbox" checked value="1" disabled="disabled" />
    <input id="submitBttn" type="button" value="Submit" onClick='return submitPage();'>
</form>?

then in jquery you can either choose one of two options:

$(document).ready(function(){
    //first option, you don't need the disabled attribute, this will prevent
    //the user from changing the checkbox values
    $("input[name^='chkBox_1']").click(function(e){
        e.preventDefault();
    });

    //second option, keep the disabled attribute, and disable it upon submit
    $("#submitBttn").click(function(){
        $("input[name^='chkBox_1']").attr("disabled",false);
        $("#aform").submit();
    });

});

?

demo: http://jsfiddle.net/5WFYt/


When posting an HTML checkbox to the server, it has a string value of 'on' or ''.

Readonly does not stop the user editing the checkbox, and disabled stops the value being posted back.
One way around this is to have a hidden element to store the actual value and the displayed checkbox is a dummy which is disabled. This way the checkbox state is persisted between posts.

Here is a function to do this. It uses a string of 'T' or 'F' and you can change this any way you like. This has been used in an ASP page using server side VB script.

public function MakeDummyReadonlyCheckbox(i_strName, i_strChecked_TorF)

    dim strThisCheckedValue

    if (i_strChecked_TorF = "T") then
        strThisCheckedValue = " checked "
        i_strChecked_TorF = "on"
    else
        strThisCheckedValue = ""
        i_strChecked_TorF = ""
    end if

    MakeDummyReadonlyCheckbox = "<input type='hidden' id='" & i_strName & "' name='" & i_strName & "' " & _
        "value='" & i_strChecked_TorF & "'>" & _
    "<input type='checkbox' disabled id='" & i_strName & "Dummy' name='" & i_strName & "Dummy' " & _
        strThisCheckedValue & ">"   
end function

public function GetCheckbox(i_objCheckbox)

    select case trim(i_objCheckbox)

        case ""
            GetCheckbox = "F"

        case else
            GetCheckbox = "T"

    end select

end function

At the top of an ASP page you can pickup the persisted value...

strDataValue = GetCheckbox(Request.Form("chkTest"))

and when you want to output your checkbox you can do this...

response.write MakeDummyReadonlyCheckbox("chkTest", strDataValue)

I have tested this and it works just fine. It also does not rely upon JavaScript.


If you want them to be submitted to the server with form but be not interacive for user, you can use pointer-events: none in css (works in all modern browsers except IE10- and Opera 12-) and set tab-index to -1 to prevent changing via keyboard. Also note that you can't use label tag as click on it will change the state anyway.

_x000D_
_x000D_
input[type="checkbox"][readonly] {_x000D_
  pointer-events: none !important;_x000D_
}_x000D_
_x000D_
td {_x000D_
  min-width: 5em;_x000D_
  text-align: center;_x000D_
}_x000D_
_x000D_
td:last-child {_x000D_
  text-align: left;_x000D_
}
_x000D_
<table>_x000D_
  <tr>_x000D_
    <th>usual_x000D_
    <th>readonly_x000D_
    <th>disabled_x000D_
  </tr><tr>_x000D_
    <td><input type=checkbox />_x000D_
    <td><input type=checkbox readonly tabindex=-1 />_x000D_
    <td><input type=checkbox disabled />_x000D_
    <td>works_x000D_
  </tr><tr>_x000D_
    <td><input type=checkbox checked />_x000D_
    <td><input type=checkbox readonly checked tabindex=-1 />_x000D_
    <td><input type=checkbox disabled checked />_x000D_
    <td>also works_x000D_
  </tr><tr>_x000D_
    <td><label><input type=checkbox checked /></label>_x000D_
    <td><label><input type=checkbox readonly checked tabindex=-1 /></label>_x000D_
    <td><label><input type=checkbox disabled checked /></label>_x000D_
    <td>broken - don't use label tag_x000D_
  </tr>_x000D_
</table>
_x000D_
_x000D_
_x000D_


you can use this:

<input type="checkbox" onclick="return false;"/>

This works because returning false from the click event stops the chain of execution continuing.


<input type="checkbox" onclick="this.checked=!this.checked;">

But you absolutely MUST validate the data on the server to ensure it hasn't been changed.


Contributing very very late...but anyway. On page load, use jquery to disable all checkboxes except the currently selected one. Then set the currently selected one as read only so it has a similar look as the disabled ones. User cannot change the value, and the selected value still submits.


I would use the readonly attribute

<input type="checkbox" readonly>

Then use CSS to disable interactions:

input[type='checkbox'][readonly]{
    pointer-events: none;
}

Note that using the pseudo-class :read-only doesn't work here.

input[type='checkbox']:read-only{ /*not working*/
    pointer-events: none;
}

In old HTML you can use

<input type="checkbox" disabled checked>text

but actually is not recommended to use just simply old HTML, now you should use XHTML.

In well formed XHTML you have to use

<input type="checkbox" disabled="disabled" checked="checked" />text <!-- if yu have a checked box-->
<input type="checkbox" disabled="disabled" />text <!-- if you have a unchecked box -->

well formed XHTML requires a XML form, thats the reason to use disabled="disabled" instead of simply use disabled.


When submitting the form, we actually pass the value of the checkbox, not the state (checked/unchecked). Readonly attribute prevents us to edit the value, but not the state. If you want to have a read-only field that will represent the value you want to submit, use readonly text.


No, input checkboxes can't be readonly.

But you can make them readonly with javascript!

Add this code anywhere at any time to make checkboxes readonly work as assumed, by preventing the user from modifying it in any way.

_x000D_
_x000D_
jQuery(document).on('click', function(e){_x000D_
      // check for type, avoid selecting the element for performance_x000D_
      if(e.target.type == 'checkbox') {_x000D_
          var el = jQuery(e.target);_x000D_
          if(el.prop('readonly')) {_x000D_
              // prevent it from changing state_x000D_
              e.preventDefault();_x000D_
          }_x000D_
      }_x000D_
});
_x000D_
input[type=checkbox][readonly] {_x000D_
    cursor: not-allowed;_x000D_
}
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<label><input type="checkbox" checked readonly> I'm readonly!</label>
_x000D_
_x000D_
_x000D_

You can add this script at any time after jQuery has loaded.

It will work for dynamically added elements.

It works by picking up the click event (that happens before the change event) on any element on the page, it then checks if this element is a readonly checkbox, and if it is, then it blocks the change.

There are so many ifs to make it not affect the performance of the page.


READONLY doesn't work on checkboxes as it prevents you from editing a field's value, but with a checkbox you're actually editing the field's state (on || off)

From faqs.org:

It's important to understand that READONLY merely prevents the user from changing the value of the field, not from interacting with the field. In checkboxes, for example, you can check them on or off (thus setting the CHECKED state) but you don't change the value of the field.

If you don't want to use disabled but still want to submit the value, how about submitting the value as a hidden field and just printing its contents to the user when they don't meet the edit criteria? e.g.

// user allowed change
if($user_allowed_edit)
{
    echo '<input type="checkbox" name="my_check"> Check value';
}
else
{
    // Not allowed change - submit value..
    echo '<input type="hidden" name="my_check" value="1" />';
    // .. and show user the value being submitted
    echo '<input type="checkbox" disabled readonly> Check value';
}

<input type="radio" name="alwaysOn" onchange="this.checked=true" checked="checked">
<input type="radio" name="alwaysOff" onchange="this.checked=false" >

Try this to make the checkbox read-only and yet disallow user from checking. This will let you POST the checkbox value. You need to select the default state of the checkbox as Checked in order to do so.

<input type="checkbox" readonly="readonly" onclick="this.checked =! this.checked;">

If you want the above functionality + dont want to receive the checkbox data, try the below:

<input type="checkbox" readonly="readonly" disabled="disabled" onclick="this.checked =! this.checked;">

Hope that helps.


You could always use a small image that looks like a check box.


This is a checkbox you can't change:

<input type="checkbox" disabled="disabled" checked="checked">

Just add disabled="disabled" as an attribute.


Edit to address the comments:

If you want the data to be posted back, than a simple solutions is to apply the same name to a hidden input:

<input name="myvalue" type="checkbox" disabled="disabled" checked="checked"/>
<input name="myvalue" type="hidden" value="true"/>

This way, when the checkbox is set to 'disabled', it only serves the purpose of a visual representation of the data, instead of actually being 'linked' to the data. In the post back, the value of the hidden input is being sent when the checkbox is disabled.


I know that "disabled" isn't an acceptable answer, since the op wants it to post. However, you're always going to have to validate values on the server side EVEN if you have the readonly option set. This is because you can't stop a malicious user from posting values using the readonly attribute.

I suggest storing the original value (server side), and setting it to disabled. Then, when they submit the form, ignore any values posted and take the original values that you stored.

It'll look and behave like it's a readonly value. And it handles (ignores) posts from malicious users. You're killing 2 birds with one stone.


I used this to achieve the results:

<input type=checkbox onclick="return false;" onkeydown="return false;" />

Most of the current answers have one or more of these problems:

  1. Only check for mouse not keyboard.
  2. Check only on page load.
  3. Hook the ever-popular change or submit events which won't always work out if something else has them hooked.
  4. Require a hidden input or other special elements/attributes that you have to undo in order to re-enable the checkbox using javascript.

The following is simple and has none of those problems.

$('input[type="checkbox"]').on('click keyup keypress keydown', function (event) {
    if($(this).is('[readonly]')) { return false; }
});

If the checkbox is readonly, it won't change. If it's not, it will. It does use jquery, but you're probably using that already...

It works.


Latest jQuery has this feature

$("#txtname").prop('readonly', false);

Why not cover the input with a blank div on top.

<div id='checkbox_wrap'>
   <div class='click_block'></div>
   <input type='checkbox' /> 
</div>

then something like this with CSS

 #checkbox_wrap{
   height:10px;
   width:10px;
   }
 .click_block{
   height: 10px;
   width: 10px;
   position: absolute;
   z-index: 100;
}