Why can't radio buttons be "readonly"?
Asked Answered
B

17

267

I would like to show a radio button, have its value submitted, but depending on the circumstances, have it not editable. Disabled doesn't work, because it doesn't submit the value (or does it?), and it grays out the radio button. Read-only is really what I'm looking for, but for some mysterious reason it doesn't work.

Is there some weird trick I need to pull to get read-only to work as expected? Should I just do it in JavaScript instead?

Incidentally, does anyone know why read-only doesn't work in radio buttons, while it does work in other input tags? Is this one of those incomprehensible omissions in the HTML specs?

Briard answered 23/12, 2009 at 14:9 Comment(6)
“Is this one of those incomprehensible omissions in the HTML specs?” Think of it from a user’s point of view. Why display a button they can’t click?Merciless
Why display a button they can't click? Because I want them to know the button is there, but I don't want them to be able to click it right now. But maybe later. It's a dynamic form, after all. Why would a radio button be any different from any other input field?Briard
Here's the spec: w3.org/TR/html401/interact/forms.html#h-17.12.2 "The following elements support the readonly attribute: INPUT and TEXTAREA." Which is obviously wrong. Back here, though, we see a more accurate summary: w3.org/TR/WD-forms-970402#readonly "READONLY applies to INPUT elements of type TEXT or PASSWORD and to the TEXTAREA element." Looks like this has slipped between the gaps of recs and specs.Vast
Even more curious. According to this ancient document "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." ( htmlcodetutorial.com/forms/_INPUT_DISABLED.html ) Is this true? Does setting READONLY on a checkbox/radio lock the value, even though the user can apparently alter it?Vast
check my post [here][1] gives a clean simple solution to the issue [1]: https://mcmap.net/q/56594/-how-to-make-disabled-readonly-functionality-for-radio-buttons-and-checkboxesSackbut
related #155791Garibay
T
187

I've faked readonly on a radio button by disabling only the un-checked radio buttons. It keeps the user from selecting a different value, and the checked value will always post on submit.

Using jQuery to make readonly:

$(':radio:not(:checked)').attr('disabled', true);

This approach also worked for making a select list readonly, except that you'll need to disable each un-selected option.

Tabb answered 25/3, 2011 at 20:40 Comment(4)
A variation on this to allow you to use the readonly property, as the OP expected it to work: $(':radio[readonly]:not(:checked)').attr('disabled', true);Platelayer
Among the solutions below, this solution provides the cleanest code, and works well with Jquery validator since I do not need to enable/disable fields, or deal with unbinding click events and re-binding them when submitting the form.Freeboot
Clever! Using .not(..), in case you already have a set of selected input fields: var myRadios = $('#specific-radios'); myRadios.not(':checked').prop('disabled',true); api.jquery.com/notUbiety
Works great with elementRef in angular tooMonreal
B
250

Radio buttons would only need to be read-only if there are other options. If you don't have any other options, a checked radio button cannot be unchecked. If you have other options, you can prevent the user from changing the value merely by disabling the other options:

<input type="radio" name="foo" value="Y" checked>
<input type="radio" name="foo" value="N" disabled>

Fiddle: http://jsfiddle.net/qqVGu/

Backwoodsman answered 23/12, 2009 at 14:12 Comment(7)
The problem with your first solution is that if I want to enable the radiobutton through javascript, I suddenly have two fields with the same name, so I have to clean up one of them. Or use the hidden one for real and have the radio button just set the value of the hidden field. Ether way, it's just a bit more cumbersome than I'd like a radiobutton to be. Your second solution, although I don't doubt it works, sounds like a really ugly hack. So I guess the javascript solution is the only one that meets my criteria. I'll go with that.Briard
Solution 2 is really a poor hack that probably won't work on less used browsers, such as "links". It also won't work on all browsers because you can TAB to it. It will just confuse the user.Schoof
Want to notice that Javascript solution is not worked, it just unchecks button. I suppose it need be onclick="return false" to prevent change.Ecospecies
onclick="return false" works in FF15 and Chrome22, but an onchange event is also fired. In IE9 the existing dot is actually unset. Solution 1 was the only one that worked for me in all 3 browsers. If you need JS manipulation then you should give the radio buttons a prefix/suffix to prevent same element ID conflict, but its not needed for FORM submit as the last element with the same name overrides previous value however disabled elements do not submit anyway.Programme
@Megan posted a more elegant solution below. Of course that's just my opinion.Whooper
When I set radio "disabled" I add "style=cursor:default" to remove "disabled cursor".Squill
If a radio is readonly and there are other options, then it could not loose its checked satus if it is read only, this is sloppy programming/spec on the browser side/ hard for everyone else in the world side. So many hoops to jump trough just to make a form read only but posted.Folio
T
187

