1,105,214 Community Members

Input/Output form with Instant Results?

Member Avatar
jonsan32
Junior Poster
154 posts since Aug 2010
Reputation Points: -3 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
Sponsor
 
0
 

I've searched a while, can't find this... I'm looking for a way to present two choices for values, then to have a result immediately appear based on those choice. IE... The first choice is an option between 1, 2, 3, 4, or 5 players... and the second choice is an option between 1, 5, 10, 25, or 50 workouts. In the following textarea (or whatever) I'd like a price or a set of prices (based on the combinations, not a math formula) to appear as the choices are made and again when they're toggled.

Here's my start. Any help will do.

<style type="text/css">
 select {
  font-family: verdana, Arial, san-serif;
  font-size:    26px;
 }
</style>


<select name="options" size="1">
 <option value="1">1</option>
 <option value="2">2</option>
 <option value="3">3</option>
 <option value="4">4</option>
 <option value="4">5</option>
 <option value="4">6</option>
 <option value="4">7</option>
 <option value="4">8</option>
 <option value="4">9</option>
 <option value="4">10</option>
 <option value="4">11</option>
 <option value="4">12</option>
</select> player(s)<br>

<select name="options" size="1">
 <option value="1">1</option>
 <option value="2">5</option>
 <option value="3">10</option>
 <option value="4">25</option>
 <option value="4">50</option>
</select> workout(s)<br><hr>


<font size=5>$90</font> per player for each workout.<br>
<font size=5>$450</font> per player for all workouts.<br>
<font size=5>$450</font> total.
Member Avatar
jonsan32
Junior Poster
154 posts since Aug 2010
Reputation Points: -3 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
Sponsor
 
0
 

Kinda like this: http://www.heroku.com/pricing#6-16 without the math and fanciness. I just need them to select two options, then spit out a predetermined answer based on the combo. Here's a thread that kinda asks my question, but it has no answer: http://www.codingforums.com/archive/index.php/t-135771.html

Thanks.

Member Avatar
jonsan32
Junior Poster
154 posts since Aug 2010
Reputation Points: -3 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
Sponsor
 
0
 

Maybe something like the following:

<FORM NAME="Calc">

<TABLE BORDER=6>

<TR>

<TD height=50 width=200 bgcolor="#000000"><center><select name="Input2" /> 
           <OPTION value="1">1 Player</OPTION>
           <OPTION value="2">2 Players</OPTION>
           <OPTION value="3">3 Players</OPTION>
           <OPTION value="4">4 Players</OPTION>
           <OPTION value="5">5 Players</OPTION>
           <OPTION value="6">6 Players</OPTION>
           <OPTION value="7">7 Players</OPTION>
           <OPTION value="8">8 Players</OPTION>
           <OPTION value="9">9 Players</OPTION>
           <OPTION value="10">10 Players</OPTION>
           <OPTION value="11">11 Players</OPTION>
           <OPTION value="12">12-15 Players</OPTION>

        </SELECT>
</center>
</TD>




<TD width="300" align="center" bgcolor="#000000">

<font color="#ffffff">$

<input type="text" name="Input" size="10" />



</TD>


</tr><tr>
<TD width="500" height=50 colspan=2 align="center" bgcolor="#000000">

<INPUT TYPE="button" NAME="one" VALUE=" 1 Workout " OnClick="Calc.Input2.value += 'Carrots '; Calc.Input.value += '+30'; Calc.Input.value = eval(Calc.Input.value)" />

<INPUT TYPE="button" NAME="four" VALUE=" 5 Workouts " OnClick="Calc.Input2.value += 'Eggs '; Calc.Input.value += '+200'; Calc.Input.value = eval(Calc.Input.value)" />

<INPUT TYPE="button" NAME="seven" VALUE=" 10 Workouts " OnClick="Calc.Input2.value += 'Bananas '; Calc.Input.value += '+70'; Calc.Input.value = eval(Calc.Input.value)" />

<INPUT TYPE="button" NAME="four" VALUE=" 25 Workouts " OnClick="Calc.Input2.value += 'Eggs '; Calc.Input.value += '+200'; Calc.Input.value = eval(Calc.Input.value)" />

<INPUT TYPE="button" NAME="seven" VALUE=" 50 Workouts " OnClick="Calc.Input2.value += 'Bananas '; Calc.Input.value += '+70'; Calc.Input.value = eval(Calc.Input.value)" />

