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

按需求定制Bootstrap模态框的功能与样式

实现带状态记忆的Bootstrap属性选择模态框(修复Show More布局问题)

以下是完整的修正后代码,解决了Show More按钮位置冲突、布局排列及状态记忆需求:

HTML 结构

<!-- 触发按钮 -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#attributeModal">
  Select Attribute
</button>

<!-- 属性选择模态框 -->
<div class="modal fade" id="attributeModal" tabindex="-1" aria-labelledby="attributeModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <!-- 模态框头部 -->
      <div class="modal-header">
        <h5 class="modal-title" id="attributeModalLabel">Select Attributes:</h5>
        <div class="ms-auto">
          <div class="form-check form-check-inline">
            <input class="form-check-input" type="checkbox" id="selectAll">
            <label class="form-check-label" for="selectAll">Select All</label>
          </div>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
      </div>
      <!-- 模态框主体 -->
      <div class="modal-body">
        <!-- 默认显示的属性 -->
        <div class="row mb-3">
          <div class="col-md-4 mb-2">
            <div class="form-check">
              <input class="form-check-input attribute-checkbox" type="checkbox" id="attr1" value="attr1">
              <label class="form-check-label" for="attr1">Attribute 1</label>
            </div>
          </div>
          <div class="col-md-4 mb-2">
            <div class="form-check">
              <input class="form-check-input attribute-checkbox" type="checkbox" id="attr2" value="attr2">
              <label class="form-check-label" for="attr2">Attribute 2</label>
            </div>
          </div>
          <div class="col-md-4 mb-2">
            <div class="form-check">
              <input class="form-check-input attribute-checkbox" type="checkbox" id="attr3" value="attr3">
              <label class="form-check-label" for="attr3">Attribute 3</label>
            </div>
          </div>
        </div>

        <!-- Show More按钮(独立布局,避免冲突) -->
        <button type="button" class="btn btn-link text-decoration-none" id="showMoreBtn">Show More</button>

        <!-- 隐藏的更多属性 -->
        <div class="row mt-3 d-none" id="moreAttributes">
          <div class="col-md-4 mb-2">
            <div class="form-check">
              <input class="form-check-input attribute-checkbox" type="checkbox" id="attr4" value="attr4">
              <label class="form-check-label" for="attr4">Attribute 4</label>
            </div>
          </div>
          <div class="col-md-4 mb-2">
            <div class="form-check">
              <input class="form-check-input attribute-checkbox" type="checkbox" id="attr5" value="attr5">
              <label class="form-check-label" for="attr5">Attribute 5</label>
            </div>
          </div>
          <div class="col-md-4 mb-2">
            <div class="form-check">
              <input class="form-check-input attribute-checkbox" type="checkbox" id="attr6" value="attr6">
              <label class="form-check-label" for="attr6">Attribute 6</label>
            </div>
          </div>
        </div>

        <!-- Japan Attribute 部分 -->
        <div class="mt-4">
          <h6 class="mb-3">Japan Attribute</h6>
          <div class="row">
            <div class="col-md-4 mb-2">
              <div class="form-check">
                <input class="form-check-input attribute-checkbox" type="checkbox" id="ja1" value="ja1">
                <label class="form-check-label" for="ja1">ja1</label>
              </div>
            </div>
            <div class="col-md-4 mb-2">
              <div class="form-check">
                <input class="form-check-input attribute-checkbox" type="checkbox" id="ja2" value="ja2">
                <label class="form-check-label" for="ja2">ja2</label>
              </div>
            </div>
            <div class="col-md-4 mb-2">
              <div class="form-check">
                <input class="form-check-input attribute-checkbox" type="checkbox" id="ja3" value="ja3">
                <label class="form-check-label" for="ja3">ja3</label>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- 模态框底部 -->
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" id="cancelBtn">Cancel</button>
        <button type="button" class="btn btn-primary" id="okBtn">Ok</button>
      </div>
    </div>
  </div>