I've faked readonly on a radio button by disabling only the un-checked radio buttons. It keeps the user from selecting a different value, and the checked value will always post on submit.

Using jQuery to make readonly:

$(':radio:not(:checked)').attr('disabled', true);

This approach also worked for making a select list readonly, except that you'll need to disable each un-selected option.

Tabb answered 25/3, 2011 at 20:40 Comment(4)
A variation on this to allow you to use the readonly property, as the OP expected it to work: $(':radio[readonly]:not(:checked)').attr('disabled', true);Platelayer
Among the solutions below, this solution provides the cleanest code, and works well with Jquery validator since I do not need to enable/disable fields, or deal with unbinding click events and re-binding them when submitting the form.Freeboot
Clever! Using .not(..), in case you already have a set of selected input fields: var myRadios = $('#specific-radios'); myRadios.not(':checked').prop('disabled',true); api.jquery.com/notUbiety
Works great with elementRef in angular tooMonreal
Y
26

This is the trick you can go with.

<input type="radio" name="name" onclick="this.checked = false;" />
Yuille answered 23/12, 2009 at 14:13 Comment(6)
Exactly what I was thinking, altho it would be best if you clarified that it should be onClick="this.checked = <%=value%>" of some variety :)Wallacewallach
that is great to know. checked can have either of true or false values.Yuille
Just a warning that this won't work for those of us who browse with javascript not turned on by default.Melee
Not a problem for my case. We use tons of jQuery and Ajax already.Briard
Worth noting you can just do onclick="return false;" to keep the value the same for the groupMarabelle
This won't prevent the user from changing the value using the keyboard (focus the element and use arrow keys to switch value)Meddle
P
19

I have a lengthy form (250+ fields) that posts to a db. It is an online employment application. When an admin goes to look at an application that has been filed, the form is populated with data from the db. Input texts and textareas are replaced with the text they submitted but the radios and checkboxes are useful to keep as form elements. Disabling them makes them harder to read. Setting the .checked property to false onclick won't work because they may have been checked by the user filling out the app. Anyhow...

onclick="return false;"

works like a charm for 'disabling' radios and checkboxes ipso facto.

Pileum answered 16/10, 2012 at 18:27 Comment(0)
D
10

The best solution is to set the checked or unchecked state (either from client or server) and to not let the user change it after wards (i.e make it readonly) do the following:

<input type="radio" name="name" onclick="javascript: return false;" />
Disjunct answered 10/6, 2011 at 14:18 Comment(2)
no! in this case, user can edit html in the browser, mark needed option as selected and post the form.Technique
They could just as easily remove the "readonly" attribute, if there was one. Or just forge the whole request with their data. Server-side validation is out of scope of this question.Diamagnetic
P
2

I've come up with a javascript-heavy way to achieve a readonly state for check boxes and radio buttons. It is tested against current versions of Firefox, Opera, Safari, Google Chrome, as well as current and previous versions of IE (down to IE7).

Why not simply use the disabled property you ask? When printing the page, disabled input elements come out in a gray color. The customer for which this was implemented wanted all elements to come out the same color.

I'm not sure if I'm allowed to post the source code here, as I developed this while working for a company, but I can surely share the concepts.

With onmousedown events, you can read the selection state before the click action changes it. So you store this information and then restore these states with an onclick event.

<input id="r1" type="radio" name="group1" value="r1" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 1</input>
<input id="r2" type="radio" name="group1" value="r2" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 2</input>
<input id="r3" type="radio" name="group1" value="r3" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 3</input>

<input id="c1" type="checkbox" name="group2" value="c1" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 1</input>
<input id="c2" type="checkbox" name="group2" value="c2" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);">Option 2</input>
<input id="c3" type="checkbox" name="group2" value="c3" onmousedown="storeSelectedRadiosForThisGroup(this.name);" onclick="setSelectedStateForEachElementOfThisGroup(this.name);" checked="checked">Option 3</input>

