2008-09-04 8 views
7

que tienen múltiples selecciona:¿Hay alguna manera de volver a llenar las opciones de una selección de HTML sin activar el evento Change (usando jQuery)?

<select id="one"> 
    <option value="1">one</option> 
    <option value="2">two</option> 
    <option value="3">three</option> 
</select> 
<select id="two"> 
    <option value="1">one</option> 
    <option value="2">two</option> 
    <option value="3">three</option> 
</select> 

Lo que quiero es seleccionar "uno" de la primera selección, a continuación, tiene esa opción se elimina de la segunda. Luego, si selecciona "dos" del segundo, quiero que se elimine uno de los primeros.

Aquí está la JS tengo actualmente:

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

    var selectOptions = []; 
    $("select").each(function (index) { 
     selectOptions[index] = []; 
     for (var i = 0; i < this.options.length; i++) { 
      selectOptions[index][i] = this.options[i]; 
     } 
    }); 

    $one.change(function() { 
     var selectedValue = $("option:selected", this).val(); 
     for (var i = 0; i < selectOptions[1].length; i++) { 
      var exists = false; 
      for (var x = 0; x < $two[0].options.length; x++) { 
       if ($two[0].options[x].value == selectOptions[1][i].value) 
        exists = true; 
      } 
      if (!exists) 
       $two.append(selectOptions[1][i]); 
     } 

     $("option[value='" + selectedValue + "']", $two).remove(); 
    }); 
    $two.change(function() { 
     var selectedValue = $("option:selected", this).val(); 
     for (var i = 0; i < selectOptions[0].length; i++) { 
      var exists = false; 
      for (var x = 0; x < $one[0].options.length; x++) { 
       if ($one[0].options[x].value == selectOptions[0][i].value) 
        exists = true; 
      } 
      if (!exists) 
       $one.append(selectOptions[0][i]); 
     } 

     $("option[value='" + selectedValue + "']", $one).remove(); 
    }); 
}); 

Pero cuando los elementos consiguen repobladas, se dispara el evento de cambio en el selecto cuyas opciones están cambiando. Intenté simplemente configurar el atributo disabled en la opción que deseo eliminar, pero eso no funciona con IE6.

Respuesta

3

No soy (actualmente) un usuario de jQuery, pero puedo decirle que necesita desconectar temporalmente su controlador de eventos mientras vuelve a llenar los elementos o, como mínimo, establece un indicador que luego prueba y basa en su valor, maneja el cambio.

3

Aquí está el código final que terminé usando, la bandera (changeOnce) funcionó muy bien, gracias @Jason.

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

    var selectOptions = []; 
    $("select").each(function (index) { 
     selectOptions[index] = []; 
     for (var i = 0; i < this.options.length; i++) { 
      selectOptions[index][i] = this.options[i]; 
     } 
    }); 

    var changeOnce = false; 
    $one.change(function() { 
     if (changeOnce) return; 
     changeOnce = true; 
     var selectedValue = $("option:selected", this).val(); 
     filterSelect(selectedValue, $two, 1); 
     changeOnce = false; 
    }); 
    $two.change(function() { 
     if (changeOnce) return; 
     changeOnce = true; 
     var selectedValue = $("option:selected", this).val(); 
     filterSelect(selectedValue, $one, 0); 
     changeOnce = false; 
    }); 

    function filterSelect(selectedValue, $selectToFilter, selectIndex) { 
     for (var i = 0; i < selectOptions[selectIndex].length; i++) { 
      var exists = false; 
      for (var x = 0; x < $selectToFilter[0].options.length; x++) { 
       if ($selectToFilter[0].options[x].value == selectOptions[selectIndex][i].value) 
        exists = true; 
      } 
      if (!exists) 
       $selectToFilter.append(selectOptions[selectIndex][i]); 
     } 
     $("option[value='" + selectedValue + "']", $selectToFilter).remove(); 
     sortSelect($selectToFilter[0]); 
    } 

    function sortSelect(selectToSort) { 
     var arrOptions = []; 

     for (var i = 0; i < selectToSort.options.length; i++) { 
      arrOptions[i] = []; 
      arrOptions[i][0] = selectToSort.options[i].value; 
      arrOptions[i][1] = selectToSort.options[i].text; 
      arrOptions[i][2] = selectToSort.options[i].selected; 
     } 

     arrOptions.sort(); 

     for (var i = 0; i < selectToSort.options.length; i++) { 
      selectToSort.options[i].value = arrOptions[i][0]; 
      selectToSort.options[i].text = arrOptions[i][1]; 
      selectToSort.options[i].selected = arrOptions[i][2]; 
     } 
    } 
}); 
0

o simplemente puede ocultar la opción que no desea mostrar ...

function hideSelected($one, $two) 
{ 
    $one.bind('change', function() 
    { 
     var val = $one.val(); 
     $two.find('option:not(:visible)').show().end() 
      .find('option[value='+val+']').hide().end(); 
    }) 
} 
hideSelected($one, $two); 
hideSelected($two, $one); 

EDIT: Oh, lo siento, este código no funciona con IE6 ...

Cuestiones relacionadas