为什么单选按钮不能设置为“只读”?

264

我希望展示一个单选按钮,并将其值提交,但根据情况,它不可编辑。禁用不起作用,因为它不会提交值(或者会吗?),且灰显了单选按钮。实际上,只读是我正在寻找的,但由于某种神秘原因,它不起作用。

有没有一些奇怪的技巧可以使只读功能按预期工作?我是否应该在JavaScript中完成它?

顺便问一下,有人知道为什么只读无法在单选钮中工作,而在其他输入标记中可以工作吗?这是HTML规范中那些难以理解的遗漏之一吗?


7
这是HTML规范中那些令人费解的遗漏之一吗?从用户的角度考虑,为什么要显示他们无法点击的按钮呢? - Paul D. Waite
92
为什么要显示一个不能点击的按钮?因为我希望他们知道该按钮的存在,但现在我不想让他们能够单击它。但也许以后可以。毕竟,这是一个动态表单。为什么单选按钮会与其他输入字段不同呢? - mcv
8
这是规范说明:http://www.w3.org/TR/html401/interact/forms.html#h-17.12.2"以下元素支持readonly属性:INPUT和TEXTAREA。"这显然是错误的。不过,在这里可以看到更准确的总结:http://www.w3.org/TR/WD-forms-970402#readonly"READONLY适用于类型为TEXT或PASSWORD的INPUT元素和TEXTAREA元素。"看起来这在规范之间出现了漏洞。 - graphicdivine
更加好奇。根据这份古老的文件,“例如在复选框中,您可以将其选中或取消选中(从而设置CHECKED状态),但不会更改字段的值。”(http://www.htmlcodetutorial.com/forms/_INPUT_DISABLED.html)这是真的吗?即使用户显然可以更改它,将READONLY设置为复选框/单选按钮是否会锁定该值? - graphicdivine
请查看我的帖子这里,提供了一个干净简单的解决方案。 - driven4ward
可以将 HTML 复选框设置为只读吗? - Adriano
17个回答

248

如果有其他选项,单选按钮只需要是只读的。如果没有其他选项,则已选中的单选按钮无法取消选中。如果您有其他选项,可以通过禁用其他选项来阻止用户仅更改值:

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

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


3
你的第一个解决方案存在问题,如果我想通过JavaScript启用单选按钮,那么我会突然有两个名称相同的字段,所以我必须清理其中一个。或者真正使用隐藏的那个字段,并让单选按钮设置隐藏字段的值。无论哪种方式,这比我希望的单选按钮要繁琐一些。虽然我不怀疑你的第二个解决方案可以工作,但它听起来像是一个非常丑陋的hack。因此,我想JavaScript解决方案是唯一符合我的标准的方案。我会采用这个方案。 - mcv
7
请提供 Solution 1 的翻译。它是唯一一个适当可访问的解决方案。如果需要编写脚本,请再添加一行代码,将隐藏字段的启用状态设置为与单选按钮相反的状态。 - bobince
5
我注意到乔纳森的答案中,解决方案2和3的位置互换了,因此现在评论似乎没有太多意义。 - mcv
1
想要注意的是Javascript解决方案无法工作,它只是取消了按钮的选中状态。我认为需要使用onclick="return false"来防止更改。 - dmitry
2
当我将单选按钮设置为“禁用”时,我会添加“style=cursor:default”以去除“禁用光标”。 - Joao Paulo
显示剩余4条评论

184

我曾通过禁用未选中的单选按钮来模拟单选按钮的只读属性。这样可以防止用户选择不同的值,并且在提交时,所选的值将始终被提交。

使用jQuery实现只读:

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

这种方法也可以用于使选择列表只读,但是您需要禁用每个未选中的选项。


9
这是一个变体,允许您使用“readonly”属性,就像原帖作者期望的那样:$(':radio[readonly]:not(:checked)').attr('disabled', true); - wodow
1
在以下的解决方案中,这个方案提供了最干净的代码,并且与Jquery验证器很好地配合使用,因为我不需要启用/禁用字段,或者在提交表单时处理取消绑定的点击事件并重新绑定它们。 - Kristianne Nerona
准确无误地工作。谢谢。 - Hassan Farooq
聪明!如果您已经有一组选定的输入字段,可以使用.not(..):var myRadios = $('#specific-radios'); myRadios.not(':checked').prop('disabled',true); https://api.jquery.com/not/ - JoePC
在Angular中,使用elementRef也非常好用。 - Muhammad Ahsan

26

这是一个可以使用的技巧。

<input type="radio" name="name" onclick="this.checked = false;" />

4
我正想的就是这个,不过最好你澄清一下应该是某种形式的 onClick="this.checked = <%=value%>" :) - JustLoren
这很好知道。checked 可以有 true 或 false 两个值。 - Sarfraz
只是提醒一下,对于那些默认未开启 JavaScript 的浏览器用户,这将无法正常工作。 - tloach
3
对于我的情况来说没有问题。我们已经在大量使用jQuery和Ajax了。 - mcv
2
值得注意的是,您可以只需执行 onclick="return false;" 来保持组的值不变。 - Zach
这不会阻止用户使用键盘更改值(将焦点放在元素上并使用箭头键切换值)。 - Alexandru Severin