</TD>

</TR>

</TABLE>

</FORM>

And I'd want the values to be predetermined, not mathematical based, so that I could offer deals and special offers.

Member Avatar
Airshow
WiFi Lounge Lizard
2,798 posts since Apr 2009
Reputation Points: 333 [?]
Q&As Helped to Solve: 393 [?]
Skill Endorsements: 11 [?]
Team Colleague
 
0
 

Jonsan,

Reading between the lines here, I think you want something that is part algorithmic and part lookup (to accommodate a discount structure).

Therefore, the rate per player per workout is to be discovered by lookup, but the other two values are to be calculated, based on the lookup value.

If I'm right, then the code will be something like this:

<!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;
}
</style>

<script type='text/javascript'>
onload = function() {
	var playersMenu = document.selections.players;
	var workoutsMenu = document.selections.workouts;
	var ppr = document.getElementById("perPlayerRate");
	var ppt = document.getElementById("perPlayerTotal");
	var tot = document.getElementById("total");

	if(playersMenu && workoutsMenu && ppr && ppt && tot) {
		playersMenu.onchange = workoutsMenu.onchange = function () {
			var players = parseInt(playersMenu[playersMenu.selectedIndex].value);
			var w = workoutsMenu[workoutsMenu.selectedIndex].value.split('@');
			var workouts = parseInt(w[0]);
			var rate = parseFloat(w[1]);
			ppr.innerHTML = rate.toFixed(2);
			ppt.innerHTML = (workouts * rate).toFixed(2);
			tot.innerHTML = (players * workouts * rate).toFixed(2);
		}
	}
	playersMenu.onchange();
}
</script>
</head>

<body>

<form name="selections">
<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)<br>

<select name="workouts">
 <option value="1@90">1</option>
 <option value="5@85">5</option>
 <option value="10@80">10</option>
 <option value="25@70">25</option>
 <option value="50@60">50</option>
</select> workout(s)<br>
</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>

</body>
</html>

Note how the discount structure is coded in the option-values of the workouts menu.

Airshow

Member Avatar
Airshow
WiFi Lounge Lizard
2,798 posts since Apr 2009
Reputation Points: 333 [?]
Q&As Helped to Solve: 393 [?]
Skill Endorsements: 11 [?]
Team Colleague
 
0
 

Jonsan, <OPTION value="12">12-15 Players</OPTION> would be no good. It would allow "rate per player per workout" to be looked up but without a specifying a definate number of players.

Airshow

Member Avatar
jonsan32
Junior Poster
154 posts since Aug 2010
Reputation Points: -3 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
Sponsor
 
0
 

Jonsan, <OPTION value="12">12-15 Players</OPTION> would be no good. It would allow "rate per player per workout" to be looked up but without a specifying a definate number of players.

Airshow

That is amazing, and I can definitely work with that. What would be perfect is if I could just call one of 50 different values whenever a combination is selected. The math could be used in regards to figuring out the per player for each workout, per player for all workouts, and total bit...

I'm trying to have a system that entices them to get more workouts with more people. Here's my real example: http://www.epicbasketball.com/p/pricing.html

If what I speak of is impossible/impractical/difficult, I can definitely work with what you've given me. Thanks a ton.

Member Avatar
Airshow
WiFi Lounge Lizard
2,798 posts since Apr 2009
Reputation Points: 333 [?]
Q&As Helped to Solve: 393 [?]
Skill Endorsements: 11 [?]
Team Colleague
 
2
 

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] + '<br><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<br>

<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)<br>

<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)<br>
</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:

  1. 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.
  2. 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

Member Avatar
jonsan32
Junior Poster
154 posts since Aug 2010
Reputation Points: -3 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
Sponsor
 
0
 

You're unreal. Thank you so much. No way I could've done this without you. Much appreciated.

Member Avatar
jonsan32
Junior Poster
154 posts since Aug 2010
Reputation Points: -3 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
Sponsor
 
0
 

Is there an easy way for me to only let them select a certain number of players based on which package they select? IE If they pick SQUAD, only the 5, 6, 7, and 8 options would be available to choose....

Not necessary, though. Thanks again.

