Jonsan,
There's nothing impossible there but with a number of "packages" (solo, crew, etc.) we have to approach things slightly differently from before - namely by defining all the data in javascript rather than in the HTML.
I've had a play and come up with the following:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css">
select {
font-family: verdana, Arial, san-serif;
font-size: 26px;
}
#prices {
font-size: 12pt;
}
#prices span {
font-size: 18pt;
}
.border {
border: 1px solid #000;
}
.padding {
padding: 3px;
}
.right {
text-align: right;
}
</style>
<script type='text/javascript'>
var PRICING = function(){//NAMESPACE pattern
var packages = {};
var breakpoints = [];
function setBreakpoints(b) {
breakpoints = b;
}
function addPackage(name, prices, description) {
packages[name] = {prices:prices, description:description};
}
function getDescription(package) {
return packages[package.toUpperCase()].description;
}
function getPricePerItem(package, w) {
package = package.toUpperCase();//make the package string case insensitive
var w = ( !w || isNaN(w) || w<1 ) ? 1 : Math.round(w);//sanitize w (number of workouts)
for(var i=0; i<breakpoints.length; i++) {
if(w < breakpoints[i]) { break; }
}
if(packages[package.toUpperCase()]) {
var p = (packages[package].prices[i-1]) ? packages[package].prices[i-1] : null;
return {w:w, breakpoint:breakpoints[i-1], price:p};
}
return {package:package, breakpoint:b, price:null};
}
function printPricingTable(containerID, pckgs){
var container = document.getElementById(containerID);
if(!container) { return; }
var table = document.createElement('table');
table.className = 'border';
container.appendChild(table);
var row, cell, priceObj;
row = table.insertRow(0);
cell = row.insertCell(0);
for(var j=0; j<breakpoints.length; j++) {
cell = row.insertCell(j+1);
cell.className = 'border padding';
cell.innerHTML = breakpoints[j] + "+";
}
for(var i=0; i<pckgs.length; i++) {
row = table.insertRow(i+1);
cell = row.insertCell(0);
cell.className = 'border padding';
cell.innerHTML = pckgs[i] + '<span style="color:gray;font-size:9pt;">' + getDescription(pckgs[i]) + '</span>';
for(var j=0; j<breakpoints.length; j++) {
cell = row.insertCell(j+1);
cell.className = 'border padding right';
priceObj = getPricePerItem(pckgs[i], breakpoints[j]);
cell.innerHTML = priceObj.price ? "$" + priceObj.price : '-';
}
}
}
return {
setBreakpoints: setBreakpoints,
addPackage: addPackage,
getDescription: getDescription,
getPricePerItem: getPricePerItem,
printPricingTable: printPricingTable
};
}();
onload = function() {
// ********************************************
// ******* Here, establish all the data *******
// ********************************************
PRICING.setBreakpoints([1,5,10,25,50]);
PRICING.addPackage('SOLO', [90,88,85,83,80], '1 Player'),
PRICING.addPackage('CREW', [27,25,24,23,21], '2-4 Players'),
PRICING.addPackage('EPIC', [null,null,null,null,15], '1 Member in a 9-12 Player group'),
PRICING.addPackage('SQUAD',[17,14,13,12,11], '5-8 Players'),
PRICING.addPackage('TEAM', [13,11,10,9,8], '9-15 Player')
// ********************************************
// ********************************************
PRICING.printPricingTable('pricingTable', ['SOLO', 'CREW', 'EPIC', 'SQUAD', 'TEAM']);
var playersMenu = document.selections.players;
var workoutsMenu = document.selections.workouts;
var packageMenu = document.selections.package;
var packageDescr = document.getElementById("packageDescr");
var ppr = document.getElementById("perPlayerRate");
var ppt = document.getElementById("perPlayerTotal");
var tot = document.getElementById("total");
var cache = {};
if(playersMenu && workoutsMenu && packageMenu && ppr && ppt && tot) {
playersMenu.onchange = workoutsMenu.onchange = packageMenu.onchange = function () {
var package = packageMenu[packageMenu.selectedIndex].value;
packageDescr.innerHTML = PRICING.getDescription(package);
if(package=='EPIC') {
cache.playersMenuIndex = playersMenu.selectedIndex;
cache.workoutsMenuIndex = workoutsMenu.selectedIndex;
playersMenu.selectedIndex = 0;
workoutsMenu.selectedIndex = 4;
playersMenu.disabled = true;
workoutsMenu.disabled = true;
}
else {
if(cache.playersMenuIndex >= 0) {
playersMenu.selectedIndex = cache.playersMenuIndex;
cache.playersMenuIndex = -1;
}
if(cache.workoutsMenuIndex >= 0) {
workoutsMenu.selectedIndex = cache.workoutsMenuIndex;
cache.workoutsMenuIndex = -1;
}
playersMenu.disabled = false;
workoutsMenu.disabled = false;
}
var players = parseInt(playersMenu[playersMenu.selectedIndex].value);
var workouts = parseInt(workoutsMenu[workoutsMenu.selectedIndex].value);
var priceObj = PRICING.getPricePerItem(package,workouts);
var rate = priceObj.price;
ppr.innerHTML = (rate) ? rate.toFixed(2) : '-';
ppt.innerHTML = (rate) ? (workouts * rate).toFixed(2) : '-';
tot.innerHTML = (rate) ? (players * workouts * rate).toFixed(2) : '-';
}
}
playersMenu.onchange();
}
</script>
</head>
<body>
<form name="selections">
<select name="package">
<option value="SOLO">SOLO</option>
<option value="CREW">CREW</option>
<option value="EPIC">EPIC</option>
<option value="SQUAD">SQUAD</option>
<option value="TEAM">TEAM</option>
</select> Package
<div id="packageDescr"></div>
<select name="workouts">
<option value="1">1</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
</select> workout(s)
<select name="players">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
<option value="11">11</option>
<option value="12">12</option>
</select> player(s)
</form>
<hr>
<div id="prices">
<div><span>$</span><span id="perPlayerRate">0</span> per player for each workout.</div>
<div><span>$</span><span id="perPlayerTotal">0</span> per player for all workouts.</div>
<div><span>$</span><span id="total">0</span> total.</div>
</div>
<hr>
<div id="pricingTable"></div>
</body>
</html>
You will see that I have lumped a lot the complexity together in a javascript "namespace" called "PRICING", which is loaded with your data at lines 94-99.
Once loaded with data, PRICING becomes a glorified 2-dimensional lookup table, queried by calling PRICING.getPricePerItem(package, workouts) , where:package: is "SOLO", "CREW" etc.
workouts: is the number of workouts.
PRICING.getPricePerItem returns an object containing the following properties:.price: is the price per item (ie price per player).
.w: is the number of workouts actually used (after range checking) to lookup the price
.breakpoint: is the discounting breakpoint in which w lies.
.w and .breakpoint are included for completeness in case they are ever needed.
Also included is a utility method PRICING.printPricingTable(containerID, pckgs) , where:containerID: is the id of an HTML element in which the table is to be displayed
pckgs: an array of package names ["SOLO", "CREW", etc.], each of which will become a line entry in the table.
PRICING.printPricingTable is intended to allow the data to be inspected. The standard of presentation is unlikely to be good enough for production use.
The onload function contains examples of how PRICING might be used:to implement a pricing query as specified by a set of pulldown menus (similar to the code in the previous post above). You will see that your EPIC package requires some exception handling.
to print out the data table
Your requirement is probably different but the examples should give you enough of a clue to see how PRICING (or something very much like it) might be used.
Airshow