Disable select option in group of select dropdowns when option is selected - javascript

What I'm trying to do: I have multiple select dropdowns, if an option is selected in one of the select dropdowns and the value exists in any of the other dropdowns the value should be disabled/unselectable, it again can become enabled/selectable if the selection is changed.
What happens with current code: it works about 50%, I can't pinpoint the issue, but I think because I'm applying a for loop some values get skipped and not disabled and sometimes the "Select" default option becomes disabled?!
Approach: The way I wrote my code was when a selection from the dropdown box occurs, enable all options, get the first dropdown's current selected value, if it's not the default "Select" then go through every dropdown box and disable any matching values, then repeat this process for the second dropdown's current selected value and so on.
Fiddle: http://jsfiddle.net/haakym/r2y73ndt/
Code:
HTML:
<div id="nomineeInfo">
<div>
<label>Manager</label>
<select class="positionTypes" id="pos_manager">
<option value="0">Select</option>
<option value="1">John Smith</option>
<option value="2">Jane Smith</option>
<option value="4">John Smoe</option>
</select>
</div>
<div>
<label>Deputy</label>
<select class="positionTypes" id="pos_deputy_manager">
<option value="0">Select</option>
<option value="1">John Smith</option>
<option value="2">Jane Smith</option>
<option value="3">John Doe</option>
</select>
</div>
<div>
<label>Finance</label>
<select class="positionTypes" id="pos_finance">
<option value="0">Select</option>
<option value="1">John Smith</option>
<option value="3">John Doe</option>
<option value="4">John Smoe</option>
</select>
</div>
Javascript:
$('#nomineeInfo').on('change', '.positionTypes', function () {
var selectedValue = $(this).val();
var dropdownOnChangeId = $(this).prop('id');
var positionTypesEn = ['manager', 'deputy_manager', 'finance'];
// set all enabled
for (var i = 0; i < 7; i++) {
$('#pos_'+positionTypesEn[i]).each(function(){
$("option", this).removeAttr('disabled');
});
};
for (var i = 0; i < 7; i++) {
// if position type selected value is not 0, i.e. if it's not "Select"
if( $('#pos_' + positionTypesEn[i]).val() != 0 ){
// go through each option in every dropdown
for (var j = 0; j < 7; j++) {
console.log( positionTypesEn[j] ); // show current dropdown
$('#pos_' + positionTypesEn[j] + ' option').each(function(k){
if( !$(this).is(':selected') ){
if( $(this).val() == selectedValue && $(this).val() != 0 ){
$(this).prop('disabled', 'true');
console.log('disabled: ' + $(this).val() );
}
}
});
}
}
}
});
Any help is much appreciated!

After enabling all the options, you need to go through all the menus, get their selected values, and re-disable all of them in the other menus, not just the one you just changed.
$(document).ready(function () {
$('#nomineeInfo').on('change', '.positionTypes', function () {
// Get the selected options of all positions
var allSelected = $(".positionTypes").map(function () {
return $(this).val();
}).get();
// set all enabled
$(".positionTypes option").removeAttr("disabled");
// Disable selected options in other positions
$(".positionTypes option:not(:selected):not([value='0'])").each(function () {
if ($.inArray($(this).val(), allSelected) != -1) {
$(this).attr('disabled', true);
}
});
});
});
DEMO

try
$("select.positionTypes").change(function () {
$("select.positionTypes option").prop('disabled', false);
$("select.positionTypes option:selected:not([value='0'])").each(function (i) {
$("select.positionTypes option:nth-child(" + ((+this.value) + 1) + ")").prop('disabled', true)
});
});
DEMO

Try this too, an optimized version
$("select.positionTypes").change(function () {
$("select.positionTypes option[value='" + $(this).data('index') + "']").prop('disabled', false);
$(this).data('index', this.value);
$("select.positionTypes option[value='" + this.value + "']:not([value='0'])").prop('disabled', true);
});
DEMO

