Bootstrap-select下拉多选框+选中项添加radio单选按钮组

目录

一、问题描述

工作中遇到的需求,需要将下拉单选框改成下拉多选框,因此使用Bootstrap-select插件完成。这个下拉单选框可以通过按钮切换为输入框,选中项或输入项都添加为radio单选按钮。过程中遇到了以下问题。

  1. Bootstrap-select显示出错,总是显示两个下拉多选框
  2. Bootstrap-select宽度width问题
  3. radio单选按钮组去重

二、具体实现

1. 下载Bootstrap-select及汉化插件并引入

引入:

<link href="static/bootstrap4/css/bootstrap.css" rel="stylesheet" type="text/css">
<link href="static/bootstrap4/css/bootstrap-select.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="static/bootstrap4/js/bootstrap.min.js"></script>
<script type="text/javascript" src="static/bootstrap4/js/bootstrap-select.min.js"></script>
<script type="text/javascript" src="static/bootstrap4/js/defaults-zh_CN.js"></script>

2. bootstrap-select下拉多选实现

HTML

主要是在select标签加上class="selectpicker"multiple

<div class="row" id="answer_part_div">
	<div class="col-sm-10" id="answer_select_div">
        <label for="answer_select"></label>
        <select class="selectpicker" multiple required id="answer_select">
            <option value="" hidden>请选择候选项</option>
        </select>
    </div>
    <div class="col-sm-10" id="answer_input_div" style="display: none">
        <input type="text" name="answer" class="form-control" placeholder="请输入候选项" required>
    </div>
    <div class="col-sm-2 m-auto">
        <button class="btn btn-sm btn-primary" id="answer_toggle_btn" title="切换输入">
            <i class="fas fa-keyboard"></i>
        </button>
        <button class="btn btn-sm btn-success" id="answer_confirm_btn" title="确认添加">
            <i class="fas fa-check"></i>
        </button>
        <button class="btn btn-sm btn-danger" title="删除选项" id="answer_del_btn">
           <i class="fas fa-minus"></i>
        </button>
   </div>
</div>
<div id="answer_list_div" class="col-sm-12 mt-5"></div>

JS

  1. 解决显示出两个多选框的问题

由于这里是一个类似问卷出题的系统,每个问题+选项div是一个模板,出题者每次点击添加问题按钮,就会复制一份这个div模板。可能是复制的时候使用bootstrap-select这个插件有问题,就会在answer_select_div这个div下显示出两个bootstrap-select下拉框。解决方法是在每次添加问题之后先清除answer_select_div的内容,然后再次添加这个下拉多选框。(也就是之前在HTML文件写的answer_select_div内的内容是无效的,直接在JS插入了这个HTML内容)

// 这里使用了bootstrap-select,显示上稍微有点问题,需要先清空answer_select_div,再插入answer_select
var answer_select_div = $("#answer_select_div");
answer_select_div.empty();
// 插入answer_select
var answer_select = $("<select class='selectpicker' multiple required id='answer_select' data-width='100%'></select>");
answer_select_div.append(answer_select);
// 获取answer_select
var select = $(".selectpicker");
// 插入选项,这里是一个示例
select.append("<option value='' hidden>请选择候选项</option>");
//使用refresh方法更新UI以匹配新状态。
select.selectpicker('refresh');
//render方法强制重新渲染引导程序 - 选择ui。
select.selectpicker('render');

注意一定要调用select.selectpicker(‘refresh’)和select.selectpicker(‘render’),否则将UI无法更新。

  1. 解决该下拉复选框的宽度width问题

问题:在css中设置如下内容,在选中项过多时,会造成布局溢出。

/*调整下拉复选框的宽度*/
.bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) {
    width: 100%;
}

解决:查阅bootstrap-select的文档,使用data-width属性来定义宽度,可选的值有以下4个。

  • auto:select的宽度由option中内容宽度最宽的哪个决定;
  • fit:select的宽度由实际选中的option的宽度决定;
  • 100px:select的宽度定义为100px;
  • 50%:select的宽度设置为父容器宽度的50%。
  1. 选中项或输入框输入项插入为radio单选按钮组
$(document).on("click", "#answer_confirm_btn", function () {
    var cur_div = $(this).parents("#a_div");
    var err_msg = "";
    var unique_id = cur_div.parents(".qa_div").attr("id");

    // 判断输入框是否可见
    var input_visible = cur_div.find("#answer_input_div").is(":visible");
    // 插入输入的选项
    if (input_visible) {
        // 获取输入的内容
        var input_val = cur_div.find("input[name='answer']").val();

        // 输入内容判断
        if (input_val === "") {
            err_msg = "选项内容不能为空";
        }
        $.each(cur_div.find("#answer_list_div label"), function (i, obj) {
            if (input_val === obj.textContent) {
                err_msg = "选项已存在";
            }
        });
        if (err_msg) {
            show_toast(err_msg);
            // 清空候选项内容
            cur_div.find("input[name='answer']").val("");
            return;
        }

        // 插入选项
        insertRadio(cur_div, unique_id, input_val);

        // 清空已提交的候选项内容
        cur_div.find("input[name='answer']").val("");
    }
    // 改变多选的选项
    else {
        // 获取多选数组
        var select_val = cur_div.find("#answer_select").val();
        // 删除数组中第一个空值
        if (select_val.length && select_val[0] === "") {
            select_val.shift();
        }
        // 选项内容判断
        if (select_val.length === 0) {
            err_msg = "选项内容不能为空";
        }
        if (err_msg) {
            show_toast(err_msg);
            return;
        }

        // 遍历数组,插入选项
        select_val.forEach(function (val) {
            insertRadio(cur_div, unique_id, val);
        });
    }
});
// 插入选项
function insertRadio(cur_div, unique_id, val) {
    // 去重
    var isExisted = false;
    var answer_list = cur_div.find(".custom-radio input");
    // 遍历radio
    if(answer_list) {
        $.each(answer_list, function (i, answer) {
            if(answer && $(answer).val() === val) {
                isExisted = true;
            }
        })
    }
    // 如果已经存在,就不插入了
    if(!isExisted) {
        // 新建radio
        var radio_id = unique_id + "_" + val;
        var new_radio = $("<div class='custom-control custom-radio'>" + "<input type='radio' id='" + radio_id + "' value='" + val + "' name='" + unique_id + "' class='custom-control-input'>" + "<label class='custom-control-label' for='" + radio_id + "'>" + val + "</label>" + "</div>");
        cur_div.find("#answer_list_div").append(new_radio);
    }
}

本来实现的效果是:每次改变多选选项,清空answer_list_div,重新插入多选的选项,即cur_div.find("#answer_list_div").empty();再插入选项。但这样会导致在input框手动输入的radio选项丢失,因此还是采用了在insertRadio方法中判断是否重复后插入选项的方法。

三、参考博客

bootstrap下拉列表多选组件

bootstrap-select 的多选+模糊查询下拉框详解(官方示例文档解读)

BootStrap-select插件动态添加option无法显示

上一篇:Bootstrap(pink老师)


下一篇:Bootstrap多层表头及嵌套数据显示