Member Avatar
Airshow
WiFi Lounge Lizard
2,798 posts since Apr 2009
Reputation Points: 333 [?]
Q&As Helped to Solve: 393 [?]
Skill Endorsements: 11 [?]
Team Colleague
 
2
 

Jonsan,

Is there an easy way for me to only let them select a certain number of players based on which package they select? IE If they pick SQUAD, only the 5, 6, 7, and 8 options would be available to choose....

I realise that is a shortcoming of the code I posted above, so I have prepared an improved version.

Manipulating the "players" menu is rather difficult with standard javascript but much easier with the jquery lib. The code below uses jquery throughout.

<!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" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<!-- NOTE: Use own, locally served clpy of jquery in live production environment -->
<script type='text/javascript'>
var PRICING = function(){//NAMESPACE pattern
	var packages = {};//object of package objects, indexed by name
	var packages_array = [];//array of package names
	var breakpoints = [];

	function setBreakpoints(b) {
		breakpoints = b;
	}
	function addPackage(name, prices, description, values) {
		packages[name] = {prices:prices, description:description, values:values};
		packages_array.push(name);
	}
	function getDescription(package) {
		return packages[package.toUpperCase()].description;
	}
	function getValues(package) {
		return packages[package.toUpperCase()].values;
	}
	
	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){
		pckgs = (!pckgs) ? packages_array : pckgs;
		var $container = $("#"+containerID);
		var $table = $('<table>').addClass('border').appendTo($container);
		var $row, price;
		$row = $("<tr>").appendTo($table);
		$("<td>").appendTo($row);
		for(var j=0; j<breakpoints.length; j++) {
			$("<td>").appendTo($row).addClass('border padding').html(breakpoints[j] + "+");
		}
		for(var i=0; i<pckgs.length; i++) {
			$row = $("<tr>").appendTo($table);
			$("<td>").appendTo($row).addClass('border padding').html(pckgs[i] + '<br><span style="color:gray;font-size:9pt;">' + getDescription(pckgs[i]) + '</span>');
			for(var j=0; j<breakpoints.length; j++) {
				price = getPricePerItem(pckgs[i], breakpoints[j]).price;
				$("<td>").appendTo($row).addClass('border padding right').html(price ? "$" +  price : '-');
			}
		}
	}
	return {
		setBreakpoints: setBreakpoints,
		addPackage: addPackage,
		getDescription: getDescription,
		getValues: getValues,
		getPricePerItem: getPricePerItem,
		printPricingTable: printPricingTable
	};
}();

$(document).ready(function() {
	// ********************************************
	// ******* Here, establish all the data *******
	// ********************************************
	PRICING.setBreakpoints([1,5,10,25,50]);
	PRICING.addPackage('SOLO', [90,88,85,83,80], '1 Player', [1]),
	PRICING.addPackage('CREW', [27,25,24,23,21], '2-4 Players', [2,3,4]),
	PRICING.addPackage('EPIC', [null,null,null,null,15], '1 Member in a 9-12 Player group', [1]),
	PRICING.addPackage('SQUAD',[17,14,13,12,11], '5-8 Players', [5,6,7,8]),
	PRICING.addPackage('TEAM', [13,11,10,9,8], '9-15 Players', [9,10,11,12,13,14,15])
	// ********************************************
	// ********************************************

	PRICING.printPricingTable('pricingTable');

	var $playersMenu = $('[name="players"]');
	var $workoutsMenu = $('[name="workouts"]');
	var $packageMenu = $('[name="package"]');
	var $packageDescr = $("#packageDescr");
	var $ppr = $("#perPlayerRate");
	var $ppt = $("#perPlayerTotal");
	var $tot = $("#total");
	var cache = {};

	//shuffle all "players" options into a dummy select element.
	var $dummyMenu = $("<select>");
	$playersMenu.find("option").each(function() {
		$(this).appendTo($dummyMenu);
	});
	
	//function to constrain the "players" menu in response to the current package selection.
	function setPlayersMenu() {
		var package = $packageMenu.val();
		var values = PRICING.getValues(package);
		//first remove any previously cloned "players" options
		$playersMenu.find("option").each(function() {
			$(this).remove();
		});
		//now selectively clone options from the dummy menu.
		$dummyMenu.find("option").each(function(){
			var $opt = $(this);
			if($.inArray( Number($opt.attr('value')),values) > -1) {
				$opt.clone().appendTo($playersMenu);	
			}
		});
		$playersMenu.val(values[0]);//otherwise last appended option is selected.
	}

	function menuChange() {
		var package = $packageMenu.val();
		$packageDescr.html(PRICING.getDescription(package));
		if(package=='EPIC') {
			cache.workoutsMenuVal = $workoutsMenu.val();
			$workoutsMenu.val('50');
			$workoutsMenu.attr('disabled',true);
		}
		else {
			if(cache.workoutsMenuVal) {
				$workoutsMenu.val(cache.workoutsMenuVal);
				cache.workoutsMenuVal = null;
			}
			$workoutsMenu.attr('disabled',false);
		}
		var players = Number($playersMenu.val());
		var workouts = Number($workoutsMenu.val());
		var rate = PRICING.getPricePerItem(package,workouts).price;
		$ppr.html((rate) ? rate.toFixed(2) : '-');
		$ppt.html((rate) ? (workouts * rate).toFixed(2) : '-');
		$tot.html((rate) ? (players * workouts * rate).toFixed(2) : '-');
	}
	$packageMenu.change(setPlayersMenu);
	$().add($packageMenu).add($playersMenu).add($workoutsMenu).change(menuChange);
	setPlayersMenu();
	menuChange();
});
</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<br>