The javascript portion of this would then work like this (again only the concepts):

var selectionStore = new Object();  // keep the currently selected items' ids in a store

function storeSelectedRadiosForThisGroup(elementName) {
    // get all the elements for this group
    var radioOrSelectGroup = document.getElementsByName(elementName);

    // iterate over the group to find the selected values and store the selected ids in the selectionStore
    // ((radioOrSelectGroup[i].checked == true) tells you that)
    // remember checkbox groups can have multiple checked items, so you you might need an array for the ids
    ...
}

function setSelectedStateForEachElementOfThisGroup(elementName) {
    // iterate over the group and set the elements checked property to true/false, depending on whether their id is in the selectionStore
    ...

    // make sure you return false here
    return false;
}

You can now enable/disable the radio buttons/checkboxes by changing the onclick and onmousedown properties of the input elements.

Policy answered 15/9, 2011 at 9:19 Comment(0)
A
2

For the non-selected radio buttons, flag them as disabled. This prevents them from responding to user input and clearing out the checked radio button. For example:

<input type="radio" name="var" checked="yes" value="Yes"></input>
<input type="radio" name="var" disabled="yes" value="No"></input>
Aldwin answered 15/5, 2013 at 23:26 Comment(1)
checked="yes"? What spec is that? Either use checked="checked" or just the attribute checked without a value. Same for disabled.Kelantan
E
2

JavaScript way - this worked for me.

<script>
$(document).ready(function() {
   $('#YourTableId').find('*').each(function () { $(this).attr("disabled", true); });
});
</script>

Reason:

  1. $('#YourTableId').find('*') -> this returns all the tags.

  2. $('#YourTableId').find('*').each(function () { $(this).attr("disabled", true); }); iterates over all objects captured in this and disable input tags.

Analysis (Debugging):

  1. form:radiobutton is internally considered as an "input" tag.

  2. Like in the above function(), if you try printing document.write(this.tagName);

  3. Wherever, in tags it finds radio buttons, it returns an input tag.

So, above code line can be more optimized for radio button tags, by replacing * with input: $('#YourTableId').find('input').each(function () { $(this).attr("disabled", true); });

Empennage answered 3/6, 2014 at 11:26 Comment(0)
K
1

Try the attribute disabled, but I think the you won't get the value of the radio buttons. Or set images instead like:

<img src="itischecked.gif" alt="[x]" />radio button option

Best Regards.

Kibbutz answered 23/12, 2009 at 14:15 Comment(1)
oh, my html code was stripped: img src="itIsChecked.gif" alt="[x]" OptionCheckedKibbutz
S
1

A fairly simple option would be to create a javascript function called on the form's "onsubmit" event to enable the radiobutton back so that it's value is posted with the rest of the form.
It does not seem to be an omission on HTML specs, but a design choice (a logical one, IMHO), a radiobutton can't be readonly as a button can't be, if you don't want to use it, then disable it.

Schlessel answered 23/12, 2009 at 14:26 Comment(0)
M
1

I found that use onclick='this.checked = false;' worked to a certain extent. A radio button that was clicked would not be selected. However, if there was a radio button that was already selected (e.g., a default value), that radio button would become unselected.

<!-- didn't completely work -->
<input type="radio" name="r1" id="r1" value="N" checked="checked" onclick='this.checked = false;'>N</input>
<input type="radio" name="r1" id="r1" value="Y" onclick='this.checked = false;'>Y</input>

For this scenario, leaving the default value alone and disabling the other radio button(s) preserves the already selected radio button and prevents it from being unselected.

<!-- preserves pre-selected value -->
<input type="radio" name="r1" id="r1" value="N" checked="checked">N</input>
<input type="radio" name="r1" id="r1" value="Y" disabled>Y</input>

This solution is not the most elegant way of preventing the default value from being changed, but it will work whether or not javascript is enabled.

Minim answered 2/11, 2011 at 23:16 Comment(0)
S
1

Getting radio buttons to be read-only is pretty straightforward to accomplish. Use CSS to disable the ability of the mouse to select the radio button or it's label, and set tabindex = -1 on these elements to prevent the user from using a combination of the tab key and the spacebar to select the elements.

