2008-09-04 8 views
7

Ich habe mehrere wählt:Gibt es eine Möglichkeit, die Optionen von Html Select erneut zu füllen, ohne das Ereignis Change auszulösen (mit 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> 

Was ich will, ist, um „Eins“ aus der ersten Auswahl, dann haben diese Option von der zweiten entfernt werden. Dann, wenn Sie "zwei" von der zweiten wählen, möchte ich, dass eine von der ersten entfernt.

Hier ist die JS Ich habe zur Zeit:

$(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(); 
    }); 
}); 

Aber wenn die Elemente neu besiedelt bekommen, es löst das Änderungsereignis in der Auswahl dessen Optionen ändern sich. Ich habe versucht, nur das disabled Attribut auf die Option, die ich entfernen möchte, aber das funktioniert nicht mit IE6.

Antwort

3

Ich bin (momentan) kein Benutzer von jQuery, aber ich kann Ihnen sagen, dass Sie Ihren Ereignishandler vorübergehend trennen müssen, während Sie die Elemente neu füllen oder zumindest ein Flag setzen, das Sie dann testen und darauf basieren auf seinen Wert, die Änderung handhaben.

3

Hier ist der endgültige Code, den ich am Ende verwendet, die Flagge (changeOnce) hat super funktioniert, danke @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

Oder Sie können einfach die Möglichkeit, verstecken Sie nicht wollen, um zu zeigen, ...

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 sorry, dieser Code funktioniert nicht mit IE6 ...