我怎样才能优雅地让两个 HTML 复选框相互勾选?
How can I elegantly get two HTML checkboxes to tick each other off?
我有两个互斥的复选框;既然如此,我希望每个人在进行更改时自动反映另一个人的相反状态:如果选中了 checkboxA,那么 checkboxB 应该是,如果选中,未选中(等等,我相信你知道我均值)。
我正在我的代码隐藏中创建复选框,如下所示:
ckbxPaymentForSelf = new CheckBox();
ckbxPaymentForSelf.Text = "myself";
ckbxPaymentForSelf.ID = "ckbxPaymentForSelf";
this.Controls.Add(ckbxPaymentForSelf);
ckbxPaymentForSomeoneElse = new CheckBox();
ckbxPaymentForSomeoneElse.Text = "someone else";
ckbxPaymentForSomeoneElse.ID = "ckbxPaymentForSomeoneElse";
this.Controls.Add(ckbxPaymentForSomeoneElse);
基于 this,我想也许我可以使用复选框的 Name 属性 并将它们设置为相同的值,例如 "ckbxsSelfOrSomeoneElse" 但是 没有 "Name" 属性 复选框可供我使用。
我可以这样写一些jQuery(伪脚本):
$(document).on("change", '[id$=ckbxPaymentForSelf]', function () {
var ckd = this.checked;
if (ckd) // check ckbxPaymentForSomeoneElse and uncheck if it it's checked
else // check ckbxPaymentForSomeoneElse and check if it it's unchecked
});
$(document).on("change", '[id$=ckbxPaymentForSomeoneElse]', function () {
var ckd = this.checked;
if (ckd) // check ckbxPaymentForSelf and uncheck if it it's checked
else // check ckbxPaymentForSelf and check if it it's unchecked
});
...但我想知道是否有更明显或更优雅的解决方案,因为这无疑是一个普遍的要求。
更新
我试过答案:
$(document).on("click", '[id$=ckbxPaymentForSelf]', function () {
alert('reached onclick for ckbxpaymentforself');
$('#ckbxPaymentForSomeoneElse').prop('checked', !this.checked);
});
$(document).on("click", '[id$=ckbxPaymentForSomeoneElse]', function () {
alert('reached onclick for ckbxpaymentforsomeoneelse');
$('#ckbxPaymentForSelf').prop('checked', !this.checked);
});
...但是,不合逻辑(在我看来,显然在他看来),这是行不通的。 strange/suspicious 是警报消息显示了两次!我必须点击它们两次才能关闭它们。为什么会这样,会不会是 the/a 问题?我确实注意到 jQuery 在 "View Source" 中出现了两次,当然,它在实际源代码中只出现在一个地方(在 .asxc 文件的底部)。
更新 2
正如 wilusdaman 所建议的(让它成为一个答案,Wilus,我会接受它),最优雅的方法是改用单选按钮。只需要这个:
rbPaymentForSelf = new RadioButton();
rbPaymentForSelf.Text = "myself";
rbPaymentForSelf.ID = "rbPaymentForSelf";
rbPaymentForSelf.GroupName = "SelfOfSomeoneElse";
this.Controls.Add(rbPaymentForSelf);
String checkboxPaymentForSomeoneElseText = "someone else";
rbPaymentForSomeoneElse = new RadioButton();
rbPaymentForSomeoneElse.Text = checkboxPaymentForSomeoneElseText;
rbPaymentForSomeoneElse.ID = "rbPaymentForSomeoneElse";
rbPaymentForSomeoneElse.GroupName = "SelfOfSomeoneElse";
this.Controls.Add(rbPaymentForSomeoneElse);
...与此 jQuery 相关,然后行为:
/* If user selects "payment for self" (they are seeking payment for themselves, as opposed to someone else), omit (invisibilize) sections 2 and 3 on the form */
$(document).on("change", '[id$=rbPaymentForSelf]', function () {
if (this.checked) {
$('[id$=panelSection2]').slideUp();
$('[id$=panelSection3]').slideUp();
$('[id$=_MailStopRow]').slideDown();
$('[id$=_AddressRows]').slideUp();
}
});
/* If user selects "payment for someone else" (they are seeking payment for someone else, as opposed to themselves), make sections 2 and 3 on the form visible */
$(document).on("change", '[id$=rbPaymentForSomeoneElse]', function () {
if (this.checked) {
$('[id$=panelSection2]').slideDown();
$('[id$=panelSection3]').slideDown();
$('[id$=_MailStopRow]').slideUp();
$('[id$=_AddressRows]').slideDown();
}
});
但是,如果用户选择 "someone else" 应该显示的部分不会在用户(现在是我)第一次选择 "someone else" 单选按钮时不显示 - 随后,它确实有效,虽然...
虽然这很优雅,但您会遇到一个问题,因为更改事件会同时触发。这将是笛卡尔积,因为两者将开始 war。该代码将永远改变另一个的状态,或者至少会导致不需要的结果。使用点击将是一个更好的解决方案。
$(document).on("change", '#ckbxPaymentForSelf', function () {
$('#ckbxPaymentForSomeoneElse').prop('checked', !this.checked);
});
$(document).on("change", '#ckbxPaymentForSomeoneElse', function () {
$('#ckbxPaymentForSelf').prop('checked', !this.checked);
});
我建议如下。 注意标签和使用 class 与 id 来分配事件处理程序:
$(document).on("click", '.ckbxPaymentForSelf', function () {
$('#ckbxPaymentForSomeoneElse').prop('checked', !this.checked);
});
$(document).on("click", '.ckbxPaymentForSomeoneElse', function () {
$('#ckbxPaymentForSelf').prop('checked', !this.checked);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="ckbxPaymentForSelf" class="ckbxPaymentForSelf" type="checkbox" checked/>
<label class="ckbxPaymentForSelf" for="ckbxPaymentForSelf">Payment For Self</label></br>
<input id="ckbxPaymentForSomeoneElse" class="ckbxPaymentForSomeoneElse" type="checkbox" />
<label class="ckbxPaymentForSomeoneElse" for="ckbxPaymentForSomeoneElse">Payment For Someone Else</label></br>
注意: 创建控件服务器端时,您可能需要设置
ClientIdMode="Static"
或这样编写脚本:
$('#<%= ckbxPaymentForSomeoneElse.ClientID %>').prop('checked', !this.checked);
在脚本中确保引用了您的控件
这可以用于您项目中的每个实例,您永远不必担心将逻辑混合到您希望定位的每个选择器中。超级可重复使用!
由于点击事件发生在客户端,这里有一些 jQuery 可以满足您的要求:
$.fn.dependantCheckbox = function() {
"use strict";
var $targ = $(this);
function syncSelection(group, action) {
$targ.each(function() {
if ($(this).data('checkbox-group') === group) {
$(this).prop('checked', action);
}
});
};
$('input[type="checkbox"][data-checkbox-group]').on('change', function() {
var groupSelection = $(this).data('checkbox-group');
var isChecked = $(this).prop('checked');
syncSelection(groupSelection, isChecked);
});
}
$('input[type="checkbox"][data-checkbox-group]').dependantCheckbox();
我相信使用客户端 MVC 框架是一个更优雅的解决方案。
例如,在AngularJs中,您可以将视图(两个复选框)绑定到模型,每次更改模型时,框架都会更新视图。
另外,我相信你也可以在服务器端使用observationCollection来做同样的事情(https://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx)。
我可以使用 javascript 实现如下:
<body>
<input type="checkbox" id="one" name="one" onchange="check1()"/>
<input type="checkbox" id="two" name="two" onchange="check2()"/>
<script>
function check1()
{
if(one.checked)
{
document.getElementById("two").checked = false;
}
else
{
document.getElementById("two").checked = true;
}
}
function check2()
{
if(two.checked)
{
document.getElementById("one").checked = false;
}
else
{
document.getElementById("one").checked = true;
}
}
</script>
</body>
我有两个互斥的复选框;既然如此,我希望每个人在进行更改时自动反映另一个人的相反状态:如果选中了 checkboxA,那么 checkboxB 应该是,如果选中,未选中(等等,我相信你知道我均值)。
我正在我的代码隐藏中创建复选框,如下所示:
ckbxPaymentForSelf = new CheckBox();
ckbxPaymentForSelf.Text = "myself";
ckbxPaymentForSelf.ID = "ckbxPaymentForSelf";
this.Controls.Add(ckbxPaymentForSelf);
ckbxPaymentForSomeoneElse = new CheckBox();
ckbxPaymentForSomeoneElse.Text = "someone else";
ckbxPaymentForSomeoneElse.ID = "ckbxPaymentForSomeoneElse";
this.Controls.Add(ckbxPaymentForSomeoneElse);
基于 this,我想也许我可以使用复选框的 Name 属性 并将它们设置为相同的值,例如 "ckbxsSelfOrSomeoneElse" 但是 没有 "Name" 属性 复选框可供我使用。
我可以这样写一些jQuery(伪脚本):
$(document).on("change", '[id$=ckbxPaymentForSelf]', function () {
var ckd = this.checked;
if (ckd) // check ckbxPaymentForSomeoneElse and uncheck if it it's checked
else // check ckbxPaymentForSomeoneElse and check if it it's unchecked
});
$(document).on("change", '[id$=ckbxPaymentForSomeoneElse]', function () {
var ckd = this.checked;
if (ckd) // check ckbxPaymentForSelf and uncheck if it it's checked
else // check ckbxPaymentForSelf and check if it it's unchecked
});
...但我想知道是否有更明显或更优雅的解决方案,因为这无疑是一个普遍的要求。
更新
我试过答案:
$(document).on("click", '[id$=ckbxPaymentForSelf]', function () {
alert('reached onclick for ckbxpaymentforself');
$('#ckbxPaymentForSomeoneElse').prop('checked', !this.checked);
});
$(document).on("click", '[id$=ckbxPaymentForSomeoneElse]', function () {
alert('reached onclick for ckbxpaymentforsomeoneelse');
$('#ckbxPaymentForSelf').prop('checked', !this.checked);
});
...但是,不合逻辑(在我看来,显然在他看来),这是行不通的。 strange/suspicious 是警报消息显示了两次!我必须点击它们两次才能关闭它们。为什么会这样,会不会是 the/a 问题?我确实注意到 jQuery 在 "View Source" 中出现了两次,当然,它在实际源代码中只出现在一个地方(在 .asxc 文件的底部)。
更新 2
正如 wilusdaman 所建议的(让它成为一个答案,Wilus,我会接受它),最优雅的方法是改用单选按钮。只需要这个:
rbPaymentForSelf = new RadioButton();
rbPaymentForSelf.Text = "myself";
rbPaymentForSelf.ID = "rbPaymentForSelf";
rbPaymentForSelf.GroupName = "SelfOfSomeoneElse";
this.Controls.Add(rbPaymentForSelf);
String checkboxPaymentForSomeoneElseText = "someone else";
rbPaymentForSomeoneElse = new RadioButton();
rbPaymentForSomeoneElse.Text = checkboxPaymentForSomeoneElseText;
rbPaymentForSomeoneElse.ID = "rbPaymentForSomeoneElse";
rbPaymentForSomeoneElse.GroupName = "SelfOfSomeoneElse";
this.Controls.Add(rbPaymentForSomeoneElse);
...与此 jQuery 相关,然后行为:
/* If user selects "payment for self" (they are seeking payment for themselves, as opposed to someone else), omit (invisibilize) sections 2 and 3 on the form */
$(document).on("change", '[id$=rbPaymentForSelf]', function () {
if (this.checked) {
$('[id$=panelSection2]').slideUp();
$('[id$=panelSection3]').slideUp();
$('[id$=_MailStopRow]').slideDown();
$('[id$=_AddressRows]').slideUp();
}
});
/* If user selects "payment for someone else" (they are seeking payment for someone else, as opposed to themselves), make sections 2 and 3 on the form visible */
$(document).on("change", '[id$=rbPaymentForSomeoneElse]', function () {
if (this.checked) {
$('[id$=panelSection2]').slideDown();
$('[id$=panelSection3]').slideDown();
$('[id$=_MailStopRow]').slideUp();
$('[id$=_AddressRows]').slideDown();
}
});
但是,如果用户选择 "someone else" 应该显示的部分不会在用户(现在是我)第一次选择 "someone else" 单选按钮时不显示 - 随后,它确实有效,虽然...
虽然这很优雅,但您会遇到一个问题,因为更改事件会同时触发。这将是笛卡尔积,因为两者将开始 war。该代码将永远改变另一个的状态,或者至少会导致不需要的结果。使用点击将是一个更好的解决方案。
$(document).on("change", '#ckbxPaymentForSelf', function () {
$('#ckbxPaymentForSomeoneElse').prop('checked', !this.checked);
});
$(document).on("change", '#ckbxPaymentForSomeoneElse', function () {
$('#ckbxPaymentForSelf').prop('checked', !this.checked);
});
我建议如下。 注意标签和使用 class 与 id 来分配事件处理程序:
$(document).on("click", '.ckbxPaymentForSelf', function () {
$('#ckbxPaymentForSomeoneElse').prop('checked', !this.checked);
});
$(document).on("click", '.ckbxPaymentForSomeoneElse', function () {
$('#ckbxPaymentForSelf').prop('checked', !this.checked);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="ckbxPaymentForSelf" class="ckbxPaymentForSelf" type="checkbox" checked/>
<label class="ckbxPaymentForSelf" for="ckbxPaymentForSelf">Payment For Self</label></br>
<input id="ckbxPaymentForSomeoneElse" class="ckbxPaymentForSomeoneElse" type="checkbox" />
<label class="ckbxPaymentForSomeoneElse" for="ckbxPaymentForSomeoneElse">Payment For Someone Else</label></br>
注意: 创建控件服务器端时,您可能需要设置
ClientIdMode="Static"
或这样编写脚本:
$('#<%= ckbxPaymentForSomeoneElse.ClientID %>').prop('checked', !this.checked);
在脚本中确保引用了您的控件
这可以用于您项目中的每个实例,您永远不必担心将逻辑混合到您希望定位的每个选择器中。超级可重复使用!
由于点击事件发生在客户端,这里有一些 jQuery 可以满足您的要求:
$.fn.dependantCheckbox = function() {
"use strict";
var $targ = $(this);
function syncSelection(group, action) {
$targ.each(function() {
if ($(this).data('checkbox-group') === group) {
$(this).prop('checked', action);
}
});
};
$('input[type="checkbox"][data-checkbox-group]').on('change', function() {
var groupSelection = $(this).data('checkbox-group');
var isChecked = $(this).prop('checked');
syncSelection(groupSelection, isChecked);
});
}
$('input[type="checkbox"][data-checkbox-group]').dependantCheckbox();
我相信使用客户端 MVC 框架是一个更优雅的解决方案。
例如,在AngularJs中,您可以将视图(两个复选框)绑定到模型,每次更改模型时,框架都会更新视图。
另外,我相信你也可以在服务器端使用observationCollection来做同样的事情(https://msdn.microsoft.com/en-us/library/ms668604(v=vs.110).aspx)。
我可以使用 javascript 实现如下:
<body>
<input type="checkbox" id="one" name="one" onchange="check1()"/>
<input type="checkbox" id="two" name="two" onchange="check2()"/>
<script>
function check1()
{
if(one.checked)
{
document.getElementById("two").checked = false;
}
else
{
document.getElementById("two").checked = true;
}
}
function check2()
{
if(two.checked)
{
document.getElementById("one").checked = false;
}
else
{
document.getElementById("one").checked = true;
}
}
</script>
</body>