Need help with Javascript + html ordering form

sfidirectory

Senior Member
Joined
Mar 29, 2010
Messages
931
Reaction score
504
Hi everyone,

So this is my first real crack at Javascript, for this example I have tried to make an order form with Javascript that does the client-side validation of form fields. What I am wanting to do is when the user selects a "quantity" from the dropdown menu, the subtotal is automatically calculated and produced under a "subtotals" heading (for some reason, this heading is not displayed and that is most likely because of the Javascript & html hooks). This is done for each product listed in the form. Then finally I am wanting to add all the subtotals for each product to calculate the final total (ideally I would like to try and have this done automatically so if the user changes the quantity of a product, the final total changes etc).

If someone could help me out here I will be VERY greatful. This is something I would like to get working as this is going to be a component of Stage 2 of my auction script 9created from scratch (Stage 1 is working 95% perfect).

Here is the source code for the form:

Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="scarfiesoupshack.css">

<script src="scarfiesoupshack.js" type="text/javascript"></script>

<title>Scarfie Soup Shack</title>
</head>

<body>

<h1>We Make Soup (and sell it to you)</h1>

<p><img src="soup-here.jpg" alt="The Scarfie Soup Shack."></p>

<p>Our soup shack sits in the middle of Otago University quad - you
can't miss us.</p>

<p>If you tell us what you want, we'll put it in a
box with your name on it, ready to pick up in about 5 minutes.  So why wait
out in the cold?  Put in your order from the comfort of your own
office, then come on over and collect it from the shack.</p>

<h1>Place your order:</h1>

<form method="post" action="#" name="souporderform" id="souporderform" onsubmit="return validate()">

<table>

<tr><th>Item</th><th>Price</th><th>Quantity</th><th id="subtotal_header">Subtotal</th>

<tr>
<td><label for="pumpkin_quantity">Pumpkin Soup</label></td>
<td>$3<input type="hidden" id="pumpkin_price" value="3.00"></td>
<td align="center"><select id="pumpkin_quantity" name="pumpkin_quantity" size="1">
  <option value="10">10</option>
  <option value="9">9</option>
  <option value="8">8</option>
  <option value="7">7</option>
  <option value="6">6</option>
  <option value="5">5</option>
  <option value="4">4</option>
  <option value="3">3</option>
  <option value="2">2</option>
  <option value="1">1</option>
  <option value="0" selected>0</option>
</select>
</td>
<td id="pumpkin_subtotal"></td>
</tr>

<tr>
<td><label for="chicken_quantity">Chicken Soup</label></td>
<td>$3.50<input type="hidden" id="chicken_price" value="3.50"></td>
<td align="center"><select id="chicken_quantity" name="chicken_quantity" size="1">
  <option value="10">10</option>
  <option value="9">9</option>
  <option value="8">8</option>
  <option value="7">7</option>
  <option value="6">6</option>
  <option value="5">5</option>
  <option value="4">4</option>
  <option value="3">3</option>
  <option value="2">2</option>
  <option value="1">1</option>
  <option value="0" selected>0</option>
</select>
</td>
<td id="chicken_subtotal"></td>
</tr>

<tr>
<td><label for="clam_quantity">Clam Chowder</label></td>
<td>$4<input type="hidden" id="clam_price" value="4.00"></td>
<td align="center"><select id="clam_quantity" name="clam_quantity" size="1">
  <option value="10">10</option>
  <option value="9">9</option>
  <option value="8">8</option>
  <option value="7">7</option>
  <option value="6">6</option>
  <option value="5">5</option>
  <option value="4">4</option>
  <option value="3">3</option>
  <option value="2">2</option>
  <option value="1">1</option>
  <option value="0" selected>0</option>
</select>
</td>
<td id="clam_subtotal"></td>
</tr>


<tr>
<td><label for="harira_quantity">Harira</label></td>
<td>$3.50<input type="hidden" id="harira_price" value="3.50"></td>
<td align="center"><select id="harira_quantity" name="harira_quantity" size="1">
  <option value="10">10</option>
  <option value="9">9</option>
  <option value="8">8</option>
  <option value="7">7</option>
  <option value="6">6</option>
  <option value="5">5</option>
  <option value="4">4</option>
  <option value="3">3</option>
  <option value="2">2</option>
  <option value="1">1</option>
  <option value="0" selected>0</option>
</select>
</td>
<td id="harira_subtotal"></td>
</tr>

<tr id="tablefoot"><td>Total:</td><td colspan="2" id="totalerr"><td id="finaltotal"></td></tr>

</table>

<p><label for="yourname">Your name (so we can write it on the box):</label>
  <input name="yourname" id="yourname" type="text">
  <span id="nameerr"></span></p>
