Reputation: 5651
I have a set of drop down lists (8 in all). All drop downs have the same set of drop down options available to them. However the business requirement is to make sure that the user cannot select the same option more than once.
Looking at the problem, at first it appears simple but it's rapidly becoming lots of code. However it seems like a relatively common problem. Does anyone know of a solution, have any tips on how to do this without writing reams of Javascript. Some sort of reusable jquery plugin might be handy for this too. Does one exist?
One issue is that when a select item is chosen, it then becomes unavailable to the other select lists. The item is removed from the other select drop downs. When it becomes available again (a drop down changes) it needs to be inserted at the correct point in the list (the drop down options have an order). This is the bit where my solution has started to get quite complex.
Upvotes: 0
Views: 1811
Reputation: 6304
Personally, the way I'd implement it is to have a "master" drop down containing all possible options, simply for the purpose of caching. These options are then replicated in each of the "slave" drop downs. Whenever any slave drop down is changed, they're all re-populated again to ensure that no two drop downs can share the same selected value.
For the purpose of demonstration, I've only worked with 3 drop down lists in the code below, but it should scale up pretty easily. Just add mode drop downs and make sure they contain the attribute class="slave"
.
Also, if you want any of the options to be immune from being removed, so that it's possible to exist in all of your slave drop downs (such as the default option in the code below), just add the attribute class="immune"
to the option tag in the master drop down.
<script type="text/javascript">
// document - on load
$(document).ready(function() {
// initially populate all the drop downs
PopulateAllDropDowns();
// populate all drop downs on each subsequent change
$('select.slave').change(function(){
PopulateAllDropDowns();
});
});
function PopulateAllDropDowns()
{
// populate all the slave drop downs
$('select.slave').each(function(index){
PopulateDropDown($(this).attr('id'));
});
}
function PopulateDropDown(id)
{
// preserve the selected value
var selectedValue = $('#'+id).val();
// clear current contents
$('#'+id).html('');
// attempt to add each option from the master drop down
$('select#ddlTemplate').children('option').each(function(index){
// scope-safe var
var masterOptionValue = $(this).val();
// check if option is in use in another slave drop down, unless it's immune
var optionInUse = false;
if (!$(this).hasClass("immune"))
{
$('select.slave option:selected').each(function(index){
if (masterOptionValue == $(this).val() )
optionInUse = true;
});
}
// if it's not in use, add it to this slave drop down
if (!optionInUse)
{
// create new option
var newOption = $('<option></option>').val($(this).val()).html($(this).text());
// ensure selected value is preserved, if applicable
if (selectedValue == $(this).val())
newOption.attr('selected', 'selected')
// add the option
$('#'+id).append(newOption);
}
});
}
</script>
<form>
<!-- master drop down -->
<select id="ddlTemplate" class="master" style="display:none">
<option value="" class="immune">Select ...</option>
<option value="a">Option A</option>
<option value="b">Option B</option>
<option value="c">Option C</option>
<option value="d">Option D</option>
<option value="e">Option E</option>
</select>
<!-- slave drop downs -->
<select id="ddlOne" class="slave"></select>
<select id="ddlTwo" class="slave"></select>
<select id="ddlThree" class="slave"></select>
</form>
Hope that helps.
Upvotes: 2
Reputation: 2870
The simplest way to do what you want is binding a function in the select event from dropdown list that filter content from all other dropdowns and remove or disable the options with value already selected.
To keep the order from your list, cache the options list in array, then you can remove and add in the right position, or remove all options and re-add the current possible options.
If you want re-select the cached already chosen options, and you don't lose anything.
Upvotes: 0