This is *not* required on the cart or checkout pages, so should not be place in those templates.
<script type="text/javascript" charset="utf-8"> //<![CDATA[ $(document).ready(function() { TOTALCLASS = "_total"; // Create an array to store all the adjustments ADJUST = []; // Set the handlers for each *_adjust form element $("[class$=_adjust]").each(function() { var pID = $(this).attr("class").split("_")[0]; if (typeof(ADJUST[pID]) === "undefined") { // Create the array for this product code ADJUST[pID] = []; } switch(this.tagName) { case "SELECT": // Store the current value ADJUST[pID][$(this).attr("name")] = $(this).val(); $(this).change(function() { var pID = $(this).attr("class").split("_")[0]; ADJUST[pID][$(this).attr("name")] = $(this).val(); recalcTotal(); }) break; case "INPUT": switch($(this).attr("type")) { case "checkbox": if ($(this).is(":checked")) { ADJUST[pID][$(this).attr("name")] = $(this).val(); } else { ADJUST[pID][$(this).attr("name")] = ""; } $(this).bind(($.browser.msie ? "click" : "change"), function () { var pID = $(this).attr("class").split("_")[0]; if ($(this).is(":checked")) { ADJUST[pID][$(this).attr("name")] = $(this).val(); } else { ADJUST[pID][$(this).attr("name")] = ""; } recalcTotal(); }) break; case "radio": // Store the current value if ($(this).is(":checked")) { ADJUST[pID][$(this).attr("name")] = $(this).val(); } $(this).bind(($.browser.msie ? "click" : "change"), function () { var pID = $(this).attr("class").split("_")[0]; ADJUST[pID][$(this).attr("name")] = $(this).val(); recalcTotal(); }) break; } break; } }); recalcTotal(); }); function parseAttributes(sValue) { sValue = sValue.match(/{(.*?)}/); if (sValue) { aValue = sValue[1].split("|"); for(i in aValue) { aParts = aValue[i].match(/p([\+|\-|\:])(.+)/); if (aParts) { return aParts; } } } return; } function recalcTotal() { for(p in ADJUST) { price = Number($("#"+p+"_price").val()); adjustment = 0; for (a in ADJUST[p]) { var aParts = parseAttributes(ADJUST[p][a]); if (aParts) { var modifier = aParts[1]; switch(modifier) { case ":": price = Number(aParts[2]); break; case "+": adjustment += Number(aParts[2]); break; case "-": adjustment -= Number(aParts[2]); break; } } } price += adjustment; $("."+p+TOTALCLASS).html(fc_CurrencyFormatted(price)); } } //]]> </script>
<script type="text/javascript" charset="utf-8"> //<![CDATA[ $(document).ready(function() { TOTALCLASS = "_total"; // Create an array to store all the adjustments ADJUST = []; // Set the handlers for each *_adjust form element $("[class$=_adjust]").each(function() { var pID = $(this).attr("class").split("_")[0]; if (typeof(ADJUST[pID]) === "undefined") { // Create the array for this product code ADJUST[pID] = []; } switch(this.tagName) { case "SELECT": // Store the current value ADJUST[pID][$(this).attr("name")] = $(this).val(); $(this).change(function() { var pID = $(this).attr("class").split("_")[0]; ADJUST[pID][$(this).attr("name")] = $(this).val(); recalcTotal(); }) break; case "INPUT": switch($(this).attr("type")) { case "checkbox": if ($(this).is(":checked")) { ADJUST[pID][$(this).attr("name")] = $(this).val(); } else { ADJUST[pID][$(this).attr("name")] = ""; } $(this).bind("change", function () { var pID = $(this).attr("class").split("_")[0]; if ($(this).is(":checked")) { ADJUST[pID][$(this).attr("name")] = $(this).val(); } else { ADJUST[pID][$(this).attr("name")] = ""; } recalcTotal(); }) break; case "radio": // Store the current value if ($(this).is(":checked")) { ADJUST[pID][$(this).attr("name")] = $(this).val(); } $(this).bind("change", function () { var pID = $(this).attr("class").split("_")[0]; ADJUST[pID][$(this).attr("name")] = $(this).val(); recalcTotal(); }) break; } break; } }); recalcTotal(); }); function parseAttributes(sValue) { sValue = sValue.match(/{(.*?)}/); if (sValue) { aValue = sValue[1].split("|"); for(i in aValue) { aParts = aValue[i].match(/p([\+|\-|\:])(.+)/); if (aParts) { return aParts; } } } return; } function recalcTotal() { for(p in ADJUST) { price = Number($("#"+p+"_price").val()); adjustment = 0; for (a in ADJUST[p]) { var aParts = parseAttributes(ADJUST[p][a]); if (aParts) { var modifier = aParts[1]; switch(modifier) { case ":": price = Number(aParts[2]); break; case "+": adjustment += Number(aParts[2]); break; case "-": adjustment -= Number(aParts[2]); break; } } } price += adjustment; $("."+p+TOTALCLASS).html(fcc._currency_format(price)); } } //]]> </script>
<input type="hidden" name="code" value="p1" />
<input type="hidden" name="price" id="p1_price" value="20" />
Selects:
<select class="p1_adjust" name="Size"> <option value="10 ml">10 ml</option> <option value="20 ml{c+test|p+2.50}">20 ml</option> <option value="20 ml{p+50|c+test}">30 ml</option> </select>
Checkboxes:
<label for="something">Something</label><input type="checkbox" name="something" value="Yes{p:10|c+test}" class="p1_adjust">
Radio Buttons (note that the grouped radio buttons need to all share the same “name”) :
<input type="radio" class="p1_adjust" name="group1" value="Milk{p:2}"><label>Milk</label> <input type="radio" class="p1_adjust" name="group1" value="Butter{p:3}" checked><label>Butter</label> <input type="radio" class="p1_adjust" name="group1" value="Cheese{p:4}"><label>Cheese</label>
<h4>$<span class="p1_total">20.00</span></h4>
The total would be put into that span element, and as no dollar sign is returned with the value, that is placed outside the span in the h4 element. If you want to use a class that is the code combined with a different string, this can be set at the top of the javscript in the TOTALCLASS variable.
That should be it. The script basically runs through all the elements that have a class ending in “_adjust”, and grabs what the active value is. If that value has a price modifier (p:X, p+X, p-X), it chucks it into an array. After looping over all the form elements, it loops through all the relevent price modifiers, and adjusts the base price and sets the total element. Worth noting is that if you have multiple flat price modifiers (eg p:30) where it alters the base price, only the last modifier is applied, but any plus or minus modifiers are applied after that.