Being a cut-n-paste JSer and a newbie to webpage writing, I am attempting to "borrow" elegant code that precludes having to write a million TR/TD statements in my online order form. This code works to create a beautiful looking form, but has one major flaw, and one minor flaw when used in NS-6.2
Major Flaw: It does not generate a named tag element for the product code, nor description. As far as calculating, on-the-fly, qty*price=total and GrandTotal -- it works great. When used with ACTION:mailto, it does send &quantity, &cost, &total to the URL. But, I can't figure out where to build in the &code or &description; everything I tried either prints to the order form, or dies.
Minor Flaw: Just installed NS6.2 and in testing the order form using TAB to get to NEXT FIELD while calculating total, the cursor first jumps to the next QTY field, then pauses and goes backwards to the last digit of the total field just entered (which should not be entered into at all). Works as designed in IE5 and NS4.79
Here's all that's required in the HTML BODY under <TABLE>:
<TR><TD colspan=5 align="center">ArtDeco</TD></TR>
...
...COL headers
...
<SCRIPT LANGUAGE="JavaScript"><!--
orderLine("AD 108","ArtDecoFan","6.25");
orderLine("AD 109","ArtDecoLilly","7.00");
orderLine("AD 113","ArtDecoLillyCircle","7.00");
orderLine("AD 311","ArtDecoLillyMirrored","5.75");
orderLine("AD 111","ArtDecoLillyRect","5.75");
orderLine("AD 212","LillyRibbon1","5.75");
orderLine("AD 213","LillyRibbon2","5.75");
//--></SCRIPT>
And, here's the order.js called in <HEAD>:
//*Order form management
// Called from _order.html
function fix(num,places)
{
shift = Math.pow(10,places);
totalDecimal = "" + Math.round(num * shift);
integer = totalDecimal.substring(0,totalDecimal.length - places );
decimal = totalDecimal.substring(totalDecimal.length - places,totalDecimal.length - places + 2);
return(integer + "." + decimal);
}
function td(s) { return("<TD align=center><Font Face=Arial Size=-1>" + s + "</Font></TD>");
} function tr(s) { return ("<TR>" + s + "</TR>"); }
function input(name,type,onStuff,val,size)
{
i = '<INPUT TYPE="' + type + '" name="' + name + '" ';
if ( size != 0 )
i = i + 'SIZE=' + size + ' ';
if ( val != null )
i = i + 'VALUE ="' + val + '" ';
if ( onStuff == null )
i = i + '>';
else
i = i + onStuff + '>';
return(i);
}
function w(s) { document.write(s); }
function tdOpen() { return("<TD>"); }
function tdClose() { return("</TD>"); }
function trOpen() { return("<TR>"); }
function trClose() { return("</TR>"); }
function selectOpen(name) { return('<SELECT NAME="' + name + '" SIZE=1>'); }
function selectClose() { return("</SELECT>"); }
function selectOption(option) { return("<OPTION>" + option); }
function orderLine(code,description,price,option1,option2,option3,option4,option5,option6,option7,option8,opt ion9,option10)
{
w(trOpen());
w(td(code));
if ( option1 == null )
w(td(description));
else {
w(tdOpen());
w(description+" ");
w(selectOpen("option"));
w(selectOption(option1));
if ( option2 != null ) w(selectOption(option2));
if ( option3 != null ) w(selectOption(option3));
if ( option4 != null ) w(selectOption(option4));
if ( option5 != null ) w(selectOption(option5));
if ( option6 != null ) w(selectOption(option6));
if ( option7 != null ) w(selectOption(option7));
if ( option8 != null ) w(selectOption(option8));
if ( option9 != null ) w(selectOption(option9));
if ( option10 != null ) w(selectOption(option10));
w(selectClose());
w(tdClose());
}
w(td(fix(price,2)+input("price","hidden","onChange=dummy()",price,0)));
w(td(input("quantity","text","onChange=computeField(this)","",4)));
w(td(input("cost","text","onFocus=moveAlong(this)","",8)));
w(trClose());
}
function setIndexes() {
// Introduce another field called index into the price,quantity and cost
// arrays to store the actual index positions within the array. So that
// each element "knows" it's own index. This will be usefull in the
// computeField() function where the index won't be known explicitly.
var j;
var a=document.form.price,b=document.form.quantity,c=document.form.cost;
for (j=0; j<c.length; j++) {
a[j].index = j;
b[j].index = j;
c[j].index = j;
}
}
function totalLine()
// This simply adds a total field to the form. computForm() is called if the
// user changes this field!
{
w(tr(td(" ") + td(" ") + td(" ") + td("Total") + td(input("total","text","onFocus=moveAlong(this)","",8))));
}
function checkNum(str,min,max) {
// Check the value is numeric and in the range min to max.
for ( var i=0; i < str.length; i++) {
var ch = str.substring(i,i+1);
if ( ch < "0" || ch > "9") {
alert("Try a number, please.");
return(false);
}
}
var num = 0 + str;
if ( num < min || num > max ) {
alert("Try a number from " + min + " to " + max );
return(false);
}
return(true);
}
var focusTo = 0;
function computeField(input)
// Make sure field value is numeric then calculate the cost for
// this item by multiplying the unit price by the quantity.
{
focusTo = 0;
if ( input.value != null && input.value.length != 0 ) {
if ( checkNum(input.value,1,100) ) {
input.value = "" + eval(input.value);
input.form.cost[input.index].value = fix(input.value * input.form.price[input.index].value,2);
}
else {
input.value = "";
input.form.cost[input.index].value = "";
input.focus();
input.select();
focusTo = input; // Make SURE we get the focus!
return;
}
}
else
input.form.cost[input.index].value = "";
// Sum the costs
computeForm();
}
function moveAlong(input) {
// The focus is on a field that shouldn't be changed.
// This is either the total field or one of the cost fields.
if ( focusTo != 0 ) {
focusTo = 0;
return;
}
else {
var newindex = 0;
if ( input.name != "total" )
if ( input.index+2 < input.form.cost.length )
newindex = input.index+1;
input.form.quantity[newindex].focus();
input.form.quantity[newindex].select();
}
}
// do nothing function to satisfy onChange for hidden fields
function dummy(){}
function fixupCost(input)
// The idiot has modified a cost field - fix it up for him!
{
input.form.cost[input.index].value = fix(input.form.quantity[input.index].value * input.form.price[input.index].value,2);
}
function computeForm()
// Sum the cost column into the total
{
var total = 0;
var c=document.form.cost,total=0;
for (j=0; j<c.length; j++) {
if ( c[j].value != "" )
total += eval(c[j].value);
}
// If just the postage then clear the total
if ( total != document.form.cost[document.form.cost.length - 1].value )
document.form.total.value = fix(total,2);
// document.form.total.value = total;
else
document.form.total.value = "";
}
Thank you for taking your time to help me.
Major Flaw: It does not generate a named tag element for the product code, nor description. As far as calculating, on-the-fly, qty*price=total and GrandTotal -- it works great. When used with ACTION:mailto, it does send &quantity, &cost, &total to the URL. But, I can't figure out where to build in the &code or &description; everything I tried either prints to the order form, or dies.
Minor Flaw: Just installed NS6.2 and in testing the order form using TAB to get to NEXT FIELD while calculating total, the cursor first jumps to the next QTY field, then pauses and goes backwards to the last digit of the total field just entered (which should not be entered into at all). Works as designed in IE5 and NS4.79
Here's all that's required in the HTML BODY under <TABLE>:
<TR><TD colspan=5 align="center">ArtDeco</TD></TR>
...
...COL headers
...
<SCRIPT LANGUAGE="JavaScript"><!--
orderLine("AD 108","ArtDecoFan","6.25");
orderLine("AD 109","ArtDecoLilly","7.00");
orderLine("AD 113","ArtDecoLillyCircle","7.00");
orderLine("AD 311","ArtDecoLillyMirrored","5.75");
orderLine("AD 111","ArtDecoLillyRect","5.75");
orderLine("AD 212","LillyRibbon1","5.75");
orderLine("AD 213","LillyRibbon2","5.75");
//--></SCRIPT>
And, here's the order.js called in <HEAD>:
//*Order form management
// Called from _order.html
function fix(num,places)
{
shift = Math.pow(10,places);
totalDecimal = "" + Math.round(num * shift);
integer = totalDecimal.substring(0,totalDecimal.length - places );
decimal = totalDecimal.substring(totalDecimal.length - places,totalDecimal.length - places + 2);
return(integer + "." + decimal);
}
function td(s) { return("<TD align=center><Font Face=Arial Size=-1>" + s + "</Font></TD>");
} function tr(s) { return ("<TR>" + s + "</TR>"); }
function input(name,type,onStuff,val,size)
{
i = '<INPUT TYPE="' + type + '" name="' + name + '" ';
if ( size != 0 )
i = i + 'SIZE=' + size + ' ';
if ( val != null )
i = i + 'VALUE ="' + val + '" ';
if ( onStuff == null )
i = i + '>';
else
i = i + onStuff + '>';
return(i);
}
function w(s) { document.write(s); }
function tdOpen() { return("<TD>"); }
function tdClose() { return("</TD>"); }
function trOpen() { return("<TR>"); }
function trClose() { return("</TR>"); }
function selectOpen(name) { return('<SELECT NAME="' + name + '" SIZE=1>'); }
function selectClose() { return("</SELECT>"); }
function selectOption(option) { return("<OPTION>" + option); }
function orderLine(code,description,price,option1,option2,option3,option4,option5,option6,option7,option8,opt ion9,option10)
{
w(trOpen());
w(td(code));
if ( option1 == null )
w(td(description));
else {
w(tdOpen());
w(description+" ");
w(selectOpen("option"));
w(selectOption(option1));
if ( option2 != null ) w(selectOption(option2));
if ( option3 != null ) w(selectOption(option3));
if ( option4 != null ) w(selectOption(option4));
if ( option5 != null ) w(selectOption(option5));
if ( option6 != null ) w(selectOption(option6));
if ( option7 != null ) w(selectOption(option7));
if ( option8 != null ) w(selectOption(option8));
if ( option9 != null ) w(selectOption(option9));
if ( option10 != null ) w(selectOption(option10));
w(selectClose());
w(tdClose());
}
w(td(fix(price,2)+input("price","hidden","onChange=dummy()",price,0)));
w(td(input("quantity","text","onChange=computeField(this)","",4)));
w(td(input("cost","text","onFocus=moveAlong(this)","",8)));
w(trClose());
}
function setIndexes() {
// Introduce another field called index into the price,quantity and cost
// arrays to store the actual index positions within the array. So that
// each element "knows" it's own index. This will be usefull in the
// computeField() function where the index won't be known explicitly.
var j;
var a=document.form.price,b=document.form.quantity,c=document.form.cost;
for (j=0; j<c.length; j++) {
a[j].index = j;
b[j].index = j;
c[j].index = j;
}
}
function totalLine()
// This simply adds a total field to the form. computForm() is called if the
// user changes this field!
{
w(tr(td(" ") + td(" ") + td(" ") + td("Total") + td(input("total","text","onFocus=moveAlong(this)","",8))));
}
function checkNum(str,min,max) {
// Check the value is numeric and in the range min to max.
for ( var i=0; i < str.length; i++) {
var ch = str.substring(i,i+1);
if ( ch < "0" || ch > "9") {
alert("Try a number, please.");
return(false);
}
}
var num = 0 + str;
if ( num < min || num > max ) {
alert("Try a number from " + min + " to " + max );
return(false);
}
return(true);
}
var focusTo = 0;
function computeField(input)
// Make sure field value is numeric then calculate the cost for
// this item by multiplying the unit price by the quantity.
{
focusTo = 0;
if ( input.value != null && input.value.length != 0 ) {
if ( checkNum(input.value,1,100) ) {
input.value = "" + eval(input.value);
input.form.cost[input.index].value = fix(input.value * input.form.price[input.index].value,2);
}
else {
input.value = "";
input.form.cost[input.index].value = "";
input.focus();
input.select();
focusTo = input; // Make SURE we get the focus!
return;
}
}
else
input.form.cost[input.index].value = "";
// Sum the costs
computeForm();
}
function moveAlong(input) {
// The focus is on a field that shouldn't be changed.
// This is either the total field or one of the cost fields.
if ( focusTo != 0 ) {
focusTo = 0;
return;
}
else {
var newindex = 0;
if ( input.name != "total" )
if ( input.index+2 < input.form.cost.length )
newindex = input.index+1;
input.form.quantity[newindex].focus();
input.form.quantity[newindex].select();
}
}
// do nothing function to satisfy onChange for hidden fields
function dummy(){}
function fixupCost(input)
// The idiot has modified a cost field - fix it up for him!
{
input.form.cost[input.index].value = fix(input.form.quantity[input.index].value * input.form.price[input.index].value,2);
}
function computeForm()
// Sum the cost column into the total
{
var total = 0;
var c=document.form.cost,total=0;
for (j=0; j<c.length; j++) {
if ( c[j].value != "" )
total += eval(c[j].value);
}
// If just the postage then clear the total
if ( total != document.form.cost[document.form.cost.length - 1].value )
document.form.total.value = fix(total,2);
// document.form.total.value = total;
else
document.form.total.value = "";
}
Thank you for taking your time to help me.