Como criar uma caixa de seleção personalizada Multi Select Dropdown

HTML fornece uma forma nativa de criar uma caixa de seleção que suporta a seleção de vários itens com o atributo múltiplo em elementos selecionados, mas a renderização disto realmente não é muito compacta ou bonita, e também não há muito que você possa fazer com opções em uma caixa de seleção. Não consegui encontrar nenhum design personalizado que se adaptasse ao estilo que procurava, por isso acabei por fazer o meu próprio. O código completo está disponível no meu GitHub aqui junto com uma barra de busca correspondente.

Esta é construída do zero devido a dificuldades em mudar o comportamento e estilo de uma seleção normal. A parte normalmente visível da seleção é um simples botão. O menu dropdown é um mergulho escondido pela classe utilitário Bootstrap d-none, com arredondamento e sombreamento aplicados através das classes utilitárias Bootstrap shadow e arredondado. As opções são caixas de seleção simples com etiquetas. Estas poderiam ser substituídas por botões de rádio se você quisesse uma caixa de seleção correspondente.

Aqui está o HTML final para o botão e menu

<div> <button onclick="dropDown(event);" class="menu-btn" type="button"> Menu 1 &#9013; </button> <div class="d-none shadow rounded menu"> <span class="d-block menu-option"><label><input type="checkbox">&nbsp; Option 1</label></span> <span class="d-block menu-option"><label><input type="checkbox">&nbsp; Option 2</label></span> <span class="d-block menu-option"><label><input type="checkbox">&nbsp; Option 3</label></span> </div></div>
Entrar no modo ecrã inteiro Sair do modo ecrã inteiro

Queria que o botão de menu fosse arredondado e bastante pequeno, por isso estilizei-o em conformidade (pode estilizá-lo da forma que quiser, claro, não afecta em nada a função):

.menu-btn { border-radius: 48px; border: 0.5px solid lightgrey; font-size: 0.9em; padding: 2px 10px; background-color: white;}
Entre no modo ecrã completo Sair do modo ecrã completo

Para o menu em si, adicionei um pequeno acolchoamento para que o texto não estivesse a correr contra o topo do menu e alguma margem para não se sobrepor ao botão (ambos completamente opcionais). Também adicionei um alto índice z (para que ele fosse exibido sobre outras coisas), uma cor de fundo (o padrão é transparente, o que parece idiota neste contexto), e definir posição para absoluto para que ele não empurre outras coisas para baixo na página.

.menu { padding-top: 10px; z-index: 200; margin-top: 4px; background-color: white; position: absolute;}
Enter fullscreen mode Exit fullscreen mode

Para as opções do menu, adicionei um pequeno padding para separá-las.

.menu-option { padding: 6px 20px 6px;}
Entrar no modo de ecrã completo Sair do modo de ecrã completo

Precisamos de uma forma de detectar quando os cliques são feitos fora do menu dropdown para que possa ser descartado clicando fora dele como uma caixa de selecção normal. Eu fiz isso criando um div que cobre toda a tela com um índice z menor do que o menu. Isto permite-nos detectar todos os cliques fora do menu

<div class="d-none" onclick="hide(event)"></div>
Enter fullscreen mode Exit fullscreen mode

#overlay { position: absolute; top: 0px; left: 0px; width: 100%; height: 100%; z-index: 100;}
Enter fullscreen mode Exit fullscreen mode

Para que isto funcione de facto, precisamos das funções JavaScript para fazer aparecer e desaparecer os menus e sobreposições.
Esta função remove as classes d-none do menu e overlay, ativando-as. Ao invés de lidar com isso via ID, ela simplesmente pega o segundo elemento do pai do alvo (botão) e assume que é o menu. Esta é a razão pela qual o menu e o botão estão envoltos num div.

function dropDown(event) { event.target.parentElement.children.classList.remove("d-none"); document.getElementById("overlay").classList.remove("d-none");}
Enter fullscreen mode Exit fullscreen mode

Esta função adiciona a classe d-none ao overlay e todos os elementos com o menu de classes, escondendo-os.

function hide(event) { var items = document.getElementsByClassName('menu'); for (let i = 0; i < items.length; i++) { items.classList.add("d-none"); } document.getElementById("overlay").classList.add("d-none");}
Entrar no modo de ecrã completo Sair do modo de ecrã completo

Se achou isto útil, pode também gostar do design da minha barra de pesquisa correspondente.

Deixe uma resposta

O seu endereço de email não será publicado.