I understand that you need to follow fixed prices (it would not be a simple math equation).
For that reason I recommend you use an array on your code to hold the values for all prices. You would need to update the javascript array to represent the correct values.
Dividing prices on ranks/divisions is pointless. Instead of having two separate lists, you can merge two in one: B5, B4, B3, B2, B1, S5, S4, ...
(where B=Bronze
and S=Silver
).
So you have one single list of prices. What you need to do is get what index at the array is the current rank + division, and what index at the array is the desired rank + division.
When you have those two values, you just need to sum all values from the current index to the desired index, thus getting the accumulated values.
Also I recommend warning the user if they select a less rank/division than they currently are, or otherwise the price would be negative (having a surprising economic impact).
I added the first 3 ranks, you can do the remaining 2. From an UX point of view, I honestly recommend using a single select
, since there are not too many values, and it would mean less clicks for the user. If you want to go that route, let me know and I will update the script.
Show warning if user selected invalid rank/division (simpler)
var current_division,
desired_division;
// These are the flattened prices for all divisions.
// First is bronze div5, second is bronze div4, bronze div3,
// bronze div2, bronze div1, silver div 5, etc.
// You would need to add the remaining ranks and update the prices.
var prices = [
00,02,04,06,08,
10,12,14,16,18,
20,22,24,26,28
];
function getCurrentIndex() {
return (+document.getElementById("CRANK1").value +
+document.getElementById("CRANK2").value);
}
function getDesiredIndex() {
return (+document.getElementById("DRANK1").value +
+document.getElementById("DRANK2").value);
}
function total() {
var currentIndex = getCurrentIndex();
var desiredIndex = getDesiredIndex();
// If desiredIndex is greater than currentIndex, warn the user
// that they can't go from high to low!
if (desiredIndex < currentIndex) {
document.getElementById('prices').value = "You can't rank backwards";
return;
}
// Now you need to start summing the prices from currentIndex
// to desiredIndex.
var accumulatedPrice = 0;
for(var i = currentIndex; i <= desiredIndex; i++) {
accumulatedPrice += prices[i];
}
document.getElementById('prices').value = accumulatedPrice;
document.getElementById("prices").readOnly = true;
}
document.getElementById('divboost').addEventListener('change', function() {
total();
})
<form id="divboost" name="priceCalc" action="">
<br/>
<select id="CRANK1"> Current Rank
<option value="0">Bronze</option>
<option value="5">Silver</option>
<option value="10">Gold</option>
</select>
<br>
<br/>
<select id="CRANK2"> Current Divison
<option value="0">Division 5</option>
<option value="1">Division 4</option>
<option value="2">Division 3</option>
<option value="3">Division 2</option>
<option value="4">Division 1</option>
</select>
<br>
<br>
<br/>
<br/>
<select id="DRANK1"> Desired Rank
<option value="0">Bronze</option>
<option value="5">Silver</option>
<option value="10">Gold</option>
</select>
<br>
<br/>
<select id="DRANK2"> Desired Divison
<option value="0">Division 5</option>
<option value="1">Division 4</option>
<option value="2">Division 3</option>
<option value="3">Division 2</option>
<option value="4">Division 1</option>
</select>
<br>
<br>
<input type="text" id="prices">
<br/>
<br>
</form>
Hide invalid options (more complex)
var current_division,
desired_division;
// These are the flattened prices for all divisions.
// First is bronze div5, second is bronze div4, bronze div3,
// bronze div2, bronze div1, silver div 5, etc.
// You would need to add the remaining ranks and update the prices.
var prices = [
00,02,04,06,08,
10,12,14,16,18,
20,22,24,26,28
];
function getIndex(rankNode, divisionNode) {
return +rankNode.value + +divisionNode.value;
}
// show: can be a boolean or a function filter
function showHTMLCollection(htmlCollection, show) {
if (!htmlCollection || htmlCollection.length === 0) return;
show = typeof show === "undefined" ? true : show;
for (var i = 0; i < htmlCollection.length; i++) {
var computedShow = typeof show === "function" ? show(htmlCollection[i]) : show;
htmlCollection[i].disabled = !computedShow;
htmlCollection[i].style.display = computedShow ? "" : "none";
}
}
function validateSelectValue(selectNode) {
// If <select> has selected a disabled <option>, set to first valid value
var selectedOptionNode = selectNode.querySelector("option[value='" + selectNode.value + "']");
if (selectNode.value == "" || selectedOptionNode.disabled) {
for (var i = 0; i < selectNode.children.length; i++) {
if (!selectNode.children[i].disabled) {
selectNode.value = selectNode.children[i].value;
return;
}
}
// There's no more valid values on the list, set to empty
selectNode.value = "";
}
}
function total() {
var currentRankNode = document.getElementById("CRANK1");
var currentDivisionNode = document.getElementById("CRANK2");
var currentIndex = getIndex(currentRankNode, currentDivisionNode);
var desiredRankNode = document.getElementById("DRANK1");
var desiredDivisionNode = document.getElementById("DRANK2");
var desiredIndex = getIndex(desiredRankNode, desiredDivisionNode);
var desiredRankChildren = desiredRankNode.children;
// Hide ranks based on filter
showHTMLCollection(desiredRankChildren, function(option) {
// Show only desired ranks greater than the current rank,
// or if same rank, we are not on the last division
// otherwise we can't keep ranking
return (option.value > +currentRankNode.value ||
(option.value == +currentRankNode.value && +currentDivisionNode.value < 4));
});
// Make sure that the desired ranks select contains valid value
validateSelectValue(desiredRankNode);
var desiredDivisionChildren = desiredDivisionNode.children;
// Hide divisions based on filter
showHTMLCollection(desiredDivisionChildren, function(option) {
// If greater rank, show all divisions. If same rank,
// show only desired divisions greater than the current divisions
return (+desiredRankNode.value > +currentRankNode.value ||
(+desiredRankNode.value == +currentRankNode.value && option.value > +currentDivisionNode.value));
});
// Make sure that the desired ranks select contains valid value
validateSelectValue(desiredDivisionNode);
// Now you need to start summing the prices from currentIndex
// to desiredIndex.
var accumulatedPrice = 0;
for(var i = currentIndex; i <= desiredIndex; i++) {
accumulatedPrice += prices[i];
}
document.getElementById('prices').value = accumulatedPrice;
document.getElementById("prices").readOnly = true;
}
document.getElementById('divboost').addEventListener('change', function() {
total();
})
<form id="divboost" name="priceCalc" action="">
<br/>
<select id="CRANK1"> Current Rank
<option value="0">Bronze</option>
<option value="5">Silver</option>
<option value="10">Gold</option>
</select>
<br>
<br/>
<select id="CRANK2"> Current Divison
<option value="0">Division 5</option>
<option value="1">Division 4</option>
<option value="2">Division 3</option>
<option value="3">Division 2</option>
<option value="4">Division 1</option>
</select>
<br>
<br>
<br/>
<br/>
<select id="DRANK1"> Desired Rank
<option value="0">Bronze</option>
<option value="5">Silver</option>
<option value="10">Gold</option>
</select>
<br>
<br/>
<select id="DRANK2"> Desired Divison
<option value="0" disabled style="display: none">Division 5</option>
<option value="1" selected>Division 4</option>
<option value="2">Division 3</option>
<option value="3">Division 2</option>
<option value="4">Division 1</option>
</select>
<br>
<br>
<input type="text" id="prices">
<br/>
<br>
</form>