La respuesta gratuita de Alvaros JS fue un gran comienzo para mí, y realmente intenté obtener una respuesta verdaderamente libre de JS que aún ofreciera toda la funcionalidad esperada de un Select con imágenes, pero lamentablemente los formularios de anidación fueron la caída. Estoy publicando dos soluciones aquí; mi solución principal que usa 1 línea de JavaScript, y una solución totalmente libre de JavaScript que no funcionará dentro de otro formulario, pero podría ser útil para los menús de navegación.
Desafortunadamente, hay un poco de repetición en el código, pero cuando piensas en lo que hace un Select tiene sentido. Cuando hace clic en una opción, copia ese texto en el área seleccionada, es decir, hacer clic en 1 de 4 opciones no cambiará las 4 opciones, pero la parte superior ahora repetirá la que hizo clic. Hacer esto con imágenes requeriría JavaScript, orrrr ... duplicar las entradas.
En mi ejemplo, tenemos una lista de juegos (Productos), que tienen versiones. Cada producto también puede tener expansiones, que también pueden tener versiones. Para cada Producto, le damos al usuario una lista de cada versión si hay más de una, junto con una imagen y un texto específico de la versión.
<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 la deselección de la casilla de verificación podemos tener múltiples instancias en un formulario. Aquí me he extendido para mostrar una lista de expansiones, que también tienen la misma lógica en torno a las versiones.
<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>
Por supuesto, esto requiere un poco de CSS, que solo he incluido en este JSFiddle para reducir el tamaño de esta respuesta ya masiva. He usado Bootstrap 4 para reducir la cantidad necesaria y también para permitir que se ajuste a otros controles de Bootstrap y cualquier personalización del sitio que se haya realizado.
Las imágenes están configuradas en 75 píxeles, pero esto se puede cambiar fácilmente en 5 líneas .rich-select
y.rich-select-option-body img