<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)<br>

<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>
 <option value="13">13</option>
 <option value="14">14</option>
 <option value="15">15</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>

I have played with this quite a bit and it seems to be robust but could be better commented than I have had time for.

Please note the comment against the jquery script (download then serve own copy of jquery). http://docs.jquery.com/Downloading_jQuery

Airshow

Member Avatar
jonsan32
Junior Poster
154 posts since Aug 2010
Reputation Points: -3 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
Sponsor
 
0
 

Surreal and perfect. I've already implemented this (http://www.epicbasketball.com/p/pricing.html), but will touch it up as time goes by. This is something I'll start within a year or so, and you've given more me of a chance to actualize my dream. I couldn't thank you more. I'm gonna make, and revisit it (and you) if anything ever comes into fruition monetarily. Thanks a ton!

Member Avatar
jonsan32
Junior Poster
154 posts since Aug 2010
Reputation Points: -3 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
Sponsor
 
0
 

.

Question Answered as of 2 Years Ago by Airshow
Member Avatar
Airshow
WiFi Lounge Lizard
2,798 posts since Apr 2009
Reputation Points: 333 [?]
Q&As Helped to Solve: 393 [?]
Skill Endorsements: 11 [?]
Team Colleague
 
0
 

Page looks good.

Good luck with your project, Jonsan. I hope the code serves you well.

Airshow

Member Avatar
jonsan32
Junior Poster
154 posts since Aug 2010
Reputation Points: -3 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
Sponsor
 
0
 

Before I ask another forum, I thought I'd just ask the source. Although changing the prices in the code is easy, I can't figure out the math enough to alter the formula. I'd like for the total price per workout to be more uniform. For example, if it's 2-4 players, I'd need them paying $92. So if 2 players are selected, it should be $46 each. If 3, it would be $30.66. And 4 would yield $23 each.

I've outlined my pricing on a spreadsheet if you (or anyone else) could look it over. I actually break it down by how much I'd like per player regardless of package chosen, but I wouldn't mind the same price being paid for any number of players within a given package.

https://spreadsheets.google.com/spreadsheet/pub?key=0AmWD_Na4J_4BdENpSVc4d1hjRDFMMTJxbTRKUDlXZ3c&output=html&chrome=false

My goal is to entice them subtly to get more kids in my program and to buy more workouts because of the gradual, yet noticeable, reduction in price.

Z per player for each workout.
Y per player for all workouts.
X total.

I'd need X to be a given number, then Y and Z to be dependent on X.

And no worries, you've helped more than enough. I can easily go elsewhere if you're time is slim. Thanks again.

Member Avatar
Airshow
WiFi Lounge Lizard
2,798 posts since Apr 2009
Reputation Points: 333 [?]
Q&As Helped to Solve: 393 [?]
Skill Endorsements: 11 [?]
Team Colleague
 
0
 

Jonsan,

