You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用bootstrapDualListbox()实现同一选项的多次重复选择?

实现支持重复选择的双列表组件(替代bootstrapDualListbox)

首先明确:bootstrapDualListbox 基于原生 <select multiple> 实现,而原生select的机制决定了每个 <option> 只能被选中一次,无法直接满足重复选择同一值的需求。要实现选中如1,1,2,3,3这类重复项的效果,需要自定义逻辑,下面提供一种可行的替代方案:

方案思路

放弃依赖原生select的选中机制,改为手动维护右侧已选列表的DOM元素:每次选择左侧选项时,复制一个相同的选项到右侧列表(而非移动原选项),以此支持重复添加同一值。

完整代码实现

HTML结构

<div class="row">
  <div class="col-md-5">
    <h5>可选列表</h5>
    <select id="availableSelect" multiple class="form-control" size="5">
      <option value="1"> One </option>
      <option value="2"> Two</option>
      <option value="3"> Three</option>
    </select>
    <button id="addBtn" class="btn btn-primary mt-2">→ 添加</button>
  </div>
  <div class="col-md-2 d-flex align-items-center justify-content-center">
    <!-- 占位列 -->
  </div>
  <div class="col-md-5">
    <h5>已选列表</h5>
    <div id="selectedContainer" class="border rounded p-2" style="min-height: 120px; overflow-y: auto;">
      <!-- 动态生成已选项 -->
    </div>
    <button id="removeBtn" class="btn btn-danger mt-2">← 移除选中</button>
  </div>
</div>

JavaScript逻辑

// 添加选项到已选列表
document.getElementById('addBtn').addEventListener('click', function() {
  const availableSelect = document.getElementById('availableSelect');
  const selectedContainer = document.getElementById('selectedContainer');
  
  // 获取左侧选中的所有选项
  const selectedOpts = Array.from(availableSelect.selectedOptions);
  
  selectedOpts.forEach(opt => {
    // 复制原选项作为已选项节点
    const clonedOpt = opt.cloneNode(true);
    clonedOpt.classList.add('selected-item');
    // 给已选项添加点击选中样式
    clonedOpt.style.display = 'block';
    clonedOpt.style.padding = '4px 8px';
    clonedOpt.style.cursor = 'pointer';
    clonedOpt.addEventListener('click', function() {
      this.classList.toggle('bg-primary');
      this.classList.toggle('text-white');
    });
    // 添加到右侧容器
    selectedContainer.appendChild(clonedOpt);
  });
  
  // 清空左侧选中状态
  availableSelect.selectedIndex = -1;
});

// 移除选中的已选项
document.getElementById('removeBtn').addEventListener('click', function() {
  const selectedContainer = document.getElementById('selectedContainer');
  const itemsToRemove = selectedContainer.querySelectorAll('.selected-item.bg-primary');
  
  itemsToRemove.forEach(item => selectedContainer.removeChild(item));
});

// 获取所有已选值(提交表单时调用)
function getSelectedValues() {
  const selectedItems = document.querySelectorAll('#selectedContainer .selected-item');
  return Array.from(selectedItems).map(item => item.value);
}

可选样式优化

.selected-item:hover {
  background-color: #f0f0f0;
}
.selected-item.bg-primary {
  background-color: #0d6efd !important;
}

方案说明

  1. 左侧保留原生select用于选择选项,但不依赖它的选中状态维护已选列表
  2. 点击添加按钮时,复制选中的选项到右侧容器,同一选项可被多次添加
  3. 右侧已选项支持点击选中,再通过移除按钮删除选中的项
  4. 最终可通过getSelectedValues()方法获取包含重复项的所有已选值

如果一定要基于bootstrapDualListbox改造,需要修改插件核心逻辑:将选项移动操作改为复制操作,但这种方式需要深入修改插件源码,维护成本较高,不如自定义实现灵活。

内容的提问来源于stack exchange,提问作者ihavenokia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 06:41:19