Your html structure, classes and attempt is not bad but if you are using jQuery you should use its full advantages like .each function to make your live alot easier.
I would make an attempt like this:
$('.positionTypes').on('change', function () { //When any select changes...
var changedID = $(this).attr("id"); //Save id of select that was changed...
var selectedValue = $(this).val(); //Save value of select was changed...
if($(this).val() != "0") { //If we did not select a 0 value at all...
$('.positionTypes option').prop("disabled", false); //Enable all disabled options of all selects...
$('.positionTypes').each(function() { //Loop all existing selects
if($(this).attr("id") != changedID) { //If the select id is not our own select
$("#" + $(this).attr("id") + " option").each(function() { //loop all options of all selects except the one excluded by previous if clause
if($(this).attr("value") == selectedValue) { //if the value matches to saved value
$(this).prop("disabled", true); //Disable this one
}
});
}
});
};
});
I am not sure if this is 100% complete atleast it can disable options of other selects with identical value with a little bit more structured code.

Related

get unselected option from multiple select list

I have a multiple select list. When user unselects the selected option, I want to know the value of the unselected option made by user. How do I capture it?
My sample code is as below.
<select multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
I have following jquery code to allow user to select multiple options
$('option').mousedown(function(){
e.preventDefault();
$(this).prop('selected', $(this).prop('selected') ? false :true);
});
Mouse events aren't available cross browser
My suggestion would be always store array of previous values on the select.
On every change you can then compare to prior value array and once found update the stored array
$('#myselect').on('change', function() {
var $sel = $(this),
val = $(this).val(),
$opts = $sel.children(),
prevUnselected = $sel.data('unselected');
// create array of currently unselected
var currUnselected = $opts.not(':selected').map(function() {
return this.value
}).get();
// see if previous data stored
if (prevUnselected) {
// create array of removed values
var unselected = currUnselected.reduce(function(a, curr) {
if ($.inArray(curr, prevUnselected) == -1) {
a.push(curr)
}
return a
}, []);
// "unselected" is an array
if(unselected.length){
alert('Unselected is ' + unselected.join(', '));
}
}
$sel.data('unselected', currUnselected)
}).change();
DEMO
Great question, i wrote some codes for detecting unselected options using data attributes.
$('#select').on('change', function() {
var selected = $(this).find('option:selected');
var unselected = $(this).find('option:not(:selected)');
selected.attr('data-selected', '1');
$.each(unselected, function(index, value){
if($(this).attr('data-selected') == '1'){
//this option was selected before
alert("I was selected before " + $(this).val());
$(this).attr('data-selected', '0');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select multiple id="select">
<option data-selected=0 value="volvo">Volvo</option>
<option data-selected=0 value="saab">Saab</option>
<option data-selected=0 value="opel">Opel</option>
<option data-selected=0 value="audi">Audi</option>
</select>
If I understand you correctly, you want the option that just got unselected, right?
if so, try this:
create a variable "lastSelectedValue" (or whatever you want to call it). When you select an option, assign to it, when you change the selected option, you can get the value and use it, and assign to it again
var lastSelectedOption = '';
$('select').on('change', function(){
//do what you need to do
lastSelectedOption = this.val();
});
here's a fiddle: https://jsfiddle.net/ahmadabdul3/xja61kyx/
updated with multiple: https://jsfiddle.net/ahmadabdul3/xja61kyx/
not sure if this is exactly what you need. please provide feedback
As mentioned by others, the key would be to compare the previous selected values with current value. Since you need to figure out the removed value, you can check if the lastSelected.length > currentSelected.length and then simply replace the currentSelected from the lastSelected to get the results.
var lastSelected = "";
$('select').on('change', function() {
var currentSelected = $(this).val();
if (lastSelected.length > currentSelected.length) {
var a = lastSelected.toString().replace(currentSelected.toString(),"");
alert("Removed value : " + a.replace(",",""));
}
lastSelected = currentSelected;
});
Working example : https://jsfiddle.net/DinoMyte/cw96h622/3/
You can try make it
$('#link_to_id').find('option').not(':selected').each(function(k,v){
console.log(k,v.text, v.value);
});
With v.text get the Text
With v.value get the Value

Not allow duplicates in different HTML selects with the same content with javascript or JQuery

I have different selects with the same content and i want control that the user don't put the same value in two or more selects, i make this code, but i think there are some options better than this, I put here the code for share and at the same time ask if exist some better options. because i search some solution like this and i can't found.
$(function () {
function restrict_multiple(selector) {
// Here sets the current value in your alt
$(selector).each(function () {
$(this).attr("alt", $(this).val());
})
// trigger when the select change
$(selector).change(function () {
// Remove the hidden from the <option>
$(selector + " option").removeClass("hidden");
// I use thr alt attr, like an aid to maintain the actual selected value
$(this).attr("alt", $(this).val())
// Create an array with the selected options
var selected = new Array();
// Every selected option is assigned into this array
$(selector + " option:selected").each(function () {
selected.push(this.value);
})
// Apply the hidden the other select options
for (k in selected) {
if( selected[k] != "" ){
$(selector + "[alt!=" + selected[k] + "] option[value=" + selected[k] + "]").addClass("hidden")
}
}
})
// trigger to keep updated all selects
$(selector).each(function () { $(this).trigger("change"); })
}
//calling the function again sending the class
restrict_multiple(".excluyent-select");
})
.hidden { display: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<select name="participantes_1" id="participantes_1" class="excluyent-select" >
<option value="">Seleccionar</option>
<option value="1">111111111111111111</option>
<option value="2">222222222222222222</option>
<option value="3">333333333333333333</option>
<option value="4">444444444444444444</option>
<option value="5">555555555555555555</option>
<option value="6">666666666666666666</option>
<option value="7">777777777777777777</option>
<option value="8">888888888888888888</option>
<option value="9">999999999999999999</option>
</select><br />
<select name="participantes_2" id="participantes_2" class="excluyent-select" >
<option value="">Seleccionar</option>
<option value="1">111111111111111111</option>
<option value="2">222222222222222222</option>
<option value="3">333333333333333333</option>
<option value="4">444444444444444444</option>
<option value="5">555555555555555555</option>
<option value="6">666666666666666666</option>
<option value="7">777777777777777777</option>
<option value="8">888888888888888888</option>
<option value="9">999999999999999999</option>
</select><br />
Here i put the link to some example running: http://jsfiddle.net/hevercking/xdmd87se/
I changed the js code to do it this way:
$(function () {
function restrict_multiple(selector) {
$(selector).each(function () {$(this).attr("alt", $(this).val());});
$(selector).on('change', function () {
var ind = $(this).index();
var val = $(this).val();
var alt = $(this).attr('alt');
$(selector).each(function () {
$(this).find("option[value="+alt+"]").removeClass("hidden");
if($(this).index() != ind && val != "") {
$(this).find("option[value="+val+"]").addClass("hidden");
}
});
$(this).attr('alt', val);
});
}
restrict_multiple(".excluyent-select");
})
Let me know if it works correctly: http://jsfiddle.net/48zmLm7x/5/
Great! i like more your option, but the two options i discover have one problem and i don't know how to solve, if i generate the selects with one for.
for ( var i=0; i < 2; i++ ) {
$('<p><select name="grup_'+i+'" id="grup_'+i+'" class="excluyent-select")"><option value="">Seleccionar</option><option value="1">111111111111111111</option><option value="2">222222222222222222</option><option value="3">333333333333333333</option><option value="4">444444444444444444</option><option value="5">555555555555555555</option><option value="6">666666666666666666</option><option value="7">777777777777777777</option><option value="8">888888888888888888</option><option value="9">999999999999999999</option></select></p>').appendTo('#selecs');
}
$(function () {
function restrict_multiple(selector) {
$(selector).each(function () {$(this).attr("alt", $(this).val());});
$(selector).on('change', function () {
var ind = $(this).index();
var val = $(this).val();
var alt = $(this).attr('alt');
$(selector).each(function () {
$(this).find("option[value="+alt+"]").removeClass("hidden");
if($(this).index() != ind && val != "") {
$(this).find("option[value="+val+"]").addClass("hidden");
}
});
$(this).attr('alt', val);
});
}
restrict_multiple(".excluyent-select");
})
.hidden { display: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div id="selecs">
</div>
in this case don't run http://jsfiddle.net/hevercking/t3qg45v3/
I try make with onChange but only start to remove when i change one select the second time and if i change don't apear again until remove all options in the other select, i put here the example: http://jsfiddle.net/hevercking/e4scbtre/3/

Jquery : Select option of dropdown based on textbox text

I have tried to select option based on the textbox text.
Below is my html
<select id="select1">
<option value="">-- Please Select --</option>
<option value="277">12 +$2.99</option>
<option value="278">25 +$2.75</option>
<option value="279">50 +$2.50</option>
<option value="280">100 +$2.00</option>
<option value="281">250 +$1.90</option>
<option value="282">500 +$1.70</option>
<option value="283">1000 +$1.60</option>
<option value="284">2500 +$1.50</option>
<option value="285">5000 +$1.20</option>
<option value="286">10000 +$1.00</option>
<option value="287">25000 +$0.80</option>
</select>
<input type="text" id="pqr" />
And my js like bellow
$(function(){
$('#pqr').change(function(){
$txt = $( "#select1 option:contains('"+$(this).val()+"')" ).text();
$arr = $txt.split(" +");
$( "#select1").val($txt);
alert($arr[0])
$( "#select1" ).filter(function() {
alert($( this ).text > $arr[0]);
})
});
});
so if user enter text 12 or greater than 12 and bellow 25 than i want to select option second 12 +$2.99 and if user enter 1500 than option 1000 +$1.60 get selected. Basically i have try to compare option text before (+) sign and try to select based on that.
Please give me hint or any good help so solve this problem
At every change, iterate over all option elements and compare based on parseInt():
jQuery(function($) {
$('#pqr').on('change', function() {
var value = parseInt(this.value, 10),
dd = document.getElementById('select1'),
index = 0;
$.each(dd.options, function(i) {
if (parseInt(this.text, 10) <= value) {
index = i;
}
});
dd.selectedIndex = index; // set selected option
});
});
Demo
Loop through each option to compare the value. You can use something like this,
$(function () {
$('#pqr').change(function () {
var txtvalue = parseFloat($(this).val());
$("#select1 option").each(function () {
var splitText = $(this).next().text().split("+");
if (splitText.length > 1) {
if (txtvalue < parseFloat(splitText[0].trim())) {
$(this).prop("selected", true);
return false;
}
}
});
});
});
Fiddle
Try this :
$(function(){
$('#pqr').change(function(){
var inputVal = parseInt($(this).val());
$('#select1 option').each(function(){
var firstVal = $(this).text().split('+')[0];
var nextVal = inputVal;
if(!$(this).is(':last'))
$(this).next().text().split('+')[0];
if(parseInt(firstVal) <= inputVal && parseInt(nextVal) >=inputVal)
{
$(this).prop('selected',true);
}
});
});
});
Demo
The $arr[0] in the change callback function will be containing a text value which is not yet parsed to integer so the statement alert($( this ).text > $arr[0]); would not give desired output.
For checking the value lying between a range of select lists option you can use data attributes as followed:
<select id="select1">
<option value="" data-min="-" data-max="-"> Please Select </option>
<option value="277" data-min="12" data-max="25">12 +$2.99</option>
<option value="278" data-min="25" data-max="50">25 +$2.75</option>
This way you will not have to Parse the text of option into integer.
These data values can be retrieved for using jquery data function http://api.jquery.com/data/.
Also all the times you will not be getting the $('#pqr').val() as the text in the option's text so you will have to collect the value of text box and compare it with the range of each option(value >= data-max || value <= data-min).
$(function(){
$('#pqr').on("input", function(){
var text = this.value;
var options = $("#select1 > option");
var elementToSelect = options.eq(0);
if (text.match(/[0-9]+/)) {
elementToSelect = options.filter(function(){
return Number(this.innerText.split("+")[0]) <= text;
})
.eq(-1);
}
elementToSelect.attr("selected",true);
});
});

change selected option of dropDown using jQuery

I have a dropdown on change a popup appears with a warning that change the value will do some affects. when user select no the dropdown selected index is supposed to return to initial selected option. here is what I do:
function closeDeleteVariantsPopup(){
parent.$.fn.colorbox.close();
var elementSpecies= parent.document.getElementsByClassName("speice");
for(var i = 0;i<elementSpecies[0].options.length; ++i) {
alert(parent.document.getElementById("speciesHiddenValue").value);
if(elementSpecies[0].options[i].id === parent.document.getElementById("speciesHiddenValue").value) {
alert(parent.document.getElementById("speciesHiddenValue").value);
elementSpecies[0].selectedIndex = i;
break;
}
}
}
html & freemarker:
[#spring.bind "genomicReferenceBean.specie.id"/]
<select name="specie.id" id="specie.id" [#if !(genomicReferenceBean.specie?has_content) || genomicReferenceBean.specie.id==-1] multiple="multiple" [/#if] class='speice singleList' onchange='getMaterials()' >
[#if genomicReferenceInitializerBean.species?has_content]
[#list genomicReferenceInitializerBean.species as initializerValueBean]
<option for="selectSpecie" name="${initializerValueBean.name}" [#if genomicReferenceBean.specie?has_content && genomicReferenceBean.specie.id?number == initializerValueBean.id] selected="selected" [/#if] value="${initializerValueBean.id}">${initializerValueBean.name}</option>
[/#list]
[/#if]
</select>
<input type="hidden" id="speciesHiddenValue" value="${genomicReferenceBean.specie.id?number}"/>
now when I press no button the popup close and nothing happen
I used jQuery and it worked fine:
parent.$(".speice option").each(function(){
if($(this).val() === parent.document.getElementById("speciesHiddenValue").value) {
$(this).attr('selected', 'selected');
}
});

Jquery : Need to check a list of values in a combo box

I am totally confused how to make it.. Here is my problem.
I have n number of customized combo boxes (Which creates dynamically from the server side). Now i want to store the values of each combo box and need to validate by client side. If any one of the combo box val() == 0(i mean no option selected), then i need to show an error message. If all the combo box values are selected, then i need to show a a div in a popup. All these actions have to be happened if i click the save button.
Since these combo boxes are rendering dynamically, i cannot use its ID. My idea is to give a class name called combo and need to validate. Here is my code,
HTML (dynamicaaly generated)
<select class="combo">
<option selected="selected" value="0"></option>
<option value="1">Employee First Name (HR)</option>
<option value="2">Employee last Name (HR)</option>
<option value="3">Employee number (HR)</option>
<option value="4">NINO (HR)</option>
</select>
jQuery
$(document).ready(function(){
$('#save').click(function(){
var myLength = $('.combo option:selected').length;
alert(myLength);
if(myLength > 0){
alert('popups here');
count=count+1;
alert(count);
var maskHeight = $(document).height();
var maskWidth = $(window).width();
$('#mask').css({'width':maskWidth,'height':maskHeight});
$('#mask').fadeTo("fast",0.8);
var winH = $(window).height();
var winW = $(window).width();
$('.popups').css('top',winH/2-$('.popups').height()/2);
$('.popups').css('left',winW/2-$('.popups').width()/2);
$('.popups').show();
}
else
{
alert('No popups');
}
return false;
});
});
The idea is not working. Please suggest how to proceed... Many thanks :)
var trace = false;
$('#save').on('click', function() {
$('select.combo').each(function() {
if(this.value == 0){
trace = true;
return;
}
});
if(trace) {
// all combo not selected
alert('Please select all combo');
trace = false;
} else {
// all selected
alert('Thanks..');
}
});
How about this approach:
$('#save').click(function(){
var comboLength = $('.combo').length;
var selectedLength = $('.combo option:selected[value!=0]').length;
if (comboLength == selectedLength) { /* code for valid case*/}
else { /*code for invalid case*/; return false;}
})
TRY
HTML
<select class="combo" multiple="multiple">
<option selected="selected" value="0" >--SELECT ONE--</option>
<option value="1">Employee First Name (HR)</option>
<option value="2">Employee last Name (HR)</option>
<option value="3">Employee number (HR)</option>
<option value="4">NINO (HR)</option>
​
jQuery
var foo = {};
$('#submit').live('click', function() {
$('select.combo').each(function(i) {
var selected = $(this).val();
foo[i] = selected;
});
//this will remove first value ( blank having value=0)
var finalOutput = jQuery.grep(foo[0], function(value) {
//this will unselect the blank value
$('.combo option:eq(0)').prop('selected', false);
return value != "0";
});
if ($.isEmptyObject(finalOutput)) {
alert('please select atlest one')
}
else {
alert('Output:' + finalOutput)
}
})​​
Working DEMO

Categories