Reputation: 4300
I have several select boxes (the exact number is dynamic), each containing the same values. When an option is selected in one box, I want to disable
this value in all the other select boxes.
As shown in this jsFiddle, when you select a value in the first select box, it correctly disables that value in the second select box. When you select a value in the second select box, the code correctly disables that value in the first select box; however, it enables (i.e. does not disable) the original selected value from the first select box, in the second box.
To replicate: select Value One
for the first select box. Value One
is correctly disabled in the second select box. Now select Value Two
in the second select box. It's disabled in the first select box, but now Value One
is incorrectly enabled in the second select box.
After hours of trying to diagnose the issue, it seems that my .each
statement only processes the first select box, and does not advance to the second select box to iterate over it's values. Edit: Actually it doesn't stop processing; if you remove line 22-24 from the jsFiddle (the else statement that enables the values that are no longer selected), and then select Value One
then Value Three
in the first select box the code correctly processes the second select box and disables Value One
and Value Three
. So it's a problem with the multiple iterations over selectedAreas
?
How can I iterate over all the options from all the select boxes on the page with my area_select
class?
My jQuery:
$(function() {
$(document).on('change', '.area_select', function (e) {
generateSelectedAreas();
});
});
function generateSelectedAreas()
{
var selectedAreas = new Array();
//Get all the currently selected areas
$('.area_select option:selected').each(function () {
if ($(this).val() != '') {
selectedAreas.push($(this).val());
}
});
//The selectedAreas array contains all the correct values, as shown here
console.log(selectedAreas);
$('.area_select>option:not(:selected)').each(function () {
for(var counter=0; counter < selectedAreas.length; counter++) {
if (selectedAreas[counter] == $(this).val()) {
$(this).attr("disabled", true);
}
else {
$(this).attr("disabled", false);
}
}
});
return selectedAreas;
}
Upvotes: 0
Views: 2294
Reputation: 40459
Okay this is a little complicating but I will do my best to explain what is going on here.
The main problem stems from the following statement:
$('.area_select>option:not(:selected)').each(function () {
for(var counter=0; counter < selectedAreas.length; counter++) {
if (selectedAreas[counter] == $(this).val()) {
$(this).attr("disabled", true);
}
else {
$(this).attr("disabled", false);
}
}
});
Say that I have two select
elements:
Select 1
---------
Value 1
Value 2
Value 3
Value 4
Select 2
---------
Value 1
Value 2
Value 3
Value 4
You iterate through each option not currently selected:
Select 1 (Selected Value 3)
---------
Value 1 (Enabled)
Value 2 (Enabled)
Value 4 (Enabled)
Select 2 (Selected Value 4)
---------
Value 1 (Enabled)
Value 2 (Enabled)
Value 3 (Enabled)
selectedAreas = ['Value 3', 'Value 4']
you then go through each individual value in selectedAreas
and say
if the selectedArea value is equal to the current
option
then disable it, or else enable it
Now look what happens when you go through each value:
If Option Equals Value 3
Select 1 (Selected Value 3)
---------
Value 1 (Enabled)
Value 2 (Enabled)
Value 4 (Enabled)
Select 2 (Selected Value 4)
---------
Value 1 (Enabled)
Value 2 (Enabled)
Value 3 (Disabled)
If Option Equals Value 4
Select 1 (Selected Value 3)
---------
Value 1 (Enabled)
Value 2 (Enabled)
Value 4 (Disabled)
Select 2 (Selected Value 4)
---------
Value 1 (Enabled)
Value 2 (Enabled)
Value 3 (Enabled)
You see, it overlaps.
What you want to do is the following:
$(function() {
$(document).on('change', '.area_select', function (e) {
generateSelectedAreas();
});
function generateSelectedAreas()
{
//enable all options, otherwise they overlap and cause probl
$('.area_select option').each(function () {
$(this).prop('disabled', false);
});
$('.area_select option:selected').each(function () {
var select = $(this).parent(),
optValue = $(this).val();
if($(this).val()!=''){
$('.area_select').not(select).children().filter(function(e){
//filters all children equal to option value
if($(this).val()==optValue)
return e
}).prop('disabled', true);
}
});
}
});
DEMO: http://jsfiddle.net/dirtyd77/J6ZYu/3/
Sorry for the long explanation! Hope this helps and let me know if you have any questions!
Upvotes: 1