Reputation: 838
I have 4 select items in my form. When the user selects one item in any of selects, I want this item to be disabled in each other select element. My problem happens when I select all option items, because it disables everything. How can I to enabled/disabled the items when they are selected/deselect?
First referee: <select class="d1">
<option>One</option>
<option>Two</option>
<option>Three</option>
<option>Four</option>
<option>Five</option>
<option>Six</option>
</select>
Second referee: <select class="d2">
<option>One</option>
<option>Two</option>
<option>Three</option>
<option>Four</option>
<option>Five</option>
<option>Six</option>
</select>
Third referee: <select class="d3">
<option>One</option>
<option>Two</option>
<option>Three</option>
<option>Four</option>
<option>Five</option>
<option>Six</option>
</select>
Fourth referee:<select class="d4">
<option>One</option>
<option>Two</option>
<option>Three</option>
<option>Four</option>
<option>Five</option>
<option>Six</option>
</select>
$(document).ready(function () {
$('.d1, .d2, .d3, .d4').change(function () {
var V1 = $('.d1').find(":selected").text();
var V2 = $('.d2').find(":selected").text();
var V3 = $('.d3').find(":selected").text();
var V4 = $('.d4').find(":selected").text();
$('.d1, .d2, .d3, .d4').children().each(function (index, element) {
if ($(element).text() == V1 ) {
$(this).prop('disabled', true);
}
if ($(element).text() == V2) {
$(this).prop('disabled', true);
}
if ($(element).text() == V3) {
$(this).prop('disabled', true);
}
if ($(element).text() == V4) {
$(this).prop('disabled', true);
}
});
});
});
Upvotes: 5
Views: 2867
Reputation: 25
Try this may be this will work
$(document).ready(function () {
$('.d1, .d2, .d3, .d4').change(function () {
var V1 = $('.d1').find(":selected").text();
var V2 = $('.d2').find(":selected").text();
var V3 = $('.d3').find(":selected").text();
var V4 = $('.d4').find(":selected").text();
$('.d1, .d2, .d3, .d4').children().each(function (index, element) {
if ($(element).text() == V1 ) {
$(this).prop('disabled', true).siblings().removeAttr('disabled');;
}
if ($(element).text() == V2) {
$(this).prop('disabled', true).siblings().removeAttr('disabled');;
}
if ($(element).text() == V3) {
$(this).prop('disabled', true).siblings().removeAttr('disabled');;
}
if ($(element).text() == V4) {
$(this).prop('disabled', true).siblings().removeAttr('disabled');;
}
});
});
});
Upvotes: 0
Reputation: 10202
A lot of answers are already there (and good ones two), but I was busy creating my own version, so I'll post it anyway ;) I've made it a bit more flexible by selecting the select input by name, and the option by value.
HTML
First referee:
<select name="d1">
<option value="1">One</option>
<option value="2">Two</option>
<!-- and so on -->
</select>
Second referee:
<select name="d2">
<!-- same options here -->
</select>
<!-- even more dropdowns here -->
Javascript
The key here is to store the "old" value somewhere before it is changed, so you can re-enable the options on the other dropdowns.
$('select[name^="d"]').focus(function(){
// Store the current value in the data attribute, for use later (whenever it's actually changed)
$(this).data('previouslySelected', $(this).val());
}).change(function () {
// Grab current (new) and old value (see focus event)
var currentValue = $(this).val();
var oldValue = $(this).data('previouslySelected');
// Select all select inputs, but NOT the current one
$('select[name^="d"]').not(this).each(function(i, e) {
// disable currently selected
var opt = $('option[value="' + currentValue + '"]', this).prop('disabled', true);
// re-enable previously selected item
$('option[value="' + oldValue + '"]', this).prop('disabled', false);
});
});
And of course, here is the fiddle ;)
Upvotes: 0
Reputation: 171679
Here's a solution that instead of disabling the choices removes them instead. Subsequent changes will also be updated.
I added extra class ref_select
to each element as well as value
for each option
$(function () {
var $ref_select = $('.ref_select');
/* cache option html */
var optHtml = $ref_select.first().html();
$ref_select.on('change', function () {
/* make array of all selected values*/
var selecteds=$ref_select.find('option:selected').map(function(){
return this.value
}).get();
/* rebuild the other select elements*/
$ref_select.not(this).each(function(){
var selVal=this.value || '';
/* create new set of options with filtered values*/
var $opts=$(optHtml).filter(function(){
return $.inArray(this.value,selecteds) ==-1 || this.value ==selVal
});
/* replace children*/
$(this).html($opts).val(selVal);
});
});
});
Upvotes: 0
Reputation: 247
Try this script. It works by storing the index of the "previous" value on focus, and then sets that to be not disabled when looping through to disable the new one.
Keep in mind, using index will only work if all your options are in the same order.
$(document).ready(function () {
var origIndex;
$('.d1, .d2, .d3, .d4').focus(function() {
origIndex = $(this).find(":selected").index();
}).change(function () {
var index = $(this).find(":selected").index();
$('.d1, .d2, .d3, .d4').each(function() {
$(this).children().eq(index).prop("disabled", true);
$(this).children().eq(origIndex).prop("disabled", false);
});
});
});
Upvotes: 0
Reputation: 20250
Set disabled
to false
on all <option>
elements in the first line of your change handler. Then, loop over each <select>
and disable any <option>
s in sibling <select>
s where this.value
matches:
var $select = $('.d1, .d2, .d3, .d4');
$select.on('change', function() {
$select.find('option').prop('disabled', false);
$select.each(function() {
$(this).siblings('select').find('option')
.filter('[value="' + this.value + '"]').prop('disabled', true);
});
});
Upvotes: 1
Reputation: 33870
If your select list are all the same you can base the disable on their index :
$(document).ready(function () {
var $select = $('.d1, .d2, .d3, .d4').change(function () {
$select.find('option').prop('disabled', false); //All option enabled
$select.each(function(){
var $this = $(this), index = $this.find(':selected').index(); //Get the index
$select.not(this).find('option:nth-child('+ (index+1) +')').prop('disabled', true); //Select option base on their position and disable them
})
});
});
Fiddle : http://jsfiddle.net/u6eCL/16/
Else, here the code based on the text :
$(document).ready(function () {
var $select = $('.d1, .d2, .d3, .d4').change(function () {
$select.find('option').prop('disabled', false); //All option enabled
$select.each(function(){
var $this = $(this), text = $this.find(':selected').text(); //Get the text
$select.not(this).find('option').filter(function(){
return $(this).text() === text
}).prop('disabled', true); //Select option base on their text and disable them
})
});
});
Upvotes: 2
Reputation: 835
Try with:
$(this).attr('disabled', 'disabled');
instead of
$(this).prop('disabled', true);
Upvotes: 0
Reputation: 43156
You can try the following as a quick fix
$(document).ready(function () {
$('.d1, .d2, .d3, .d4').change(function () {
var V1 = $('.d1').find(":selected").text();
var V2 = $('.d2').find(":selected").text();
var V3 = $('.d3').find(":selected").text();
var V4 = $('.d4').find(":selected").text();
$('select option').prop('disabled',false); // reset everything
$('.d1, .d2, .d3, .d4').children().each(function (index, element) {
if ($(element).text() == V1) {
$(this).prop('disabled', true);
}
if ($(element).text() == V2) {
$(this).prop('disabled', true);
}
if ($(element).text() == V3) {
$(this).prop('disabled', true);
}
if ($(element).text() == V4) {
$(this).prop('disabled', true);
}
});
});
});
Upvotes: 3