I have multiple selects:
我有多个选择:
<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>
What I want is to select "one" from the first select, then have that option be removed from the second one. Then if you select "two" from the second one, I want that one removed from the first one.
我想要的是从第一个选择中选择“一个”,然后从第二个选项中删除该选项。然后,如果你从第二个中选择“两个”,我希望从第一个中删除一个。
Here's the JS I have currently:
这是我目前的JS:
$(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();
});
});
But when the elements get repopulated, it fires the change event in the select whose options are changing. I tried just setting the disabled
attribute on the option I want to remove, but that doesn't work with IE6.
但是当元素重新填充时,它会触发select中选项正在发生变化的change事件。我尝试在我想要删除的选项上设置disabled属性,但这不适用于IE6。
3 个解决方案
#1
3
I am not (currently) a user of jQuery, but I can tell you that you need to temporarily disconnect your event handler while you repopulate the items or, at the least, set a flag that you then test for and based on its value, handle the change.
我(目前)不是jQuery的用户,但我可以告诉您,在重新填充项目时需要暂时断开事件处理程序,或者至少设置一个标记然后根据其值进行测试,处理变化。
#2
3
Here's the final code that I ended up using, the flag (changeOnce
) worked great, thanks @Jason.
这是我最终使用的最终代码,标志(changeOnce)效果很好,感谢@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];
}
}
});
#3
0
Or you can just hide the option you don't want to show...
或者您可以隐藏您不想显示的选项...
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, this code does not work with IE6...
编辑:哦对不起,此代码不适用于IE6 ...
#1
3
I am not (currently) a user of jQuery, but I can tell you that you need to temporarily disconnect your event handler while you repopulate the items or, at the least, set a flag that you then test for and based on its value, handle the change.
我(目前)不是jQuery的用户,但我可以告诉您,在重新填充项目时需要暂时断开事件处理程序,或者至少设置一个标记然后根据其值进行测试,处理变化。
#2
3
Here's the final code that I ended up using, the flag (changeOnce
) worked great, thanks @Jason.
这是我最终使用的最终代码,标志(changeOnce)效果很好,感谢@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];
}
}
});
#3
0
Or you can just hide the option you don't want to show...
或者您可以隐藏您不想显示的选项...
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, this code does not work with IE6...
编辑:哦对不起,此代码不适用于IE6 ...