我怎样才能优雅地让两个 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();

http://codepen.io/nicholasabrams/pen/mJqyqG

我相信使用客户端 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>