I have had a good look and have a few observations:

  • The text and spreadsheet appear to impose different requirements. In particular, the text says "if it's 2-4 players, I'd need them paying $92" but the spreadsheet gives different prices for 2,3,4 players.
  • The discount structure as depicted in the spreadsheet appears to negate the need for packages (SOLO, CREW etc.) As it stands, each line entry in the table stands in its own right, without breakpoints.
  • The pricing structure as depicted in the spreadsheet appears to be upside down. Does the "volume discount" for number of players work in the wrong sense?

If I have understood correctly, I think these requirements can't be accommodated without major changes to what already exists. As far as I can tell, it's more than a simple tweak of the math.

Airshow

Member Avatar
jonsan32
Junior Poster
154 posts since Aug 2010
Reputation Points: -3 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
Sponsor
 
0
 

Sorry about that. Your point was exactly what I was trying to say that I'm okay with. I should've made the spreadsheet reflect that. Each package having its own price never entered my mind until I saw your first post, but I like it a lot. I've altered the spreadsheet at https://spreadsheets.google.com/spreadsheet/pub?hl=en_US&hl=en_US&key=0AmWD_Na4J_4BdENpSVc4d1hjRDFMMTJxbTRKUDlXZ3c&output=html

Just as the math is now, I only get $56 or less for one workout, and that's bad when the gym cost that much. I just need a certain total for each, then have the price per individual based off of that. And again, I can try asking elsewhere. Thanks for all your help.

Member Avatar
Airshow
WiFi Lounge Lizard
2,798 posts since Apr 2009
Reputation Points: 333 [?]
Q&As Helped to Solve: 393 [?]
Skill Endorsements: 11 [?]
Team Colleague
 
0
 

Jonsan,

That's a relief. The changes are minimal. Structurally all the html and javascript stay the same.

It's just a question of specifying price-per-workout in the data, rather than price per-player-per-workout, then dividing all through by the selected number of players in the math at lines 156-158, which all looks like this:

<!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" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<!-- NOTE: Use own, locally served copy of jquery in live production environment -->
<script type='text/javascript'>
var PRICING = function(){//NAMESPACE pattern
	var packages = {};//object of package objects, indexed by name
	var packages_array = [];//array of package names
	var breakpoints = [];

	function setBreakpoints(b) {
		breakpoints = b;
	}
	function addPackage(name, prices, description, values) {
		packages[name] = {prices:prices, description:description, values:values};
		packages_array.push(name);
	}
	function getDescription(package) {
		return packages[package.toUpperCase()].description;
	}
	function getValues(package) {
		return packages[package.toUpperCase()].values;
	}
	
	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};//price is $ per workout (all players)
		}
		return {package:package, breakpoint:b, price:null};
	}
	function printPricingTable(containerID, pckgs){
		pckgs = (!pckgs) ? packages_array : pckgs;
		var $container = $("#"+containerID);
		var $table = $('<table>').addClass('border').appendTo($container);
		var $row, price;
		$row = $("<tr>").appendTo($table);
		$("<td>").appendTo($row);
		for(var j=0; j<breakpoints.length; j++) {
			$("<td>").appendTo($row).addClass('border padding').html(breakpoints[j] + "+");
		}
		for(var i=0; i<pckgs.length; i++) {
			$row = $("<tr>").appendTo($table);
			$("<td>").appendTo($row).addClass('border padding').html(pckgs[i] + '<br><span style="color:gray;font-size:9pt;">' + getDescription(pckgs[i]) + '</span>');
			for(var j=0; j<breakpoints.length; j++) {
				price = getPricePerItem(pckgs[i], breakpoints[j]).price;
				$("<td>").appendTo($row).addClass('border padding right').html(price ? "$" +  price : '-');
			}
		}
	}
	return {
		setBreakpoints: setBreakpoints,
		addPackage: addPackage,
		getDescription: getDescription,
		getValues: getValues,
		getPricePerItem: getPricePerItem,
		printPricingTable: printPricingTable
	};
}();

