Bootstrap selectpicker 下拉框多选获取选中value和多选获取文本值

本文介绍了如何在Bootstrap的selectpicker组件中实现多选功能,并展示了通过js代码获取选中项的value和文本值的方法。通过设置maxlength属性,可以限制最多选择的项目数量。

1.页面代码:

页面引入:

bootstrap-select.min.css和
bootstrap-select.min.js、
defaults-zh_CN.min.js文件,并初始化下拉选项框。
带有下拉搜索样式的下拉框属性:data-live-search="true"
下拉选项框可多选属性:multiple
<div class="col-xs-6 col-sm-6 col-md-4 col-lg-4 clearfix ">
    <label class="col-xs-4 col-sm-4 control-label required">车班名称:</label>
    <div class="col-xs-8 col-sm-8">
        <div class="input-group">
            <select name="shuttleBusId" class="form-control select-picker" data-live-search="true" multiple>
                <option value="">-- 请选择 --</option>
                <option th:each="iterator : ${vehicleShiftList}"
                        th:value="${iterator.idTrafficVehicleShift}"
                        th:text="${iterator.vehicleShiftName}">
                </option>
            </select>
        </div>
    </div>
</div>

2.js代码// select 多选可以设置做多选中项,使用maxlength

// js代码如下:
// 获取到下拉框说所有选中项
var checkParam = $('#type-select').find('option:selected');
// 选中的ID集合
var checkId = [];
// 选中的文本值集合
var checkText = [];
for (var i=0;i<checkParam.length;i++) {
    checkId.push(checkParam[i].value);
}
for (var i=0;i<checkParam.length;i++) {
    checkText.push(checkParam[i].textContent);
}
// 数组转字符串
var ids = checkId.join(',');
var text = checkText.join(',');
// 1.定义对象,并设置属性名和值---------------------------------------------
// 判断是否选中
if (checkParam.length > 0) {
   var hilidayFlag = 1;
    // 定义传入参数对象,并赋值
    var params = {
        holidayFlag: holidayFlag,
        shuttleBusId: ids,
     shuttleBusName: text
    }
}

// 2.定义对象,并设置属性名和值---------------------------------------------

// 获取表单值
var user= {};
// 获取到页面表单中所有值 name-value形式
var formData = $('#addForm').serializeArray();
formData.forEach(function (item) {
    user[item.name] = item.value;
})

ps:将获取表单结果数组转成对象

 

 