18

我有一个很长的表单(超过250个字段)要提交到数据库。这是一个在线就业申请表。当管理员查看已提交的申请时,表单会填充来自数据库的数据。输入文本和文本区域将替换为用户提交的文本,但单选框和复选框需要保留为表单元素。禁用它们会使它们更难读取。在单击时将.checked属性设置为false不起作用,因为它们可能已由填写应用程序的用户选择。总之...

onclick="return false;"

对于“禁用”单选框和复选框,它的效果非常好。


11

最佳解决方案是设置选中或未选中状态(可以来自客户端或服务器),并且不让用户在之后更改它(即将其设置为只读)。请执行以下操作:

<input type="radio" name="name" onclick="javascript: return false;" />

在这种情况下,用户可以在浏览器中编辑HTML,将所需选项标记为已选择,并提交表单。 - error1009
2
如果有必要,他们可以轻松地删除“readonly”属性。或者使用自己的数据伪造整个请求。服务器端验证超出了本问题的范围。 - ericek111

2
我想到了一种使用JavaScript实现复选框和单选按钮只读状态的方法。它已经在当前版本的Firefox、Opera、Safari、Google Chrome以及IE的当前和以前版本(包括IE7)中进行了测试。
你可能会问为什么不直接使用disabled属性呢?因为在打印页面时,禁用的输入元素会以灰色显示。而该客户要求所有元素都以相同的颜色显示。
我不确定是否可以在此处发布源代码,因为我是在公司工作时开发的,但我可以分享这些概念。
通过onmousedown事件,您可以在点击操作更改选择状态之前读取该状态。因此,您可以存储此信息,然后通过onclick事件恢复这些状态。
<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>

这部分的JavaScript将按照以下方式运作(仅涉及概念):
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;
}

现在,您可以通过更改输入元素的onclick和onmousedown属性来启用/禁用单选按钮/复选框。


2

对于未被选中的单选按钮,请将它们标记为禁用状态。这可以防止它们响应用户输入并清除已选中的单选按钮。例如:

<input type="radio" name="var" checked="yes" value="Yes"></input>
<input type="radio" name="var" disabled="yes" value="No"></input>

5
checked="yes"是什么规范?建议使用checked="checked"或者只使用属性checked而不带值。对于disabled属性也是同样的情况。 - Robin van Baalen

2

JavaScript方法 - 这对我有用。

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

原因:

  1. $('#YourTableId').find('*') -> 这将返回所有标签。

  2. $('#YourTableId').find('*').each(function () { $(this).attr("disabled", true); }); 遍历此中捕获的所有对象并禁用输入标签。

分析(调试):

  1. form:radiobutton 在内部被视为 "input" 标签。

  2. 像上面的函数()一样,如果您尝试打印 document.write(this.tagName);

  3. 无论在哪个标签中找到单选按钮,它都会返回一个输入标签。

因此,对于单选按钮标记,上述代码行可以通过将 * 替换为 input 来进行更优化: $('#YourTableId').find('input').each(function () { $(this).attr("disabled", true); });


1
我发现使用 onclick='this.checked = false;' 可以在一定程度上起作用。被单击的单选按钮将不会被选择。然而,如果有一个已经被选中的单选按钮(例如,默认值),那么这个单选按钮将变成未选中状态。
<!-- 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>

在这种情况下,保留默认值并禁用其他单选按钮将保留已选择的单选按钮,并防止其被取消选择。
<!-- 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>

这个解决方案并不是防止默认值被更改的最优雅的方式,但它可以在启用或禁用 JavaScript 的情况下都能正常工作。


1
尝试使用属性disabled,但我认为您将无法获取单选按钮的值。 或者可以设置图像,例如:
<img src="itischecked.gif" alt="[x]" />radio button option

此致敬礼。


1
哦,我的HTML代码被剥离了: img src="itIsChecked.gif" alt="[x]" OptionChecked - Tim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接