$(document).ready(function() {
	// ********************************************
	// ******* Here, establish all the data *******
	// ********************************************
	PRICING.setBreakpoints([1,5,10,25,50]);
	PRICING.addPackage('SOLO', [90,88,86,84,82], '1 Player', [1]),
	PRICING.addPackage('CREW', [96,94,92,90,88], '2-4 Players', [2,3,4]),
	PRICING.addPackage('EPIC', [null,null,null,null,75], '1 Member', [1]),
	PRICING.addPackage('SQUAD',[104,102,100,98,96], '5-8 Players', [5,6,7,8]),
	PRICING.addPackage('TEAM', [118,116,114,112,110	], '9-15 Players', [9,10,11,12,13,14,15])
	// ********************************************
	// ********************************************

	PRICING.printPricingTable('pricingTable');

	var $playersMenu = $('[name="players"]');
	var $workoutsMenu = $('[name="workouts"]');
	var $packageMenu = $('[name="package"]');
	var $packageDescr = $("#packageDescr");
	var $ppr = $("#perPlayerRate");
	var $ppt = $("#perPlayerTotal");
	var $tot = $("#total");
	var cache = {};

	//shuffle all "players" options into a dummy select element.
	var $dummyMenu = $("<select>");
	$playersMenu.find("option").each(function() {
		$(this).appendTo($dummyMenu);
	});
	
	//function to constrain the "players" menu in response to the current package selection.
	function setPlayersMenu() {
		var package = $packageMenu.val();
		var values = PRICING.getValues(package);
		//first remove any previously cloned "players" options
		$playersMenu.find("option").each(function() {
			$(this).remove();
		});
		//now selectively clone options from the dummy menu.
		$dummyMenu.find("option").each(function(){
			var $opt = $(this);
			if($.inArray( Number($opt.attr('value')),values) > -1) {
				$opt.clone().appendTo($playersMenu);	
			}
		});
		$playersMenu.val(values[0]);//otherwise last appended option is selected.
	}

	function menuChange() {
		var package = $packageMenu.val();
		$packageDescr.html(PRICING.getDescription(package));
		if(package=='EPIC') {
			cache.workoutsMenuVal = $workoutsMenu.val();
			$workoutsMenu.val('50');
			$workoutsMenu.attr('disabled',true);
		}
		else {
			if(cache.workoutsMenuVal) {
				$workoutsMenu.val(cache.workoutsMenuVal);
				cache.workoutsMenuVal = null;
			}
			$workoutsMenu.attr('disabled',false);
		}
		var players = Number($playersMenu.val());
		var workouts = Number($workoutsMenu.val());
		var rate = PRICING.getPricePerItem(package,workouts).price;//price per workout
		$ppr.html((rate) ? (rate/players).toFixed(2) : '-');//per player rate
		$ppt.html((rate) ? (workouts * rate/players).toFixed(2) : '-');//per player total
		$tot.html((rate) ? (workouts * rate).toFixed(2) : '-');//total for all workouts
	}
	$packageMenu.change(setPlayersMenu);
	$().add($packageMenu).add($playersMenu).add($workoutsMenu).change(menuChange);
	setPlayersMenu();
	menuChange();
});
</script>
</head>

<body>

<form name="selections">
<table cellpadding="5" width="950" bgcolor="#000000">
<tr>
<td width="20%" valign="top" style="text-align:center;color:#FFF;">
<select name="package" style="margin-top:15px; background-color:#000; color:#FFF;">
 <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><br>
<div id="packageDescr"></div>

</td><td width="20%" style="text-align:center;" valign="top">

<select name="players" style="margin-top:15px; background-color:#000; color:#FFF;">
 <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>
 <option value="13">13</option>
 <option value="14">14</option>
 <option value="15">15</option>
</select> player(s)
 
</td><td width="20%" style="text-align:center;" valign="top">

<select name="workouts" style="margin-top:15px; background-color:#000; color:#FFF;">
 <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)

</td><td width="40%" valign="top">
 
<div id="prices" style="color:#ffffff;">
	<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>

</td></tr></table>
</form>

<hr>

<div id="pricingTable"></div>

</body>
</html>

I've left the "EPIC" package in there unmolested except for assuming a per workout rate of $75 at line 97 (easily changed).

Hope this correctly reflects your requirement.

Airshow

Member Avatar
jonsan32
Junior Poster
154 posts since Aug 2010
Reputation Points: -3 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
Sponsor
 
0
 

Picture perfect. Just had to make that one change you mentioned on EPIC. I'd be nowhere without you. Cheers!

You
This question has already been solved: Start a new discussion instead
Post:
Start New Discussion
View similar articles that have also been tagged: