提问人:Pekka 提问时间:11/13/2009 更新时间:12/25/2022 访问量:130828
HTML 中的三态复选框?
Tri-state Check box in HTML?
答:
您可以使用单选按钮组来实现该功能:
<input type="radio" name="choice" value="yes" />Yes
<input type="radio" name="choice" value="No" />No
<input type="radio" name="choice" value="null" />null
评论
你需要使用 javascript/css 来伪造它。
请尝试此处的示例:http://www.dynamicdrive.com/forums/archive/index.php/t-26322.html
可以禁用 HTML 表单元素 -- 这不是吗?您的用户将看到它处于三种状态之一,即选中、未选中和禁用,这些状态将显示为灰色且不可单击。对我来说,这似乎类似于“null”或“不适用”或您在第三种状态中寻找的任何内容。
评论
编辑 — 感谢 Janus Troelsen 的评论,我找到了一个更好的解决方案:
HTML5 为复选框定义了一个名为 indeterminate
的属性
请参阅 w3c 参考指南。要使复选框在视觉上不确定,请将其设置为 true:
element.indeterminate = true;
这是Janus Troelsen的小提琴。但请注意:
状态不能在 HTML 标记中设置,只能通过 Javascript 完成(请参阅此 JSfiddle 测试和 CSS 技巧中的详细文章
indeterminate
)此状态不会更改复选框的值,它只是掩盖输入真实状态的视觉提示。
浏览器测试:在 Chrome 22、Firefox 15、Opera 12 和 IE7 中为我工作。关于移动浏览器,Android 2.0 浏览器和 iOS 3.1 上的 Safari 移动版不支持它。
上一个答案
另一种选择是使用复选框透明度 对于“某些选定”状态(就像 Gmail 过去
所做的那样在以前的版本中执行)。它将需要一些 javascript 和 CSS 类。在这里,我举了一个特定的例子,它处理一个列表 可检查的项目和一个允许选择所有/不选择任何项目的复选框。 此复选框显示“某些选定”状态,当某些列表 项目被选中。给定一个带有 ID 的复选框和几个带有 一个类,
#select_all
.select_one
淡化“全选”复选框的 CSS 类将是 以后:
.some_selected { opacity: 0.5; filter: alpha(opacity=50); }
以及处理全选复选框的三态状态的 JS 代码 如下所示:
$('#select_all').change (function () { //Check/uncheck all the list's checkboxes $('.select_one').attr('checked', $(this).is(':checked')); //Remove the faded state $(this).removeClass('some_selected'); }); $('.select_one').change (function () { if ($('.select_one:checked').length == 0) $('#select_all').removeClass('some_selected').attr('checked', false); else if ($('.select_one:not(:checked)').length == 0) $('#select_all').removeClass('some_selected').attr('checked', true); else $('#select_all').addClass('some_selected').attr('checked', true); });
你可以在这里尝试一下:http://jsfiddle.net/98BMK/
评论
.prop('checked', ...)
应该使用而不是 ..attr('checked', ...)
您可以在元素上使用 HTML 的不确定
IDL 属性。input
评论
https://github.com/supernifty/tristate-checkbox 中有一个简单的 JavaScript 三态输入字段实现
带有复选框插件的jQuery插件“jstree”可以做到这一点。
http://www.jstree.com/documentation/checkbox
-马 特
您可以使用不确定状态:http://css-tricks.com/indeterminate-checkboxes/。浏览器支持它,开箱即用,不需要任何外部 js 库。
评论
就像@Franz答案一样,您也可以使用选择来完成。例如:
<select>
<option></option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
有了这个,您还可以给出一个将与表单一起发送的具体值,我认为使用 javascript 不确定版本的复选框,它将发送复选框的下划线值。
至少,当 javascript 被禁用时,你可以将其用作回调。例如,给它一个 id,然后在 load 事件中将其更改为具有不确定状态的复选框的 javascript 版本。
我认为最语义化的方式是使用复选框输入可以具有的属性。没有css,没有图像等;一个内置的 HTML 属性!readonly
参见 Fiddle:
http://jsfiddle.net/chriscoyier/mGg85/2/
如上一招所述:http://css-tricks.com/indeterminate-checkboxes/
评论
我的建议是使用
- 三个适当的 Unicode 字符用于三种状态,❓例如 ,, ✅ ❌
- 纯文本输入字段 (size=1)
- 无边框
- 只读
- 不显示光标
- onclick 处理程序在三种状态之间切换
请参阅以下示例:
/**
* loops thru the given 3 values for the given control
*/
function tristate(control, value1, value2, value3) {
switch (control.value.charAt(0)) {
case value1:
control.value = value2;
break;
case value2:
control.value = value3;
break;
case value3:
control.value = value1;
break;
default:
// display the current value if it's unexpected
alert(control.value);
}
}
function tristate_Marks(control) {
tristate(control,'\u2753', '\u2705', '\u274C');
}
function tristate_Circles(control) {
tristate(control,'\u25EF', '\u25CE', '\u25C9');
}
function tristate_Ballot(control) {
tristate(control,'\u2610', '\u2611', '\u2612');
}
function tristate_Check(control) {
tristate(control,'\u25A1', '\u2754', '\u2714');
}
<input type='text'
style='border: none;'
onfocus='this.blur()'
readonly='true'
size='1'
value='❓' onclick='tristate_Marks(this)' />
<input style="border: none;"
id="tristate"
type="text"
readonly="true"
size="1"
value="❓"
onclick="switch(this.form.tristate.value.charAt(0)) {
case '❓': this.form.tristate.value='✅'; break;
case '✅': this.form.tristate.value='❌'; break;
case '❌': this.form.tristate.value='❓'; break;
};" />
参考@BoltClock答案,这是我对更复杂的递归方法的解决方案:
http://jsfiddle.net/gx7so2tq/2/
它可能不是最漂亮的解决方案,但它对我来说效果很好,而且非常灵活。
我使用两个数据对象来定义容器:
data-select-all="chapter1"
以及元素本身:
data-select-some="chapter1"
两者具有相同的值。两个数据对象在一个复选框中的组合允许以递归方式扫描子级别。因此,需要两个“辅助”函数来防止更改触发。
除了上面提到的所有插件之外,还有一些jQuery插件也可能有所帮助:
对于单个复选框:
- jQuery-Tristate-Checkbox-plugin:http://vanderlee.github.io/tristate/
对于树状行为复选框:
- jQuery Tristate:http://jlbruno.github.io/jQuery-Tristate-Checkbox-plugin/
编辑这两个库都使用“不确定”复选框属性,因为 Html5 中的此属性仅用于样式设置(https://www.w3.org/TR/2011/WD-html5-20110113/number-state.html#checkbox-state),因此 null 值永远不会发送到服务器(复选框只能有两个值)。
为了能够将此值提交到服务器,我创建了隐藏的对应字段,这些字段使用一些 javascript 在表单提交时填充。当然,在服务器端,您需要选中这些对应字段,而不是原始复选框。
我使用了第一个库(独立复选框),其中重要的是:
- 初始化选中的、未选中的、不确定的值
- 使用 .val() 函数获取实际值
- 无法使工作 .state(可能是我的错误)
希望能有所帮助。
下面是一个使用上述不确定
属性的可运行示例:
const indeterminates = document.getElementsByClassName('indeterminate');
indeterminates['0'].indeterminate = true;
<form>
<div>
<input type="checkbox" checked="checked" />True
</div>
<div>
<input type="checkbox" />False
</div>
<div>
<input type="checkbox" class="indeterminate" />Indeterminate
</div>
</form>
只需运行代码片段即可查看其外观。
这里有其他带有简单jQuery和属性的示例:data-checked
$("#checkbox")
.click(function(e) {
var el = $(this);
switch (el.data('checked')) {
// unchecked, going indeterminate
case 0:
el.data('checked', 1);
el.prop('indeterminate', true);
break;
// indeterminate, going checked
case 1:
el.data('checked', 2);
el.prop('indeterminate', false);
el.prop('checked', true);
break;
// checked, going unchecked
default:
el.data('checked', 0);
el.prop('indeterminate', false);
el.prop('checked', false);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label><input type="checkbox" name="checkbox" value="" checked id="checkbox"> Tri-State Checkbox </label>
评论
因为我需要这样的东西 - 没有任何插件 - 用于表格中脚本生成的复选框......我最终得到了这个解决方案:
<!DOCTYPE html>
<html>
<body>
Toto <input type="checkbox" id="myCheck1" onclick="updateChkBx(this)" /><br />
Tutu <input type="checkbox" id="myCheck2" onclick="updateChkBx(this)" /><br />
Tata <input type="checkbox" id="myCheck3" onclick="updateChkBx(this)" /><br />
Tete <input type="checkbox" id="myCheck4" onclick="updateChkBx(this)" /><br />
<script>
var chkBoxState = [];
function updateChkBx(src) {
var idx = Number(src.id.substring(7)); // 7 to bypass the "myCheck" part in each checkbox id
if(typeof chkBoxState[idx] == "undefined") chkBoxState[idx] = false; // make sure we can use stored state at first call
// the problem comes from a click on a checkbox both toggles checked attribute and turns inderminate attribute to false
if(chkBoxState[idx]) {
src.indeterminate = false;
src.checked = false;
chkBoxState[idx] = false;
}
else if (!src.checked) { // passing from checked to unchecked
src.indeterminate = true;
src.checked = true; // force considering we are in a checked state
chkBoxState[idx] = true;
}
}
// to know box state, just test indeterminate, and if not indeterminate, test checked
</script>
</body>
</html>
在上面使用不确定状态的答案的基础上,我想出了一点来处理单个复选框并将它们设置为三态。
无论如何,MVC razor 每个复选框使用 2 个输入(复选框和具有相同名称的隐藏复选框,以始终在提交中强制执行一个值)。MVC 使用“true”作为复选框值,使用“false”作为同名的隐藏值;使其适合在 API 调用中使用布尔值。此代码段使用第三个隐藏状态在提交后保留最后一个请求值。
使用以下命令初始化的复选框将开始不确定。选中一次将打开该复选框。选中两次将关闭该复选框(返回同名的隐藏值)。第三次检查会将其返回到不确定状态(并清除隐藏的内容,因此提交将产生空白)。
该页面还使用要启动的查询字符串上的任何值填充另一个隐藏的(例如,triBox2Orig),因此可以在提交之间初始化和保留 3 个状态。
$(document).ready(function () {
var initCheckbox = function (chkBox)
{
var hidden = $('[name="' + $(chkBox).prop("name") + '"][type="hidden"]');
var hiddenOrig = $('[name="' + $(chkBox).prop("name") + 'Orig"][type="hidden"]').prop("value");
hidden.prop("origValue", hidden.prop("value"));
if (!chkBox.prop("checked") && !hiddenOrig) chkBox.prop("indeterminate", true);
if (chkBox.prop("indeterminate")) hidden.prop("value", null);
chkBox.change(checkBoxToggleFun);
}
var checkBoxToggleFun = function ()
{
var isChecked = $(this).prop('checked');
var hidden = $('[name="' + $(this).prop("name") + '"][type="hidden"]');
var thirdState = isChecked && hidden.prop("value") === hidden.prop("origValue");
if (thirdState) { // on 3rd click of a checkbox, set it back to indeterminate
$(this).prop("indeterminate", true);
$(this).prop('checked', false);
}
hidden.prop("value", thirdState ? null : hidden.prop("origValue"));
};
var chkBox = $('#triBox1');
initCheckbox(chkBox);
chkBox = $('#triBox2');
initCheckbox(chkBox);
});
使用辅助变量的简短片段和:indeterminate
cb1.state = 1
function toggle_tristate(cb) {
cb.state = ++cb.state % 3 // cycle through 0,1,2
if (cb.state == 0) {
cb.indeterminate = true;
cb.checked = true; // after 'indeterminate' the state 'false' follows
}
}
<input id="cb1" type="checkbox" onclick="toggle_tristate(this)">
仅被捕获。其余的都是自动处理的。state==0
评论