</div>

CSS 样式(优化布局)

/* 调整复选框内边距,提升可读性 */
.modal-body .form-check {
  padding-left: 1.5em;
}

/* 优化Show More按钮样式 */
#showMoreBtn {
  padding: 0;
  color: #0d6efd;
}

JavaScript 逻辑(实现交互与状态控制)

// 存储选中状态的全局变量
let savedCheckedStates = {};

document.addEventListener('DOMContentLoaded', function() {
  const modal = document.getElementById('attributeModal');
  const selectAllCheckbox = document.getElementById('selectAll');
  const attributeCheckboxes = document.querySelectorAll('.attribute-checkbox');
  const showMoreBtn = document.getElementById('showMoreBtn');
  const moreAttributes = document.getElementById('moreAttributes');
  const okBtn = document.getElementById('okBtn');
  const cancelBtn = document.getElementById('cancelBtn');
  const modalInstance = new bootstrap.Modal(modal);

  // Show More 切换逻辑
  showMoreBtn.addEventListener('click', function() {
    moreAttributes.classList.toggle('d-none');
    this.textContent = moreAttributes.classList.contains('d-none') ? 'Show More' : 'Show Less';
  });

  // 全选/全不选功能
  selectAllCheckbox.addEventListener('change', function() {
    attributeCheckboxes.forEach(checkbox => {
      checkbox.checked = this.checked;
    });
  });

  // Ok按钮:保存选中状态并关闭模态框
  okBtn.addEventListener('click', function() {
    savedCheckedStates = {};
    // 遍历存储所有复选框状态
    attributeCheckboxes.forEach(checkbox => {
      savedCheckedStates[checkbox.id] = checkbox.checked;
    });
    // 更新全选框状态
    const allChecked = Array.from(attributeCheckboxes).every(cb => cb.checked);
    selectAllCheckbox.checked = allChecked;
    modalInstance.hide();
  });

  // Cancel按钮:重置状态并关闭模态框
  cancelBtn.addEventListener('click', function() {
    savedCheckedStates = {};
    // 重置所有复选框为未选中
    attributeCheckboxes.forEach(checkbox => {
      checkbox.checked = false;
    });
    selectAllCheckbox.checked = false;
    modalInstance.hide();
  });

  // 模态框显示时恢复状态
  modal.addEventListener('show.bs.modal', function() {
    if (Object.keys(savedCheckedStates).length > 0) {
      // 恢复之前保存的选中状态
      attributeCheckboxes.forEach(checkbox => {
        checkbox.checked = savedCheckedStates[checkbox.id] || false;
      });
      // 更新全选框状态
      const allChecked = Array.from(attributeCheckboxes).every(cb => cb.checked);
      selectAllCheckbox.checked = allChecked;
    } else {
      // 无保存状态时重置所有复选框
      attributeCheckboxes.forEach(checkbox => {
        checkbox.checked = false;
      });
      selectAllCheckbox.checked = false;
    }
    // 默认隐藏更多属性
    moreAttributes.classList.add('d-none');
    showMoreBtn.textContent = 'Show More';
  });
});

关键修复与实现说明

  1. 每行3个复选框布局:使用Bootstrap的row+col-md-4栅格系统,自动实现响应式每行3个排列,添加mb-2类增加垂直间距。
  2. Show More按钮位置修复:将按钮独立放置在默认属性容器之后,避免与栅格布局冲突,点击时通过切换d-none类控制隐藏内容的显示/隐藏。
  3. 全选功能:监听全选框的change事件,批量同步所有属性复选框的选中状态。
  4. 状态记忆(Ok按钮):点击Ok时将所有复选框的选中状态存储在对象中,下次打开模态框时读取并恢复。
  5. 重置功能(Cancel按钮):点击Cancel时清空状态存储,重置所有复选框为未选中,下次打开模态框保持初始状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 08:47:41