<p><label for="youremail">Your email address (we'll confirm your order):</label>
  <input name="youremail" id="youremail" type="text">
  <span id="emailerr"></span></p>

<div><button id="submit" type="submit">Place Order</button><button id="reset" type="reset">Clear Form</button></div>

</form>

</body>
The Javascript for "scarfiesoupshack.js":

Code:
// file scarfiesoupshack.js

var soups = ["pumpkin", "chicken", "clam", "harira"];

//get prices of soups
var pumpkin = document.getElementById("pumpkin_price");
var pumpkinprice = pumpkin.value;

var chicken = document.getElementById("chicken_price");
var chickenprice = chicken.value;

var clam = document.getElementById("clam_price");
var clamprice = clam.value;

var harira = document.getElementById("harira_price");
var hariraprice = harira.value;
//end get prices

function setup() {
  var lastCol = document.getElementById("subtotal_header");
  lastCol.style.display = "table-cell";
  var tableFoot = document.getElementById("tablefoot");
  tableFoot.style.display = "table-row";
  var theForm = document.getElementById("souporderform");

  var amounts = document.getElementsByTagName("select");
  for(var i = 0; i < amounts.length; i++){
    amounts[i].onchange = doTotals;
  }

  theForm.onsubmit = validate;
  theForm.onreset = resetTotals;
}

function validate() {
  var result = true;

  var namefield = document.getElementById("yourname");
  var nameerr = document.getElementById("nameerr");
  var namefieldRE = /^[\w ]+$/;

  var emailfield = document.getElementById("youremail");
  var emailerr = document.getElementById("emailerr");
  
  //email regex sourced from http://www.tizag.com/javascriptT/javascriptform.php

  var emailfieldRE = /^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/ ;

  if(!namefield.value.match(namefieldRE)){
    nameerr.innerHTML = "Please fill in your name";
    nameerr.style.color = "#ff0000";
    result = false;
  }
  else{
    nameerr.innerHTML = ""
    result = true;
  }

  if(!emailfield.value.match(emailfieldRE)){
    emailerr.innerHTML = "Please fill in your email";
    emailerr.style.color = "#ff0000";
    result = false;
  }
  else{
    emailerr.innerHTML = "";
    result = true;
  }

    return result;

}

function resetTotals() {
  var total = 0.0;
  for (soup in soups) {
    var subtotal = soups[soup] + "_subtotal";
    document.getElementById(subtotal).innerHTML = "0.00";
  }
  output = document.getElementById("finaltotal");
  output.innerHTML = "0.00";
}

function doTotals() {
  alert();
  //var total = 0.0;

  
  
  for (soup in soups) {
  

  var pumpkinselectedvalue = document.souporderform.pumpkin_quantity.value;
  var chickenselectedvalue = document.souporderform.chicken_quantity.value;
  var clamselectedvalue = document.souporderform.clam_quantity.value;
  var hariraselectedvalue = document.souporderform.harira_quantity.value;


  document.getElementByID(soups[soup] + "_subtotal") = (soups[soup] + "price") * (soups[soup] + "selectedvalue");


    var subtotal = soups[soup] + "_subtotal";
    document.getElementById(subtotal).innerHTML = "0.00";
  }

  output = document.getElementById("finaltotal");
  output.innerHTML = total.toFixed(2);
}

if (document.getElementById) {
  window.onload = setup;
}
And the css code for "scarfiesoupshack.css":

Code:
body {
  font-family: sans-serif;
}

table {
  border-spacing: 0;
}

th {
  padding: 0.4em 1em;
  border-bottom: solid black 2px;   
}

td {
  padding: 0.4em 1em;   
}

#subtotal_header {
  display: none;   
}

#tablefoot {
  display: none;   
}

#tablefoot td {
  border-top: solid black 2px;   
  border-bottom: solid black 2px;   
}

button {
  float: left;
  margin: 1em 1em;
}
Many thanks in advance!
 
It's very difficult to read through a whole chunk of code. Maybe you should extract the parts. Anyway, your validate() function which was called did not call doTotals()? Maybe I'm missing out something... Check your scripts clearly.
 
It's very difficult to read through a whole chunk of code. Maybe you should extract the parts. Anyway, your validate() function which was called did not call doTotals()? Maybe I'm missing out something... Check your scripts clearly.

In the script I gave in this thread, the doTotals function is being called here:

Code:
function setup() {
  var lastCol = document.getElementById("subtotal_header");
  lastCol.style.display = "table-cell";
  var tableFoot = document.getElementById("tablefoot");
  tableFoot.style.display = "table-row";
  var theForm = document.getElementById("souporderform");

  var amounts = document.getElementsByTagName("select");
  for(var i = 0; i < amounts.length; i++){
    [B]amounts[i].onchange = [U]doTotals;[/U][/B]
  }

  theForm.onsubmit = validate;
  theForm.onreset = resetTotals;
}
From what I have learned so far with Javascript, you don't call functions with the (). Unless I have got the assignment wrong?

And this is the doTotals() function code here:

