Reputation: 729
the goal I'm aiming for is to check all the SELECT element for duplicated values (can't select the same value in 2 SELECTs)
I've done lots of searching but all of it 2 SELECTs not fixable for more
the logic I tried:
check function(){
declare values array, errorElement array
foreach(select element){ if the selected value exist in the value array(duplicate), add the element to the error element array
else add the value to the value array
}
if no error elements (no duplicated values), remove the error class from all selects
else foreach(select elemnt){
if the select exists in the error element array, set error class
else remove error class
}
}on any select change, call check function
and here the demo
function checkSelects()
{
var errorElements = []; var values = [];
$("select").each(function () {
if ($.inArray($(this).val(), values) !== -1) {
errorElements.push($(this).attr('id'));
} else {
values.push($(this).val());
}
});
if (errorElements.length === 0) {
$("select").each(function () {
$(this).removeClass('error');
});
} else {
$("select").each(function () {
if ($.inArray($(this).attr('id'), errorElements) !== -1) {
$(this).addClass('error');
} else {
$(this).removeClass('error');
}
});
}
}
$(function () {
$("select").change(function () {
checkSelects();
});
});
as for functionality it works perfect, setting the error class for one side of the duplicate conflict. but I'd like to make it even more clear and set the error class for both sides
is that going over-board? any pointer how to achieve that?
here's a screen-cap of it
selecting text1 in 2 SELECTs only sets the error class for the later element.
I'd like for both text1s to be shown in red
Upvotes: 1
Views: 3056
Reputation: 173622
Simply filter all select boxes with the same value and mark all of them at once.
I've also simplified the code a fair bit by clearing all errors when the check starts.
function checkSelects()
{
var $elements = $('select');
$elements
.removeClass('error')
.each(function () {
var selectedValue = this.value;
$elements
.not(this)
.filter(function() {
return this.value == selectedValue;
})
.addClass('error');
});
}
Upvotes: 3
Reputation: 25537
Use like this
function checkSelects() {
var errorElements = [];
var values = [];
$("select").each(function () {
if ($.inArray($(this).val(), values) !== -1) {
errorElements.push($(this).attr('id'));
} else {
values.push($(this).val());
}
});
if (errorElements.length === 0) {
$("select").each(function () {
$(this).removeClass('error');
});
} else {
$("select").each(function () {
if ($.inArray($(this).attr('id'), errorElements) !== -1) {
$(this).addClass('error');
$("select[value="+$(this).val()+"]").addClass('error'); <---- here
} else {
$(this).removeClass('error');
}
});
}
}
Eidt
I've simplified your code, you can use like this way too
function checkSelects() {
$(".error").removeClass("error");
$("select").each(function () {
if ($("select[value=" + $(this).val() + "]").length > 1) {
$("select[value=" + $(this).val() + "]").addClass('error');
}
});
}
$(function () {
$("select").change(function () {
checkSelects();
});
});
Upvotes: 4