如何使用Bootstrap 4创建三态复选框按钮

4

我正在创建一个筛选表单,我想过滤掉具有属性 high=true、high=false 或忽略该属性的对象。
到目前为止,我得到的只是值“on”。
另外,在第三个值(null 或其他)上,我希望样式与其他不同,比如禁用。
有人知道一个简单的方法来做到这一点吗?

function readValue() {
  var highValue = $('#high').val();
  $('#result').html(highValue);
  if (highValue === null) {
    //don't filter
  } else {
    //filter
  }
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">

<div class="btn-group-toggle" data-toggle="buttons">
  <label onclick="readValue()" class="btn btn-secondary active">
    <input id="high" type="checkbox" checked autocomplete="off"> High
  </label>
</div>
Result:<div id='result'></div>

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>

4个回答

3
我想出了一种方法,可以通过一个按钮来切换任意数量的状态,同时按钮会显示当前状态。这正是我在寻找的 - 大部分代码来自于网络上不同的部分,我很自豪地将它们组合在一起!
如果您有建议使其更加简短易读,请评论或直接编辑 :)

var $radios = $('input[type="radio"][name="high"]');
$('#result').html($radios.filter(':checked').val());

$('#toggler').click(function() {
  var colorClasses = ["btn-danger", "btn-success", "btn-secondary"];
  var $checked = $radios.filter(':checked');
  var $next = $radios.eq($radios.index($checked) + 1);
  if (!$next.length) {
    $next = $radios.first();
  }
  $next.prop("checked", true);
  var newValue = $radios.filter(':checked').val();
  $(this)
    .removeClass(colorClasses.join(" "))
    .addClass(colorClasses[newValue]);
  $('#result').html(newValue);
});
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">

<div class="btn-group-toggle" data-toggle="buttons">
  <input type="radio" name="high" value="2" checked hidden>
  <input type="radio" name="high" value="1" hidden>
  <input type="radio" name="high" value="0" hidden>
  <button type="button" id="toggler" class="btn btn-secondary">High</button>
</div>
Result:
<div id='result'></div>

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>


2

类似的问题已经被问过了,一些人建议使用:indeterminate伪类来表示NULL状态——在该过滤器属性被忽略时。

什么是:indeterminate?

Bootstrap 4自定义复选框仅在通过JavaScript手动设置时才使用:indeterminate伪类:http://getbootstrap.com/docs/4.1/components/forms/#custom-forms

:indeterminate还很新,不是所有浏览器都能正确渲染它,所以我建议采用更简单的方法:

  • 在筛选属性旁边放置一个复选框,表示是否需要按该属性进行筛选
  • 使用复选框或单选按钮表示true/yesfalse/no状态。

页面加载时

筛选器未选择,并且其可用值已隐藏。

enter image description here

筛选器已选中/启用

如果已选择筛选器,则会显示其可用值。

enter image description here

提交时

在表单提交时,您可以始终传递两个值:

  • 过滤属性是否启用,即$().is(":checked")
  • 过滤属性值,即yes/no

Fiddle: http://jsfiddle.net/aq9Laaew/72593/

jQuery插件

一个用于可空复选框的插件:http://vanderlee.github.io/tristate/


谢谢,我觉得你的回答提供了一些非常有用的信息,+1,- 但是在这种情况下,我希望回答我的具体问题,而不是提供替代方案。而且我不知道如何在我的代码示例中轻松地使用那个 :indeterminate 类来达到我的目标。 - Cold_Class
看到我的更新。:indeterminate 可以用来表示空状态,但它本身相当新,所以并不是所有的浏览器都以相同的方式渲染它。这就是为什么我选择了“正常”的方式来做的原因。 - David Liang

0

我喜欢Cold_Class的答案,但我需要更通用的东西。在那个答案的基础上,我做了这个。

Javascript:

function onTogglerClick(el) {
    // Get the radios that are children of the parent div element
    let $radios = $(el).children('input[type="radio"]');

    // Use the radio button vals to determine the array, note that the values are also the same as the class names
    let valsClasses = $radios.map(function () {
        return $(this).val();
    }).toArray();

    // Advance to the next radio button
    let $checked = $radios.filter(':checked');
    let $next = $radios.eq($radios.index($checked) + 1);
    if ($next.val() === undefined) {
        $next = $radios.first();
    }
    $next.prop("checked", true);

    // change the class of the parent element
    let newValue = $radios.filter(':checked').val();
    $(el)
        .removeClass(valsClasses.join(" "))
        .addClass(newValue);
}

CSS

/* 单选框的样式 */

.unchecked:before {
    font-family: "Font Awesome 5 Free";
    font-weight: 200;
    content: "\f0c8";
    width: 24px;
    height: 24px;
}


.checked:before {
    font-family: "Font Awesome 5 Free";
    font-weight: 200;
    content: "\f14a";
    width: 24px;
    height: 24px;
}

.musthave:before {
    font-family: "Font Awesome 5 Free";
    font-weight: 200;
    content: "\f0fe";
    width: 24px;
    height: 24px;
}

.mustnothave:before {
    font-family: "Font Awesome 5 Free";
    font-weight: 200;
    content: "\f146";
    width: 24px;
    height: 24px;
}

Html:

<ul>
@foreach (var tag in Model.Tags)
{
<li>
    <div class="btn-group-toggle toggler unchecked" data-toggle="buttons" onclick="onTogglerClick(this)">
        <input type="radio" name="@tag" value="unchecked" checked hidden>
        <input type="radio" name="@tag" value="checked" hidden>
        <input type="radio" name="@tag" value="musthave" hidden>
        <input type="radio" name="@tag" value="mustnothave" hidden>
        <label>@tag </label>
    </div>
</li>
}

0
试试这个方法:这个按钮组是Bootstrap UI的带有标签的单选输入。我没有时间或兴趣美化这些单选按钮。
<script type="text/javascript">
    function renderRadioOptions() {
        var radioGroupOpacity = ( $(this).val() == '' ) ? 0.5 : 1.0;
        $("div#filter_options_group > label.btn").css('opacity', radioGroupOpacity);
    }

    $(function() {
        $("div#filter_options_group > label.btn").css('opacity', 0.5);
        $("input[name='options']").on('change', renderRadioOptions );
    });

</script>

<div class="btn-group btn-group-toggle" data-toggle="buttons" id="filter_options_group">
    <label class="btn btn-secondary active">
        <input type="radio" name="options" value="" id="option1" autocomplete="off" checked> 
        <i class="glyphicon glyphicon-remove">
    </label>
    <label class="btn btn-secondary">
        <input type="radio" name="options" value="low" id="option2" autocomplete="off"> Low
    </label>
    <label class="btn btn-secondary">
        <input type="radio" name="options" value="high" id="option3" autocomplete="off"> High
    </label>
</div>

但这是3个按钮,我只要一个按钮。 - Cold_Class

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