Cómo Repoblar Opciones de Selección HTML Sin Disparar el Evento de Cambio con jQuery

Al trabajar con múltiples elementos de selección HTML en una aplicación web, puedes encontrarte en una situación en la que seleccionar una opción en un dropdown afecta las opciones disponibles en otro. Un escenario común es hacer que una opción disponible en una selección desaparezca cuando se selecciona en otra. Sin embargo, hacer esto puede disparar inadvertidamente eventos de cambio que pueden complicar tu lógica. En esta publicación, abordaremos cómo repoblar dinámicamente las opciones de selección sin activar los eventos de cambio no deseados utilizando jQuery.

El Problema

Imagina que tienes dos dropdowns (elementos de selección) que son interdependientes. Quieres implementar un sistema donde seleccionar una opción en un dropdown elimina esa opción del segundo dropdown, asegurando que los usuarios no puedan seleccionar la misma opción en ambos. Sin embargo, con el comportamiento predeterminado de jQuery, cambiar las opciones en una selección también llama al evento de cambio para esa selección, lo que podría llevar a un comportamiento inesperado en tu aplicación.

Escenario de Ejemplo

Aquí tienes una estructura HTML simple para ilustrar los dropdowns:

<select id="one">
  <option value="1">uno</option>
  <option value="2">dos</option>
  <option value="3">tres</option>
</select>
<select id="two">
  <option value="1">uno</option>
  <option value="2">dos</option>
  <option value="3">tres</option>
</select>

Cuando seleccionas “uno” del primer dropdown (#one), el objetivo es eliminar “uno” del segundo dropdown (#two). Si luego seleccionas “dos” de #two, el mismo comportamiento debería ocurrir en reversa.

La Solución

Para evitar que se disparen eventos de cambio al repoblar las opciones en tus selecciones, necesitarás un enfoque de dos pasos: desconectar temporalmente los controladores de eventos y usar una bandera para determinar si el evento de cambio debe ser procesado.

Paso 1: Modificar la Lógica de JavaScript

Comienza configurando tus funciones de jQuery de la siguiente manera:

$(function () {
    var $one = $("#one");
    var $two = $("#two");

    var selectOptions = [ 
        $("option", $one).clone(), 
        $("option", $two).clone() 
    ];

    var isChanging = false; // Bandera para evitar disparar eventos de cambio

    $one.change(function () {
        if (isChanging) return; // Ignorar si ya está cambiando
        
        isChanging = true; // Establecer bandera antes de cambiar opciones
        var selectedValue = $("option:selected", this).val();
        $two.find("option[value='" + selectedValue + "']").remove();
        repopulateOptions($two, selectOptions[1]); // Restaurar opciones
        isChanging = false; // Reiniciar bandera
    });
    
    $two.change(function () {
        if (isChanging) return; // Ignorar si ya está cambiando
        
        isChanging = true; // Establecer bandera antes de cambiar opciones
        var selectedValue = $("option:selected", this).val();
        $one.find("option[value='" + selectedValue + "']").remove();
        repopulateOptions($one, selectOptions[0]); // Restaurar opciones
        isChanging = false; // Reiniciar bandera
    });

    function repopulateOptions($select, options) {
        options.each(function() {
            if (!$select.find("option[value='" + this.value + "']").length) {
                $select.append(this); // Agregar solo si no está ya presente
            }
        });
    }
});

Paso 2: Explicación de Componentes Clave

  • Bandera isChanging: Esta bandera booleana mantiene un seguimiento de si los controladores de eventos deben ejecutarse o ser ignorados, evitando cualquier disparo accidental de eventos durante la manipulación de opciones.
  • Función de Repoblar: Esta función ayuda a resincronizar las selecciones restaurando opciones previamente disponibles, asegurando que el usuario tenga acceso a todas las opciones a menos que ya se hayan elegido en el otro dropdown.
  • Clonación de Opciones: Clonar las opciones originales nos permite mantener una referencia a todas las opciones disponibles, facilitando la gestión de lo que se muestra.

Conclusión

Gestionar opciones de selección interdependientes puede ser complicado, especialmente cuando se busca evitar disparos de eventos no deseados. Siguiendo las pautas en esta publicación, podrás implementar una experiencia de usuario fluida donde las elecciones de selección se ajusten dinámicamente en tiempo real sin ningún problema asociado debido al disparo de eventos. Esta solución no solo protege contra comportamientos inesperados, sino que también mantiene tus opciones claras y a los usuarios comprometidos.

Si tienes alguna pregunta o quieres compartir tus propias experiencias con jQuery y dropdowns dinámicos, ¡no dudes en dejar un comentario abajo!