Reputation: 125
Given the following HTML selects:
<select id="HtmlSelect1">
<option value="1" selected="selected">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="HtmlSelect2">
<option value="1">1</option>
<option value="2" selected="selected">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<select id="HtmlSelect3">
<option value="1">1</option>
<option value="2">2</option>
<option value="3" selected="selected">3</option>
<option value="4">4</option>
</select>
<select id="HtmlSelect4">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4" selected="selected">4</option>
</select>
Scenario 1: If I change the selected value in HtmlSelect4 to 2, the selected value for HtmlSelect2 should change to 3 and the selected value for HtmlSelect3 should change to 4.
Scenario 2: If I change the selected value for HtmlSelect2 to 3, the selected value for HtmlSelect3 should change to 2.
In summary, I am reordering the selected value of the other drop down lists based upon one of the other drop down lists being changed. How do I accomplish this in JavaScript?
Note: The number of drop down lists and options could vary as these are being driven by data in a database.
Below is what I tried that should have theoretically worked for scenario 1, but didn't. It's a start in the direction of what I am trying to do.
<script>
function SelectChange(selectControl)
{
var controlDiv = document.getElementById("SomeDiv");
var controlSelects = controlDiv.getElementsByTagName("select");
for (var selectIndex = 0; selectIndex < controlSelects.length; selectIndex++)
{
if (controlSelects[selectIndex].id.indexOf("SelectControlPrefix") != -1)
{
if (controlSelects[selectIndex].value >= selectControl.value)
{
for (var optionIndex = 0; optionIndex < controlSelects[selectIndex].options.length; optionIndex++)
{
if (controlSelects[selectIndex].options[optionIndex].value == controlSelects[selectIndex].options.value + 1)
{
controlSelects[selectIndex].options[optionIndex].selected = "selected";
}
}
}
}
}
}
</script>
Upvotes: 1
Views: 254
Reputation: 22007
I'm having some trouble understanding the expected behavior, so I'll abstract it away in a function (Update 2 working as intended; added some comments to better explain my solution):
/* Returns a list of pairs [#element, value] to be updated */
function myBehaviour(n,o,v) {
var ret = [["#HtmlSelect" + n, v]]; // The new value should be what the user selected
// Shifts the other values, to the left of right
while ( n > o ) {
var next = $("#HtmlSelect" + (o+1));
ret.push(["#HtmlSelect" + o, next.val()]);
o++;
}
while ( n < o ) {
var next = $("#HtmlSelect" + (o-1));
ret.push(["#HtmlSelect" + o, next.val()]);
o--;
}
return ret;
}
That said, here's how you could accomplish this using jQuery:
var old;
$("select").focus(function() {
old = $(this).val(); // Saves the old value, before the change
}).change(function(e) {
var newValue = $(this).val(); // Save the new value
$(this).val(old); // Reverts to old, will change later
var oldPosition = parseInt(findOld(newValue)); // Find where the old value was
var newPosition = parseInt(this.id.substring("HtmlSelect".length));
$.each(myBehaviour(newPosition,oldPosition,newValue), function(i,pair) {
$(pair[0]).val(pair[1]); // Updates all them only after the correct positions were found
});
old = $(this).val(); // Saves the old again, in case the select is changed again
});
function findOld(value) {
return $("select").filter(function() {
return $(this).val() == value;
}).attr("id").substring("HtmlSelect".length);
}
If you need pure JavaScript, the code will get a little longer, but it can be accomplished by using document.getElementById
, onchange
, childNodes
, nodeValue
etc.
Upvotes: 1