27 de mayo de 2014

HTML Select con options excluyentes con jQuery (evitar seleccionar el mismo 2 veces)

Un saludo, tiempo sin escribirles, esta vez vengo a compartir una experiencia en la cual estuve investigando mucho, sin embargo, no pude resolver mi problema con algún Plugin o algo semejante. Les cuento:

El problema


Existen casos en los cuales uno desea mostrar repetidos selects en el mismo formulario, con la misma data, pero las opciones deben excluirse unas a otras, un caso practico: Tienes una lista de participantes y necesitas definir el orden en el que van a competir, son los mismos participantes, en varios selects, pero si el en 1er select indicas al participante nro 1, este no puede aparecer en el 2do select, ya que esta en el 1ero. Otro ejemplo: Tenemos a todos los usuarios de un sistema, y quieres asignarlos a un grupo especifico, si tienes varios grupos, estos usuarios no deben pertenecer a mas de un grupo. Veamos el demo funcionando para que quede claro el funcionamiento.

Solución


Haré uso de un flag hidden, es decir, una clase CSS llamada hidden para ocultar aquellas opciones que no quiero visualizar, ese es el truco. a continuacion describo todo detalladamente:

CSS Hoja de estilo


.hidden { display: none; }
Como se puede observar es bastante sencillo la hoja de estilos, la podemos incluir en el head de nuestro sitio web.

Javascript


Antetodo requerimos la libreria jQuery colocarla en el head de nuestro sitio y agregar las siguientes lineas:
$(function () {
    function restrict_multiple(selector) {
        // Aqui establece el valor actual en su alt
        $(selector).each(function () {
            $(this).attr("alt", $(this).val());
        })
        // Disparador cuando cambia el select
        $(selector).change(function () {
            // Eliminando el hidden del option
            $(selector + " option").removeClass("hidden");
            
            // Se usa el alt attr, como aun auxiliar para mantener el valor que esta activo
            $(this).attr("alt", $(this).val())
            
            // Creando un arreglo con las opciones seleccionadas
            var selected = new Array();
            
            // Cada opcion seleccionada se ingresa en el arreglo
            $(selector + " option:selected").each(function () {
                selected.push(this.value);
            })
            
            // Ocultando los seleccionados ya, para no verlos en los demas selects
            for (k in selected) {
                $(selector + "[alt!=" + selected[k] + "] option[value=" + selected[k] + "]").addClass("hidden")
            }
        })
        
        // Disparador para que se mantenga actualizado todos los selects
        $(selector).each(function () { $(this).trigger("change"); })
    }
    
    restrict_multiple(".excluyent-select");
})

 HTML el contenido de nuestra web


<select name="participantes_1" id="participantes_1" class="excluyent-select">
    <option value="">
        Seleccionar
    </option>

    <option value="1">
        Equipo Blanco - Escuela 1
    </option>

    ...

    <option value="9">
        Equipo Amarillo - Escuela 9
    </option>
</select>



Gracias por leerme y encantado estaría de leer sus comentarios. Igualmente les invito a suscribirse a los feeds del sitio con su lector favorito o suscribirse a través de correo electrónico, esperaré leer sus comentarios.