<!doctype html>
<html lang="pt-br">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Multiseleção com Checkboxes (Bootstrap 5)</title>
  <!-- Bootstrap 5 CSS -->
  <link
    href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
    rel="stylesheet"
    integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
    crossorigin="anonymous"
  />
  <style>
    /* Apenas para tornar o dropdown mais amigável quando há muitas opções */
    .dropdown-menu-select {
      width: 520px;
    }
    .dropdown-menu-select .options {
      max-height: 220px; /* rolagem quando muitas opções */
      overflow: auto;
      border: 1px solid var(--bs-border-color);
      border-radius: .5rem;
      padding: .25rem .5rem;
    }
    .dropdown-menu-select .form-check {
      padding: 1.25rem .5rem;
      border-radius: .375rem;
    }
    .dropdown-menu-select .form-check:hover {
      background: var(--bs-light);
    }
  </style>
</head>
<body class="bg-body-tertiary py-5">
  <div class="container">
    <h1 class="h3 mb-4">Select com multiseleção (checkbox nas opções)</h1>

    <form id="demoForm" class="vstack gap-4" onsubmit="handleSubmit(event)">
      <!-- COMPONENTE: Multiselect com checkboxes -->
      <div class="vstack gap-2">
        <label for="btn-multiselect" class="form-label">Frutas favoritas</label>

        <div class="dropdown">
          <button
            id="btn-multiselect"
            class="btn btn-outline-primary d-flex align-items-center gap-2"
            type="button"
            data-bs-toggle="dropdown"
            aria-expanded="false"
            aria-haspopup="listbox"
          >
            <span class="label-text">Escolha as frutas</span>
            <span class="badge text-bg-secondary ms-auto selected-count d-none">0</span>
            <span class="ms-1" aria-hidden="true">▾</span>
          </button>

          <div class="dropdown-menu dropdown-menu-select p-3" role="listbox" aria-label="Lista de frutas">
            <!-- Ações rápidas -->
            <div class="d-flex gap-2 mb-2">
              <button type="button" class="btn btn-sm btn-outline-secondary" id="btn-select-all">Selecionar tudo</button>
              <button type="button" class="btn btn-sm btn-outline-danger" id="btn-clear">Limpar</button>
            </div>

            <!-- Opções -->
            <div class="options vstack gap-1" id="options">
              <!-- Cada item é uma checkbox Bootstrap -->
              <div class="form-check">
                <input class="form-check-input option" type="checkbox" value="maca" id="opt-maca" data-label="Maçã">
                <label class="form-check-label" for="opt-maca">Maçã</label>
              </div>
              <div class="form-check">
                <input class="form-check-input option" type="checkbox" value="banana" id="opt-banana" data-label="Banana">
                <label class="form-check-label" for="opt-banana">Banana</label>
              </div>
              <div class="form-check">
                <input class="form-check-input option" type="checkbox" value="laranja" id="opt-laranja" data-label="Laranja">
                <label class="form-check-label" for="opt-laranja">Laranja</label>
              </div>
              <div class="form-check">
                <input class="form-check-input option" type="checkbox" value="manga" id="opt-manga" data-label="Manga">
                <label class="form-check-label" for="opt-manga">Manga</label>
              </div>
              <div class="form-check">
                <input class="form-check-input option" type="checkbox" value="uva" id="opt-uva" data-label="Uva">
                <label class="form-check-label" for="opt-uva">Uva</label>
              </div>
              <div class="form-check">
                <input class="form-check-input option" type="checkbox" value="pera" id="opt-pera" data-label="Pêra">
                <label class="form-check-label" for="opt-pera">Pêra</label>
              </div>
              <div class="form-check">
                <input class="form-check-input option" type="checkbox" value="abacaxi" id="opt-abacaxi" data-label="Abacaxi">
                <label class="form-check-label" for="opt-abacaxi">Abacaxi</label>
              </div>
              <div class="form-check">
                <input class="form-check-input option" type="checkbox" value="kiwi" id="opt-kiwi" data-label="Kiwi">
                <label class="form-check-label" for="opt-kiwi">Kiwi</label>
              </div>
            </div>
          </div>
        </div>

        <!-- Select "real" para submissão em forms -->
        <select name="frutas[]" id="select-hidden" class="d-none" multiple>
          <option value="maca">Maçã</option>
          <option value="banana">Banana</option>
          <option value="laranja">Laranja</option>
          <option value="manga">Manga</option>
          <option value="uva">Uva</option>
          <option value="pera">Pêra</option>
          <option value="abacaxi">Abacaxi</option>
          <option value="kiwi">Kiwi</option>
        </select>

        <div class="form-text">Use o botão para abrir o menu e marcar as opções. O campo oculto <code>select</code> garante submissão tradicional do formulário.</div>
      </div>

      <!-- Resultado de submissão (apenas para demo) -->
      <div class="vstack gap-2">
        <button class="btn btn-primary" type="submit">Enviar</button>
        <pre id="output" class="bg-body border rounded p-3 small"></pre>
      </div>
    </form>
  </div>

  <!-- Bootstrap 5 JS (Popper incluso) -->
  <script
    src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
    integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
    crossorigin="anonymous"
  ></script>

  <script>
    // Utilidades
    const hiddenSelect = document.getElementById('select-hidden');
    const checkboxes = Array.from(document.querySelectorAll('.option'));
    const btnLabel = document.querySelector('#btn-multiselect .label-text');
    const badgeCount = document.querySelector('#btn-multiselect .selected-count');

    function getSelected() {
      return checkboxes.filter(ch => ch.checked);
    }

    function syncHiddenSelect() {
      // Limpa seleções atuais
      Array.from(hiddenSelect.options).forEach(opt => opt.selected = false);
      // Marca conforme checkboxes
      getSelected().forEach(ch => {
        const opt = Array.from(hiddenSelect.options).find(o => o.value === ch.value);
        if (opt) opt.selected = true;
      });
    }

    function updateButtonLabel() {
      const selected = getSelected();
      const n = selected.length;
      if (n === 0) {
        btnLabel.textContent = 'Escolha as frutas';
        badgeCount.classList.add('d-none');
        badgeCount.textContent = '0';
        return;
      }
      const labels = selected.map(ch => ch.dataset.label);
      // Mostra até 2 itens, e o restante como +N
      const preview = labels.slice(0, 2).join(', ');
      const rest = n - 2;
      btnLabel.textContent = rest > 0 ? `${preview} +${rest}` : preview;
      badgeCount.textContent = String(n);
      badgeCount.classList.remove('d-none');
    }

    function setAll(value) {
      checkboxes.forEach(ch => ch.checked = value);
      syncHiddenSelect();
      updateButtonLabel();
    }

    // Listeners
    checkboxes.forEach(ch => {
      ch.addEventListener('change', () => {
        syncHiddenSelect();
        updateButtonLabel();
      });
      // Acessibilidade extra: tecla Enter também alterna
      ch.addEventListener('keydown', (e) => {
        if (e.key === 'Enter') {
          ch.checked = !ch.checked;
          ch.dispatchEvent(new Event('change'));
        }
      });
    });

    document.getElementById('btn-select-all').addEventListener('click', () => setAll(true));
    document.getElementById('btn-clear').addEventListener('click', () => setAll(false));

    // Inicializa
    syncHiddenSelect();
    updateButtonLabel();

    // Apenas para demonstração: captura submissão do form e exibe JSON
    function handleSubmit(e) {
      e.preventDefault();
      const data = new FormData(e.target);
      const frutas = data.getAll('frutas[]');
      document.getElementById('output').textContent = JSON.stringify({ frutas }, null, 2);
    }
    window.handleSubmit = handleSubmit;
    <script>
    // --- Fallback para garantir que o dropdown abre ---
    (function ensureDropdownWorks() {
      const trigger = document.getElementById('btn-multiselect');
      const menu = document.querySelector('.dropdown-menu-select');

      // Se o Bootstrap JS estiver disponível, inicializa explicitamente
      if (window.bootstrap && bootstrap.Dropdown) {
        try {
          new bootstrap.Dropdown(trigger);
        } catch (err) {}
      } else {
        // Fallback simples: toggla a classe .show manualmente
        trigger.addEventListener('click', (e) => {
          e.stopPropagation();
          menu.classList.toggle('show');
        });
        document.addEventListener('click', (e) => {
          const dd = trigger.closest('.dropdown');
          if (!dd.contains(e.target)) {
            menu.classList.remove('show');
          }
        });
        // Fecha com Esc
        document.addEventListener('keydown', (e) => {
          if (e.key === 'Escape') menu.classList.remove('show');
        });
      }
    })();
  </script>
</script>
</body>
</html>