input[type="radio"].readonly {
    pointer-events: none;
}

label.readonly {
    pointer-events: none;
}
<input tabindex="-1" class="readonly" type="radio" name="rbgOptions" id="cbOpt1" value="Option1">
<label tabindex="-1" class="readonly" for="cbOpt1">Option 1</label>
<input tabindex="-1" class="readonly" type="radio" name="rbgOptions" id="cbOpt2" value="Option2">
<label tabindex="-1" class="readonly" for="cbIOP">Option 2</label>
Synergetic answered 17/5, 2023 at 17:45 Comment(0)
U
0

I'm using a JS plugin that styles checkbox/radio input elements and used the following jQuery to establish a 'readonly state' where the underlying value is still posted but the input element appears inaccessible to the user, which is I believe the intended reason we would use a readonly input attribute...

if ($(node).prop('readonly')) {
    $(node).parent('div').addClass('disabled'); // just styling, appears greyed out
    $(node).on('click', function (e) {
        e.preventDefault();
    });
}
Utu answered 20/12, 2018 at 12:26 Comment(0)
J
0

Here is my solution (override) for Sencha ExtJS 7.2+ (checkbox and radio in a single override)


Ext.define('MyApp.override.field.Checkbox', {
    override: 'Ext.field.Checkbox',

    /**
     * OVERRIDE: to allow updateReadOnly to work propperly
     * @param {boolean} newValue
     *
     * To ensure the disabled state stays active if the field is still readOnly
     * we re - set the disabled state
     */
    updateDisabled(newValue) {
        this.callParent(arguments);

        if (!newValue && this.getReadOnly()) {
            this.inputElement.dom.disabled = true;
        }
    },

    /**
     * OVERRIDE: readonly for radiogroups and checkboxgroup do not work as other fields
     *     https://mcmap.net/q/55743/-why-can-39-t-radio-buttons-be-quot-readonly-quot
     *
     * @param {boolean} newValue
     *
     *  - use disabled on the field
     */
    updateReadOnly(value) {
        this.callParent(arguments);

        if (!this.getDisabled()) {
            this.inputElement.dom.disabled = value;
        }
    }
});
Japan answered 6/9, 2021 at 11:39 Comment(0)
R
0

Disabled works on individual radio buttons (not the whole set). If you are using PHP and your circumstances are known on the server before loading the page in the browser you can use this very simple solution.

<php $chcky= (condition) ? 'checked' : 'disabled';?>
<php $chckn= (condition) ? 'checked' : 'disabled';?>
<input type="radio" name="var" value="Yes" <?php echo $chcky?>></input>
<input type="radio" name="var" value="No" <?php echo $chckn?>></input>

I use it on the page responding a form submission.

Racehorse answered 2/2, 2022 at 15:24 Comment(0)
T
0

Extract from https://mcmap.net/q/54361/-how-can-i-make-an-entire-html-form-quot-readonly-quot

If you can't use the 'disabled' attribut (as it erases the value's input at POST), and noticed that html attribut 'readonly' works only on textarea and some input(text, password, search, as far I've seen), and finally, if you don't want to bother with duplicating all your select, checkbox and radio with hidden input, you might find the following function or any of his inner logics to your liking :

addReadOnlyToFormElements = function (idElement) {
    // html readonly don't work on input of type checkbox and radio, neither on select. So, a safe trick is to disable the non-selected items
    $('#' + idElement + ' input[type="radio"]:not(:checked)').prop('disabled',true); 

    // and, on the selected ones, mimic readonly appearance
    $('#' + idElement + ' input[type="radio"]:checked').css('opacity','0.5');
}

And there's nothing easier than to remove these readonly

removeReadOnlyFromFormElements = function (idElement) {
    // Remove the disabled attribut on non-selected
    $('#' + idElement + ' input[type="radio"]:not(:checked)').prop('disabled',false); 
 
    // Remove readonly appearance on selected ones
    $('#' + idElement + ' input[type="radio"]:checked').css('opacity','');
}
Tungus answered 11/2, 2022 at 23:23 Comment(0)
R
-2

What about capturing an "On_click()" event in JS and checking it like here?:

http://www.dynamicdrive.com/forums/showthread.php?t=33043

Resolvent answered 23/12, 2009 at 14:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.