Thursday, June 17, 2010

Javascript Math Functions and Calculator Fun

It's been a few years since I have had to perform any real engineering work. As a senior member of a management consulting firm, my days seem to be focused on business development and project management. However, my wife recently requested some assistance to help develop a special feature for her blog site that got my coding juices flowing again.

My wife has an interest in health, wellness and fitness, and follows the point-counting process for tracking meals. She has used a spreadsheet version of a 'points calculator' and an on line PHP version that we found on a dedicated website, but she wanted a calculator that would be easily accessible to her website visitors. That was my clue to get involved.

With my engineering education and work experience, the majority of my programming experience has been in FORTRAN and machine code. Although I have also had the opportunity to dabble in a number of other languages over the past 30 years. Wanting to make the points calculator an easy plug-in for any blog hosting service that she would ever use, I knew that I would have to code something that could be called from HTML, or just go straight to Javascript and keep the code right within the web page.

I believe that Javascript offers many advantages for a number of typical website functions. There have been security concerns, especially with computers using the Microsoft Windows operating system, but those issues can normally be managed by keeping the operating system up-to-date and using current virus and malware protection; a practice that most computer users follow. Javascript security issues typically do not concern OS X or Linux users. Therefore, Javascript seemed to be the answer to my language question.

The points formula is often cited to follow this convention: Points = Calories / 50 + Fat Grams / 12 - Fiber Grams / 5, where Fiber Grams cannot be greater than 4. Simple enough calculation. The Javascript Math functions were only required to accommodate the Fiber Gram restriction and to round the final answer to one decimal position. Now the only trick was to pass the data between HTML and the Javascript routine.

I decided that the easiest way to accomplish the task was to use the HTML Form Tag, passing the input to a Javascript routine for processing. I was concerned about user input error, so I spent some extra time to code validation routines to make certain that the numeric fields are not blank or filled with non-numeric characters. An incorrect entry will open a dialog box with a warning message and highlight the entry field in error.

I was not familiar with performing more advanced math operations in Javascript. Fortunately, there are many fine sources found online to help educate me. One of my favorite resources for HTML, CSS and Javascript assistance is w3schools.com. Here I found a good introduction to the Javascript Math Object.

Without boring you with a narrative of the coding trial and error, the final version of the calculator, complete with the HTML for the Form, is presented below. The working version can be found at pointsinmylife.com. Forgive me for the use of Tables in the Form, but I found them to be the most effective method to get consistent presentation format results across different browsers.

<script type="text/javascript">
function Calculate(calories, fat, fiber, form)
{
if (form.calories.value == "" || isNaN(form.calories.value)) {
alert( "Please enter a valid number for Calories." );
form.calories.focus();
return false ;
}
if (form.fat.value == "" || isNaN(form.fat.value)) {
alert( "Please enter a valid number for Fat Grams." );
form.fat.focus();
return false ;
}
if (form.fiber.value == "" || isNaN(form.fiber.value)) {
alert( "Please enter a valid number for Fiber Grams." );
form.fiber.focus();
return false ;
}
var A = parseFloat(calories);
var B = parseFloat(fat);
var C = parseFloat(fiber);
form.points.value = Math.round (((A / 50) + (B / 12) - (Math.min(C,4) / 5)) * 10) / 10;
}
function ClearForm(form)
{
form.calories.value = "";
form.fat.value = "";
form.fiber.value = "";
form.points.value = "";
}
</script>
<form method="post">
<table>
<tr colspan="2">
<td width="80%">
Enter Calories:
</td>
<td width="20%" align="right">
<input type="TEXT" name="calories" size="3" />
</td>
</tr>
<tr colspan="2">
<td width="80%">
Enter Fat Grams:
</td>
<td width="20%" align="right">
<input type="TEXT" name="fat" size="3" />
</td>
</tr>
<tr colspan="2">
<td width="80%">
Enter Fiber Grams:
</td>
<td width="20%" align="right">
<input type="TEXT" name="fiber" size="3" />
</td>
</tr>
<tr colspan="2">
<td width="80%">
Calculated Points:
</td>
<td width="20%" align="right">
<input type="TEXT" name="points" size="3" readonly style="border: none; font-weight: bold; color: #990000; background: #99bb55;" />
</td>
</tr>
<tr colspan="2">
<td width="80%">
<input type="button" value="Clear Fields" name="ClearButton" onclick="ClearForm(this.form)" />
</td>
<td width="20%" align="right">
<input type="button" value="Calculate" name="CalculateButton" onclick="return Calculate(this.form.calories.value, this.form.fat.value, this.form.fiber.value, this.form);" />
</td>
</tr>
</table>
</form>
<br />