Code:
[B]function doTotals()[/B] {
  //var total = 0.0;
  
  for (soup in soups) {
  

  var pumpkinselectedvalue = document.souporderform.pumpkin_quantity.value;
  var chickenselectedvalue = document.souporderform.chicken_quantity.value;
  var clamselectedvalue = document.souporderform.clam_quantity.value;
  var hariraselectedvalue = document.souporderform.harira_quantity.value;


  document.getElementByID(soups[soup] + "_subtotal") = (soups[soup] + "price") * (soups[soup] + "selectedvalue");


    var subtotal = soups[soup] + "_subtotal";
    document.getElementById(subtotal).innerHTML = "0.00";
  }

  output = document.getElementById("finaltotal");
  output.innerHTML = total.toFixed(2);
}
I thought I would give the whole code for the whole thing in the starting post as I didn't know where to start initially, but I hope I have correctly isolated the problematic code... It's embarrasing not knowing Javascript well but will be learning as I go :o.It's embarrasing because I have learned Java and PHP and I should be able to carry over similar concepts etc to Javascript...
 
Use the error console in your browser, and add alert statements to see what the computer is reading. Sorry, I don't have time right now to look at your code.
 
Hey everyone,

Had a look around a few tutorial sites and fixed my problem (no copy/paste)!! :).

I decided to use a for loop as opposed to a for-each loop and last time I forgot to output the subtotals to their "innerHTML" elements (predefined divs where the subtotals are displayed after the calculations are done) so I rectified that issue and used everything learned to complete the whole thing...

I love how Javascript automatically recalculates the subtotals and final total if you decide to change number of soups you order, it's really cool, and this will be put to good use for implementing with Stage 2 of my auction site :). Heres the modified javascript below:

Code:
// file scarfiesoupshack.js

var soups = ["pumpkin", "chicken", "clam", "harira"];

function setup() {
  var lastCol = document.getElementById("subtotal_header");
  lastCol.style.display = "table-cell";
  var tableFoot = document.getElementById("tablefoot");
  tableFoot.style.display = "table-row";
  var theForm = document.getElementById("souporderform");

  var amounts = document.getElementsByTagName("select");
  for(var i = 0; i < amounts.length; i++){
    amounts[i].onchange = doTotals;
  }

  theForm.onsubmit = validate;
  theForm.onreset = resetTotals;
}

function validate() {
  var result = true;

  var namefield = document.getElementById("yourname");
  var nameerr = document.getElementById("nameerr");
  var namefieldRE = /^[\w ]+$/;

  var emailfield = document.getElementById("youremail");
  var emailerr = document.getElementById("emailerr");
  
  //email regex sourced from http://www.tizag.com/javascriptT/javascriptform.php

  var emailfieldRE = /^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/ ;

  if(!namefield.value.match(namefieldRE)){
    nameerr.innerHTML = "Please fill in your name";
    nameerr.style.color = "#ff0000";
    result = false;
  }
  else{
    nameerr.innerHTML = ""
    result = true;
  }

  if(!emailfield.value.match(emailfieldRE)){
    emailerr.innerHTML = "Please fill in your email";
    emailerr.style.color = "#ff0000";
    result = false;
  }
  else{
    emailerr.innerHTML = "";
    result = true;
  }

    return result;

}

function resetTotals() {
  var total = 0.0;
  for (soup in soups) {
    var subtotal = soups[soup] + "_subtotal";
    document.getElementById(subtotal).innerHTML = "0.00";
  }
  output = document.getElementById("finaltotal");
  output.innerHTML = "0.00";
}

function doTotals() {
    
  var total = new Array();
  var subTotal = new Array();
  var price = new Array();
  var finalTotal = 0.0;
  
  for (var i = 0; i < soups.length; i++) {
      
      //get price for each soup
      price[i] = document.getElementById(soups[i] + "_price").value;
      
      //get subtotal for each soup
      subTotal[i] = price[i] * document.getElementById(soups[i] + "_quantity").value;
      
      //display subtotals for each soup on the form
      subTotalOutput = document.getElementById(soups[i] + "_subtotal");
      subTotalOutput.innerHTML = "$" + subTotal[i].toFixed(2);
  }
  
  //calculate final cost of soups ordered
  for(var i = 0; i < soups.length; i++){
      finalTotal += subTotal[i];
  }

  output = document.getElementById("finaltotal");
  output.innerHTML = "$" + finalTotal.toFixed(2);
}

if (document.getElementById) {
  window.onload = setup;
}

If you want the css, html, javascript and images for the form, you can download them from the attachment.... Oops just about forgot VirusTotal scan, here are the results:

File name:
ordeformexample_bhw.zip
Submission date:
2011-09-05 09:26:16 (UTC)
Current status:
finished
Result:
0/ 44 (0.0%)

Results URL:
Code:
https://www.virustotal.com/file-scan/report.html?id=0b3d0f901a3dc3ea185d9fb66bf20112c94e22c827037a615278539ec3db07e1-1315214776

If this helps anyone, feel free to press thanks :).
 
Heres the modified javascript below:

I don't mean to be a bother, and I know OP is banned so he can't be much of help but...can anyone tell me where I need to implement this modified version into my site?

I was able to do it right with OP first post. But anytime I try with these it doesn't work. I'm pretty new to scripting and all advice is greatly appreciated.

Thanks,
 
Back
Top