Resposta gratuita do Alvaros JS foi um grande começo para mim, e eu realmente tentei obter uma resposta verdadeiramente livre de JS que ainda fornecia toda a funcionalidade esperada de um Select com imagens, mas, infelizmente, aninhar formulários foi a queda. Estou postando duas soluções aqui; minha solução principal que usa 1 linha de JavaScript e uma solução totalmente livre de JavaScript que não funcionará em outro formulário, mas pode ser útil para os menus de navegação.
Infelizmente, há um pouco de repetição no código, mas quando você pensa sobre o que um Select faz, faz sentido. Quando você clica em uma opção, ele copia esse texto para a área selecionada, ou seja, clicar em 1 das 4 opções não altera as 4 opções, mas a parte superior agora repete a que você clicou. Para fazer isso com imagens, seria necessário JavaScript, orrrr ... você duplica as entradas.
No meu exemplo, temos uma lista de jogos (produtos), que têm versões. Cada produto também pode ter expansões, que também podem ter versões. Para cada produto, fornecemos ao usuário uma lista de cada versão, se houver mais de uma, juntamente com um texto específico da imagem e da versão.
<h4>@Model.Name</h4>
@if (Model.Versions.Count == 1)
{
<div class="rich-select-option-body pl-2">
<img src="@Model.Versions[0].ImageUrl" alt="">@Model.Versions[0].VersionName (@Model.Versions[0].Year)
</div>
}
else
{
<h5>Select the version</h5>
<div class="rich-select custom-select">
<div class="rich-select-dropdown">
@foreach (var version in Model.Versions)
{
<div class="rich-select-option">
<input type="radio" name="game" id="game-@version.ProductId-@version.VersionId" @if (version == Model.Versions.First()) { @Html.Raw(" checked") ; } />
<div class="rich-select-option-body">
<label tabindex="-1">
<img src="@version.ImageUrl" alt="">@version.VersionName (@version.Year)
</label>
</div>
</div>
}
</div>
<input type="checkbox" id="rich-select-dropdown-button" class="rich-select-dropdown-button" />
<label for="rich-select-dropdown-button"></label>
<div class="rich-select-options">
@foreach (var version in Model.Versions)
{
<div class="rich-select-option">
<div class="rich-select-option-body">
<label for="game-@version.ProductId-@version.VersionId" tabindex="-1" onclick="document.getElementById('rich-select-dropdown-button').click();">
<img src="@version.ImageUrl" alt=""> @version.VersionName (@version.Year)
</label>
</div>
</div>
}
</div>
</div>
}
Usando JS para desmarcar a caixa de seleção, podemos ter várias instâncias em um formulário. Aqui estendi para mostrar uma lista de expansões, que também têm a mesma lógica nas versões.
<h5 class="mt-3">Include Expansions?</h5>
@foreach (var expansion in Model.Expansions)
{
<div class="form-row">
<div class="custom-control custom-checkbox w-100">
<input type="checkbox" class="expansion-checkbox custom-control-input" id="exp-@expansion.ProductId">
<label class="custom-control-label w-100" for="exp-@expansion.ProductId">
@if (expansion.Versions.Count == 1)
{
<div class="rich-select-option-body pl-2">
<img src="@expansion.ImageUrl" />@expansion.Name: @expansion.Versions[0].VersionName (@expansion.Versions[0].Year)
</div>
}
else
{
<div class="rich-select custom-select">
<div class="rich-select-dropdown">
@foreach (var version in expansion.Versions)
{
<div class="rich-select-option">
<input type="radio" name="exp-@version.ProductId" id="exp-@version.ProductId-@version.VersionId" @if (version == expansion.Versions.First()) { @Html.Raw(" checked") ; } />
<div class="rich-select-option-body">
<label tabindex="-1">
<img src="@version.ImageUrl" alt="">@expansion.Name: @version.VersionName (@version.Year)
</label>
</div>
</div>
}
</div>
<input type="checkbox" id="rich-select-dropdown-button-@expansion.ProductId" class="rich-select-dropdown-button" />
<label for="rich-select-dropdown-button-@expansion.ProductId"></label>
<div class="rich-select-options">
@foreach (var version in expansion.Versions)
{
<div class="rich-select-option">
<div class="rich-select-option-body">
<label for="exp-@version.ProductId-@version.VersionId" tabindex="-1" onclick="document.getElementById('rich-select-dropdown-button-@expansion.ProductId').click();">
<img src="@version.ImageUrl" alt="">@expansion.Name: @version.VersionName (@version.Year)
</label>
</div>
</div>
}
</div>
</div>
}
</label>
</div>
</div>
É claro que isso requer um pouco de CSS, que eu incluí apenas neste JSFiddle para reduzir o tamanho dessa resposta já massiva. Usei o Bootstrap 4 para reduzir a quantidade necessária e também para permitir que ele se encaixe em outros controles do Bootstrap e em qualquer personalização do site que tenha sido feita.
As imagens estão definidas para 75px, mas isso pode ser facilmente alterado em 5 linhas .rich-select
e.rich-select-option-body img