使用btn-group时,未正确发送单选按钮值

时间:2014-08-22 13:12:20

标签: jquery twitter-bootstrap radio-button

当我使用btn-group和最新的Twitter Bootstrap显示花哨的单选按钮时,提交的值始终与屏幕上标记的值相同。问题是浏览器将框标记为已选中(它添加了active类),但实际元素仍未选中。

在Firefox和Chrome中都会出现此问题。它并不总是发生,但它发生在大约7%的时间(测试150次)。我点击一堆按钮来标记所有分数为5的元素,它将如下所示:

All marked with score 5

但是当我提交并显示结果时,你会发现它不会发送相同的结果!

Array with results, not the same

这种行为不稳定且不可预测,增加了我的困惑,但它 可重现,它不会一直发生。要查看,请尝试以下两种方法之一。 KyleMit非常友好,可以将其变成jsfiddle。请尝试一下。提交表单大约30次(每次提交时更改值),您将遇到错误。我在下面显示截图。

第二个选项是运行下面有更多输入字段的代码。更改所有字段,它们不会相同。大约6次尝试后将出现错误。

<?php
if ($_POST) {
  var_dump($_POST['quality']);
}
?>
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
    <title>Test</title>
    <style type="text/css">
        .btn { opacity:1 }
    </style>
  </head>
  <body>
    <div class="row">
      <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
        <form method="post" class="form form-horizontal">
          <fieldset>
            <legend>Quality</legend>
            <div class="row">
              <div class="col-sm-3">Test 1</div>
              <div class="col-sm-9">
                <div class="btn-group" data-toggle="buttons">
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q156" name="quality[25]" value="1" /> 1
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q157" name="quality[25]" value="2" /> 2
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q158" name="quality[25]" value="3" /> 3
                    </label> 
                    <label class="tooltip btn btn-default">
                    <input type="radio" id="q159" name="quality[25]" value="4" /> 4
                        </label> 
                    <label class="tooltip btn btn-default active">
                        <input type="radio" id="q160" name="quality[25]" checked="checked" value="5" /> 5
                    </label>
                </div>
              </div>
            </div>
            <div class="row">
              <div class="col-sm-3">Test 2</div>
              <div class="col-sm-9">
                <div class="btn-group" data-toggle="buttons">
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q128" name="quality[21]" value="1" /> 1
                    </label> 
                    <label class="tooltip btn btn-default active">
                        <input type="radio" id="q129" name="quality[21]" checked="checked" value="2" /> 2
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q130" name="quality[21]" value="3" /> 3
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q131" name="quality[21]" value="4" /> 4
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q132" name="quality[21]" value="5" /> 5
                    </label>
                </div>
              </div>
            </div>
            <div class="row">
              <div class="col-sm-3">Test 3</div>
              <div class="col-sm-9">
                <div class="btn-group" data-toggle="buttons">
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q149" name="quality[24]" value="1" /> 1
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q150" name="quality[24]" value="2" /> 2
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q151" name="quality[24]" value="3" /> 3
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q152" name="quality[24]" value="4" /> 4
                    </label> 
                    <label class="tooltip btn btn-default active">
                        <input type="radio" id="q153" name="quality[24]" checked="checked" value="5" /> 5
                    </label>
                </div>
              </div>
            </div>
            <div class="row">
              <div class="col-sm-3">Test 4</div>
              <div class="col-sm-9">
                <div class="btn-group" data-toggle="buttons">
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q142" name="quality[23]" value="1" /> 1
                    </label> 
                    <label class="tooltip btn btn-default active">
                        <input type="radio" id="q143" name="quality[23]" checked="checked" value="2" /> 2
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q144" name="quality[23]" value="3" /> 3
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q145" name="quality[23]" value="4" /> 4
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q146" name="quality[23]" value="5" /> 5
                    </label>
                </div>
              </div>
            </div>
            <div class="row">
              <div class="col-sm-3">Test 5</div>
              <div class="col-sm-9">
                <div class="btn-group" data-toggle="buttons">
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q121" name="quality[20]" value="1" /> 1
                    </label> 
                    <label class="tooltip btn btn-default active">
                        <input type="radio" id="q122" name="quality[20]" checked="checked" value="2" /> 2
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q123" name="quality[20]" value="3" /> 3
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q124" name="quality[20]" value="4" /> 4
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q125" name="quality[20]" value="5" /> 5
                    </label>
                </div>
              </div>
            </div>
            <div class="row">
              <div class="col-sm-3">Test 6</div>
              <div class="col-sm-9">
                <div class="btn-group" data-toggle="buttons">
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q135" name="quality[22]" value="1" /> 1
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q136" name="quality[22]" value="2" /> 2
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q137" name="quality[22]" value="3" /> 3
                    </label> 
                    <label class="tooltip btn btn-default">
                        <input type="radio" id="q138" name="quality[22]" value="4" /> 4
                    </label> 
                    <label class="tooltip btn btn-default active">
                        <input type="radio" id="q139" name="quality[22]" checked="checked" value="5" /> 5
                    </label>
                </div>
              </div>
            </div>
          </fieldset>
          <button type="submit" class="btn btn-primary">Save</button>
        </form>
      </div>
    </div>
  </body>
</html>

小提琴结果:

Submit value 5, received differently

1 个答案:

答案 0 :(得分:11)

Solved!解决方案:

[data-toggle="buttons"] > .btn > input[type="radio"],
[data-toggle="buttons"] > .btn > input[type="checkbox"] {
    visibility: hidden;
}

事实证明,只有当您点击按钮的某个区域时才会发生这种情况。即使它是不可见的,实际单选按钮的一小部分是可点击的(仅在数字的右侧),当你点击它时,Bootstrap javascript阻止它改变其检查状态但是javascript继续并添加了活动类。我注意到了这一点,因为当你徘徊在可点击的小型单选按钮区域时,鼠标指针从指针变为默认光标。

虽然我无法想到,但我的解决方案可能会产生负面影响。我不确定Bootstrap选择opacity: 0;超过visibility: hidden;背后的原因,但也许更有知识的人可能会提供一些。

<强>更新

在进行了一些挖掘之后,我发现了为什么他们使用不透明度而不是可见性。

  

为了支持浏览器的表单验证反馈,由required属性提供支持,我们必须隐藏&#34;通过opacity输入。我们无法使用display: none;visibility: hidden;,因为它也隐藏了弹出窗口。这样,我们确保可以看到DOM元素来定位弹出窗口。

     

有关详情,请参阅https://github.com/twbs/bootstrap/pull/12794

如果您希望能够使用本机浏览器验证,那么您几乎无法使用visibility: hidden;

它实际上似乎是一个已知的错误,请参阅此Github issue

更新2

This solution可能更好:

[data-toggle="buttons"] > .btn > input[type="radio"],
[data-toggle="buttons"] > .btn > input[type="checkbox"] {
    width: 1px;
}

this solution可能会更好:

[data-toggle="buttons"] > .btn:after,
[data-toggle="buttons"] > .btn:after {
    content: "";
    display: block;
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
}

更新3

this可能是现在最好的解决方案。正如海因里希·芬卡特所建议的那样here

[data-toggle="buttons"] > .btn > input[type="radio"],
[data-toggle="buttons"] > .btn > input[type="checkbox"] {
    clip: rect(1px, 1px, 1px, 1px);
    pointer-events: none;
}

看起来Bootstrap可能会在下一个版本中修复此问题。