peter Ojeda
asked on
Dynamic Dropdowns
Hi experts I am attempting to create a scheduling app for my company. One issue I came across early was the chance of multiple name inserts. I have 5 select boxes that contains names. If a name is selected in box a, I don't want it available in select box B. How can I go about creating this?
Here's an example: https://jsfiddle.net/zephyr_hex/jkp9ant0/
HTML
jQuery
HTML
<select id="ddl1">
<option value="0">Select</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<select id="ddl2">
<option value="0">Select</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
jQuery
$(document).ready(function() {
$('#ddl1').on('change', function() {
var selected = $(this).val();
if (selected === "0") {
//enable disabled options
$('#ddl2 option:disabled').attr('disabled', false);
} else {
//disable option
$('#ddl2 option[value="' + selected + '"]').attr("disabled", true);
}
});
});
ASKER
Below is the code I am using. I am currently able to remove what is selected in box 1 from box 2, but I have about 200 text inputs so I am not sure how to go about doing this.
<!DOCTYPE html><html><head><title>CAPA</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<style>
body {background-color:#ffffb3;}
header {padding: 1em;color: white;background-color: lightblue;text-align: center;height:130px;}
.must {margin-bottom: 7px;}
h2{text-align: Left; position:relative; left:-10px; top:-25px;}
h1{position:relative; left:390px; top:-25px;}
#fm1 {width: 90em;border: 2px solid #ddb;margin: 1px auto;padding: 7px;background: #ffd;border-radius: 7px; padding-left:20px;}
div.back {position: fixed; top: 160px;right: -167px; width: 300px;}
</style>
</head>
<body>
<header>
<h2> <img src="logo.png" alt="Arc" style="width:90px;height:120px;"></h2>
</header>
<div class="back">
<form action="#">
<input type="submit" class="btn btn-primary btn-md" style="width:137px" value="Back">
</form>
<form action="#">
<input type="submit" class="btn btn-default btn-md" style="width:137px" value="Modify">
</form>
</div>
<form id="fm1" name="capa" method="post" action= "#">
<div class="must">
<h1>Crew A </h1>
</div>
<table><tr>
<th></th><th>Light Station</th><th>Packer</th><th>Packer</th><th>Packer</th><th>Packer</th><th>Palletizer</th><th>Relief</th></tr>
<tr>
<td>
<select id="Obv_Location" name="Obv_Location" required onchange=" document.getElementById('displayValue').value=this.options[this.selectedIndex].text; document.getElementById('idValue').value=this.options[this.selectedIndex].value;
" tabindex=1 style="width: 150px;">
<option value="Select_Location">Select Location</option>
<?php
$serverName = "test\test";
$connectionInfo = array( "Database"=>"test");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn ) {
// echo "Connection established.<br />";
}else{
echo "Connection could not be established.<br />";
die( print_r( sqlsrv_errors(), true));
}
$location_query = "select distinct LineID from test.dbo.CEVisual_Lines where SafetyAuditActive = 'Y' order by LineID";
$locationQ = sqlsrv_query( $conn, $location_query );
if( $locationQ === false) {
die( print_r( sqlsrv_errors(), true) );
}
$i=0;
$Lines[0] = '';
while( $row = sqlsrv_fetch_array( $locationQ, SQLSRV_FETCH_ASSOC) ) {
echo "<option value='".$row['LineID']."'>".$row['LineID']."</option>";
$Lines[$i] = $row['LineID'];
$i++;
}
$numLines = sizeof($Lines);
sqlsrv_free_stmt($locationQ);
?>
</select>
<select id="Obv_Location2" name="Obv_Location2" required onchange=" document.getElementById('displayValue').value=this.options[this.selectedIndex].text; document.getElementById('idValue').value=this.options[this.selectedIndex].value;
" tabindex=1 style="width: 150px;">
<option value="Select_Location">Select Location</option>
<?php
$serverName = "test\test";
$connectionInfo = array( "Database"=>"IS_DGMC");
$conn = sqlsrv_connect( $serverName, $connectionInfo);
if( $conn ) {
// echo "Connection established.<br />";
}else{
echo "Connection could not be established.<br />";
die( print_r( sqlsrv_errors(), true));
}
$location_query = "select distinct LineID from test.dbo.CEVisual_Lines where SafetyAuditActive = 'Y' order by LineID";
$locationQ = sqlsrv_query( $conn, $location_query );
if( $locationQ === false) {
die( print_r( sqlsrv_errors(), true) );
}
$i=0;
$Lines[0] = '';
while( $row = sqlsrv_fetch_array( $locationQ, SQLSRV_FETCH_ASSOC) ) {
echo "<option value='".$row['LineID']."'>".$row['LineID']."</option>";
$Lines[$i] = $row['LineID'];
$i++;
}
$numLines = sizeof($Lines);
sqlsrv_free_stmt($locationQ);
?>
</select>
</tr>
</table>
<input type="submit" value="Submit All" style="width: 150px; height:40px; margin-top: 1em; margin-left: 39%;">
</form>
<script>
var select1 = document.querySelector('select[name="Obv_Location"]'),
secondList= document.querySelectorAll('select[name="Obv_Location2"] option');
select1.onchange = function(){
var selected = this.value;
for(var i=0;i<secondList.length;i++){
if(secondList[i].value==selected)
secondList[i].style.display = "none";
else if(secondList[i].style.display == "none")
secondList[i].removeAttribute('style');
}
}
</script>
</body>
</html>
Assign a class to the "main" selectors and bind your event to the class. If you wrap your paired selectors in a div, you could just look for the sibling selector when hiding options.
ASKER
Sorry but I do not follow Zephyr I am pretty new to Javascript
This is what I mean:
https://jsfiddle.net/zephyr_hex/jkp9ant0/1/
HTML (notice how the selects are paired inside div tags, and the "main" select elements all have a class assigned)
jQuery
So, the event triggers when any of the "main" selects have an option selected. We then find the dependent select by navigating the DOM. In other words, we look for the next() select element, and operate on it. This allows you to use one block of code across hundreds of select elements by using a class and DOM navigation.
https://jsfiddle.net/zephyr_hex/jkp9ant0/1/
HTML (notice how the selects are paired inside div tags, and the "main" select elements all have a class assigned)
<div>
<select class="mainSelector">
<option value="0">Select</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<select>
<option value="0">Select</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</div>
<div>
<select class="mainSelector">
<option value="0">Select</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<select>
<option value="0">Select</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</div>
<div>
<select class="mainSelector">
<option value="0">Select</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<select>
<option value="0">Select</option>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
</div>
jQuery
$(document).ready(function() {
$('.mainSelector').on('change', function() {
var selected = $(this).val();
var sibling = $(this).next('select');
if (selected === "0") {
//enable disabled options
$(sibling).find('option:disabled').attr('disabled', false);
} else {
//disable option
$(sibling).find('option[value="' + selected + '"]').attr("disabled", true);
}
});
});
So, the event triggers when any of the "main" selects have an option selected. We then find the dependent select by navigating the DOM. In other words, we look for the next() select element, and operate on it. This allows you to use one block of code across hundreds of select elements by using a class and DOM navigation.
ASKER
Awesome I think that is exactly what I needed. One question though, how about if there are three select boxes? I was playing around with this but I do not understand how to make that work.
So, the option selected in the 2nd drop down should impact the options available in the 3rd drop down?
ASKER
Yes well option 1 and 2. If option 1 is picked in dropdown box 1, option 2 is picked in dropdown 2, then only option 3 will be available in the third dropdown
So, there are two changes to the code that I provided that would accomplish this.
1) Add the "mainSelector" class to the second drop down as well
2) Change this line:
to this:
Here's an example of the above: https://jsfiddle.net/zephyr_hex/jkp9ant0/2/
Note: if all of your selectors should behave this way (where picking an option from one should impact the other two inside the div), you can get rid of the class name and just bind to the select element itself.
Here's an example of binding to the select element itself: https://jsfiddle.net/zephyr_hex/jkp9ant0/3/
1) Add the "mainSelector" class to the second drop down as well
2) Change this line:
var sibling = $(this).next('select');
to this:
var sibling = $(this).nextAll('select');
Here's an example of the above: https://jsfiddle.net/zephyr_hex/jkp9ant0/2/
Note: if all of your selectors should behave this way (where picking an option from one should impact the other two inside the div), you can get rid of the class name and just bind to the select element itself.
Here's an example of binding to the select element itself: https://jsfiddle.net/zephyr_hex/jkp9ant0/3/
ASKER
Thankyou very much that's very helpful. I know this question has been drawn out but is there any way I can make it so if it is picked in box 3 it can't be picked in box 1? right now it is only based off of previous boxes so if its selected in 1 it can't be selected in 3, but if it is in box 3 it can't be selected in box 1
ASKER
Or maybe a way to unselect box 3 if box 1 was changed to the value of box 3
In that case, you will want to get rid of the class and just bind your event to the select tag. Then use siblings() instead of nextAll() to disable the options. You will need to iterate over each of the siblings because there will be more than one.
https://jsfiddle.net/zephyr_hex/jkp9ant0/4/
jQuery
https://jsfiddle.net/zephyr_hex/jkp9ant0/4/
jQuery
$(document).ready(function() {
$('select').on('change', function() {
var selected = $(this).val();
var siblings = $(this).siblings('select');
if (selected === "0") {
//enable disabled options
$(siblings).each(function() {
$(this).find('option:disabled').attr('disabled', false);
});
} else {
//disable option
$(siblings).each(function() {
$(this).find('option[value="' + selected + '"]').attr("disabled", true);
})
}
});
});
ASKER
Hi Zephyr thankyou very much. I've been testing this method and one small issue I came accross. Say box 1 you select A then change it to B, then C, in Box 2 you can't use A or B
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Can you please share the code as well so we can look into the issue and suggest you possibilities.