There is a javascript script out on the internet that is quite useful for making dynamic shopping carts:
http://javascript.internet.com/forms/order-form.html
The code is credited as created by Paul DeBrino of infinity-rd.com. This script appears all over the web and has been online since at least 2002. It worked great with Internet Explorer, Safari, and Opera, and is the base of Designtion’s prices page.
It worked wonderfully until Firefox came along. Firefox generally handles websites more gracefully and is generally pretty forgiving, but perplexingly, is more strict about javascript variables then every other browser. Firefox has become my favorite browser on all platforms, and embarrassingly, it’s taken me a year to write an overhaul of the prices page to be compatible with Firefox.
It turns out that Firefox doesn’t respect custom properties of form elements. The script linked from above works like this: The radio button “Sauce” was assigned an additional custom property, “price”, for use in calculating the total price of the form.
<input name="Sauce" value="none" price="0.00" onclick="this.form.total.value=CheckChoice(this);" type="radio" />
Other variations of this form on the internet have used other values such as priorval, taxval, etc. for keeping track of additional variables. The script would then calculate the total by referencing these values like this:
hiddentotal.value = eval(hiddentotal.value) + eval(whichbox.price);
The problem is that Firefox doesn’t support referencing these values at all. It won’t complain about the HTML when you add the additional properties to the input, but when you try to access them or use them in calculations you get undefined values and NANs, respectively. Firefox only respects input properties that are defined by the DOM, such as name, value, checked, readonly, disabled, etc.
I could have redone this by creating all of my variables as hidden inputs and just used their value property as variables. However, my pricing form has 204 variables total, and making an input for each seemed inefficient, especially since I was using the same properties over and over. It made sense to make this script object oriented. We can make a javascript object that has all of the custom properties we want and Firefox will like it:
function cartObject(){
this.price=0;
this.priorval=0;
}
You can add whatever properties you want–Designtion’s prices page uses design prices, programming prices, and hosting costs:
function designtionCartObject(){
this.designvalue=0;
this.progvalue=0;
this.additionalvalue=0;
this.priordesignval=0;
this.priorprogval=0;
this.prioraddvalue=0;
this.priorval=0;
this.price=0;
}
Then, you initialize the object like this:
var duckSauceObj = new cartObject();
Finally, you assign values to your custom properties in your object in InitForm(), so that your objects have the right values whenever the form is loaded:
function InitForm()
{
duckSauceObj.price=10.99;
sauceObj.priorval=0;
[...]
}
Now, we’ll modify checkChoice to take both the object (for calculating prices) and the radio button (for handling input) as inputs:
function CheckChoice(cartObject, whichbox)
{
//Handle differently, depending on type of input box.
if (whichbox.type == "radio")
{
//First, back out the prior radio selection's price from the total:
document.myform.hiddentotal.value = eval(document.myform.hiddentotal.value) - eval(document.myform.hiddenpriorradio.value);
//Then, save the current radio selection's price:
document.myform.hiddenpriorradio.value = eval(cartObject.price);
//Now, apply the current radio selection's price to the total:
document.myform.hiddentotal.value = eval(document.myform.hiddentotal.value) + eval(cartObject.price);
}
else
{
//If box was checked, accumulate the checkbox value as the form total,
//Otherwise, reduce the form total by the checkbox value:
if (whichbox.checked == false)
{ document.myform.hiddentotal.value = eval(document.myform.hiddentotal.value) - eval(whichbox.value); }
else { document.myform.hiddentotal.value = eval(document.myform.hiddentotal.value) + eval(whichbox.value); }
}
//Ensure the total never goes negative (some browsers allow radiobutton to be deselected):
if (document.myform.hiddentotal.value < 0)
{
InitForm();
}
//Now, return with formatted total:
return(formatCurrency(document.myform.hiddentotal.value));
}
Note: I deleted this statement (and its closing bracket) because it was not neccessary and messed up the references to cartObject:
with (whichbox.form)
{
Finally, you can call the modified checkChoice function like this:
<input name="Sauce" value="No Website" onclick="checkChoice(duckSauceObj,this);" type="radio" />
Make sure you don’t name your object the same name as your input name. This shouldn’t break things but does because firefox gets confused about what element or object you’re talking about.
Make sure to call InitForm() in your body tag to initialize the form and variables.
<body onload="InitForm();" onreset="InitForm();">
Voila! Now you have a Firefox-compatible object-oriented javascript pricing form.
A fully functional example of this code is available here: updated_pricing_form_ex.html
This should go without saying, but your form needs to do some sort of post-processing and validation, or at the very least, human validation before any transactions take place, as javascript (and HTML forms) are extremely hackable.
If you would like Designtion to design you a form like this please contact us.
Posted in Javascript, Projects by Designtion | No Comments »