<think>我们正在处理一个关于bootstrap-select的问题,用户希望在使用bootstrap-select时实现项去重的功能。 根据引用[1]中提到的内容,用户之前使用bootstrap-select插件将下拉单框改为下拉框,并且选中项会添加为radio单按钮组。在这个过程中遇到了去重问题。 我们需要实现的是:当用户项时,如果有重复的项,需要去重。 思路: 1. 在用户项时,我们可以监听bootstrap-select的changed事件。 2. 在事件处理函数中,获取当前选中,然后进行去重处理。 3. 将去重后的重新设置回bootstrap-select。 但是需要注意的是,bootstrap-select本身不提供去重功能,因此我们需要在事件中手动处理。 另外,引用[1]中提到了“radio单按钮组去重”,所以可能是在添加为radio按钮组时也需要去重,但用户现在的问题是在bootstrap-select中项去重,所以重点在下拉框的去重。 具体步骤: 1. 给bootstrap-select绑定change事件。 2. 在事件中,获取当前选中数组。 3. 使用数组去重(例如使用Set)。 4. 将去重后的数组重新设置为bootstrap-select的选中。 但是注意:直接设置选中可能会触发change事件,导致死循环。因此,在设置之前先解除事件绑定,设置完后再重新绑定,或者使用一个标志位避免递归。 然而,bootstrap-select提供了refresh方法,我们在设置后需要刷新。 代码示例: 假设我们有一个select元素,id为"mySelect",我们将其初始化为bootstrap-select框。 去重逻辑可以这样写: ```javascript $('#mySelect').on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) { // 获取当前选中的所有 var selectedValues = $(this).val(); if (selectedValues) { // 去重 var uniqueValues = [...new Set(selectedValues)]; // 比较去重前后是否有变化 if (uniqueValues.length !== selectedValues.length) { // 解除事件绑定,避免递归触发 $(this).off('changed.bs.select'); // 重新设置选中(去重后的数组) $(this).val(uniqueValues); // 刷新bootstrap-select $(this).selectpicker('refresh'); // 重新绑定事件 $(this).on('changed.bs.select', arguments.callee); } } }); ``` 注意:上面的arguments.callee在严格模式下不可用,我们可以使用命名函数来避免。 改进版(使用命名函数): ```javascript function handleSelectChange(e, clickedIndex, isSelected, previousValue) { var $select = $(this); var selectedValues = $select.val(); if (selectedValues) { var uniqueValues = [...new Set(selectedValues)]; if (uniqueValues.length !== selectedValues.length) { $select.off('changed.bs.select', handleSelectChange); $select.val(uniqueValues); $select.selectpicker('refresh'); $select.on('changed.bs.select', handleSelectChange); } } } $('#mySelect').on('changed.bs.select', handleSelectChange); ``` 但是,这种方法在去重后重新绑定事件,可能会丢失事件处理函数中的其他逻辑。如果还有其他事件处理函数,需要一并考虑。 另外,我们也可以考虑在设置前先标记一个变量,避免进入循环: ```javascript var inProcess = false; $('#mySelect').on('changed.bs.select', function () { if (inProcess) return; var $select = $(this); var selectedValues = $select.val(); if (selectedValues) { var uniqueValues = [...new Set(selectedValues)]; if (uniqueValues.length !== selectedValues.length) { inProcess = true; $select.val(uniqueValues); $select.selectpicker('refresh'); inProcess = false; } } }); ``` 这种方法更简单,但需要注意,在刷新过程中,change事件可能再次被触发,但由于inProcess标志,我们避免了再次进入。 然而,bootstrap-select的refresh方法可能会触发change事件,所以使用标志位可以防止递归。 因此,我们推荐使用标志位的方法。 但是,用户的需求是“项去重”,即防止用户择重复的项。我们通过去重保证了选中都是唯一的。 另外,如果用户需要从源头上防止择重复的项(即在择时如果已经选中,则不允许再次择),那么我们可以通过禁用已选中项来实现?但这样可能会影响的功能,因为通常允许重复择(比如取消选中)。所以,去重是在选中后进行的。 综上所述,我们使用标志位的方法实现去重。 代码示例: ```html <select id="mySelect" class="selectpicker" multiple> <option value="1">Option 1</option> <option value="2">Option 2</option> <option value="3">Option 3</option> </select> <script> $(document).ready(function(){ $('#mySelect').selectpicker(); var inProcess = false; $('#mySelect').on('changed.bs.select', function () { if (inProcess) return; var $select = $(this); var selectedValues = $select.val(); if (selectedValues) { // 将数组中的每个转换为字符串,因为有些可能是数字,而实际获取的是字符串 // 但注意:如果本来就是数字,那么可以直接使用,但为了保险,我们统一用字符串比较 var stringValues = selectedValues.map(String); var uniqueValues = [...new Set(stringValues)]; if (uniqueValues.length !== stringValues.length) { inProcess = true; // 设置去重后的(注意:这里设置的是去重后的数组,但数组元素是字符串,而原可能是数字,需要根据情况转换?) // 实际上,bootstrap-select内部使用字符串匹配,所以设置字符串数组是可以的。 $select.val(uniqueValues); $select.selectpicker('refresh'); inProcess = false; } } }); }); </script> ``` 注意:如果有数字字符串的混合,我们统一转换为字符串去重,避免数字1字符串'1'被认为是不同的。但这样也可能带来问题:如果用户希望区分1'1',那么就不应该转换。所以,这个要根据实际需求来。 如果用户需要严格区分类型,那么就不要转换,直接使用原去重。 因此,我们可以不转换,直接使用Set去重,因为Set认为1'1'是不同的。 所以,去掉转换步骤: ```javascript var uniqueValues = [...new Set(selectedValues)]; ``` 这样,只有完全相同的(包括类型)才会去重。但通常,都是字符串,所以问题不大。 如果有数字,那么selectedValues数组中的可能是字符串(因为jQuery的val()方法返回的是字符串数组)。所以,如果项的是数字,那么我们在HTML中应该写成字符串(如value="1"),这样获取到的就是字符串,去重也是按字符串去重。 因此,我们按照上面的代码即可。 另外,引用[1]中还提到了“选中项或输入项都添加为radio单按钮”,如果用户还需要在添加为radio按钮时去重,那么需要在添加radio按钮时也进行去重判断。但用户当前的问题只是bootstrap-select的项去重,所以我们先解决这个问题。 总结:通过监听change事件,在事件中获取当前选中,去重后重新设置并刷新,即可实现项去重。 但是,我们还需要注意性能问题,因为每次择都会触发这个事件,如果项很,去重操作很快,所以影响不大。 另外,如果用户通过其他方式改变选中(比如通过代码设置),也需要触发去重,所以事件监听是合适的。 最后,提供完整示例代码: 注意:需要引入jQuery, bootstrap, bootstrap-select的cssjs文件。 示例: ```html <!DOCTYPE html> <html> <head> <title>Bootstrap-select去重示例</title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.18/dist/css/bootstrap-select.min.css"> </head> <body> <select id="mySelect" class="selectpicker" multiple> <option value="1">Option 1</option> <option value="2">Option 2</option> <option value="3">Option 3</option> <option value="1">Option 1 (重复)</option> <option value="2">Option 2 (重复)</option> </select> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.13.18/dist/js/bootstrap-select.min.js"></script> <script> $(document).ready(function() { $('#mySelect').selectpicker(); var inProcess = false; $('#mySelect').on('changed.bs.select', function () { if (inProcess) return; var $select = $(this); var selectedValues = $select.val(); // 这是一个数组,包含当前选中 if (selectedValues && selectedValues.length > 0) { // 使用Set去重 var uniqueValues = [...new Set(selectedValues)]; if (uniqueValues.length !== selectedValues.length) { inProcess = true; // 设置去重后的 $select.val(uniqueValues); $select.selectpicker('refresh'); inProcess = false; } } }); }); </script> </body> </html> ``` 在这个示例中,我们故意添加了重复的项(value重复),然后通过择它们,会发现重复的value只会保留一个。 注意:这个去重是基于value的,而不是显示文本。如果两个项的value相同,那么它们被认为是重复的。 如果用户需要根据显示文本来去重,那么我们需要在事件中获取每个项的文本,然后根据文本去重。但是,bootstrap-select的val()方法只能获取,所以我们需要遍历项,然后根据选中获取文本,这样比较复杂。而且,通常去重都是根据value,因为value才是实际提交的。 因此,我们按value去重是合理的。 如果用户需要根据文本去重,那么我们可以这样: 1. 获取当前选中数组selectedValues。 2. 遍历这些获取每个对应的文本,然后根据文本去重,保留唯一文本对应的(注意:如果同一个文本对应,我们只能保留其中一个,这需要规则)。 3. 然后设置选中为去重后的。 但这种情况较为复杂,且不常见,所以这里不展开。 综上所述,我们提供了基于value的去重方法。 因此,回答用户的问题:可以通过监听change事件,在事件中获取选中数组,去重后重新设置并刷新,实现项去重。 相关问题: 根据用户的问题,我们可以生成以下相关问题: 1. 如何防止bootstrap-select择重复的项? 2. bootstrap-select如何根据文本去重? 3. 在bootstrap-select中,如何动态添加项并避免重复? 4. 如何在使用bootstrap-select时同时实现去重实时搜索? 但是,我们只回答当前问题,相关问题作为扩展。 因此,我们生成的相关问题如下: §§相关问题§§ 1. 如何根据文本(而不是)实现bootstrap-select的去重? 2. 如何在动态添加项到bootstrap-select时避免重复项? 3. 在bootstrap-select中,如何实现实时搜索同时支持去重? 4. 除了去重,bootstrap-select还有哪些常见问题及解决方法?</think>要在 Bootstrap-Select 中实现项去重功能,可以通过以下步骤实现: ### 解决方案(基于 JavaScript/jQuery) ```html <select id="mySelect" class="selectpicker" multiple> <!-- 初始项 --> <option value="1">Apple</option> <option value="2">Orange</option> </select> <script> $(document).ready(function() { // 初始化下拉框 $('#mySelect').selectpicker(); // 去重函数 function removeDuplicates() { const values = new Set(); $('#mySelect option').each(function() { const val = $(this).val(); // 发现重复时删除 if (values.has(val)) { $(this).remove(); } else { values.add(val); } }); // 刷新下拉框 $('#mySelect').selectpicker('refresh'); } // 监听择变化 $('#mySelect').on('changed.bs.select', function() { removeDuplicates(); }); }); </script> ``` ### 关键实现原理 1. **Set 对象去重**: - 使用 `new Set()` 存储唯一 - 遍历所有项时检查是否已存在 2. **动态删除重复项**: ```javascript if (values.has(val)) { $(this).remove(); // 删除重复项 } ``` 3. **刷新组件**: ```javascript $('#mySelect').selectpicker('refresh'); // 更新UI显示 ``` 4. **事件监听**: ```javascript $('#mySelect').on('changed.bs.select', ...) // 监听择变化 ``` ### 处理动态添加项 ```javascript // 添加新项时自动去重 function addOption(value, text) { if (!$(`#mySelect option[value="${value}"]`).length) { $('#mySelect').append(`<option value="${value}">${text}</option>`); $('#mySelect').selectpicker('refresh'); } } // 示例:添加新项 addOption('3', 'Banana'); // 成功添加 addOption('1', 'Red Apple'); // 被阻止(value=1已存在) ``` ### 注意事项 1. **唯一性原则**: - 去重基于 `value` 属性而非显示文本 - 确保业务逻辑中 `value` 具有唯一性标识 2. **性能优化**: - 建议在项数量大时添加防抖处理 - 可在操作完成后统一刷新而非每次修改都刷新 3. **特殊场景处理**: ```javascript // 保留首次出现的项(默认) // 或保留最后一次出现的项: $(this).prevAll(`[value="${val}"]`).remove(); ``` [^1]: Bootstrap-select 中文文档 [^2]: 动态组件刷新机制
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值