Hong Kong's Dr. Ashley Cheng has produced a JavaScript page which contains an example of how JavaScript and forms can be combined to create special-purpose calculators and mini-spreadsheets. It's located at this site:
http://www.iohk.com/UserPages/acheng/javascript.html
Cheng's example is a calculator which, given a user's height and weight, calculates the individual's Body Mass Index and then makes a comment(usually light-hearted) about the implications of the calculated index. The comments range from "Umm. .
.You are obese, want some liposuction?" to "You are starving. Go find some food!"
The interface is simple: a form with four fieldsthe user fills in the height and weight fields and the remaining two fields are filled in by the script with the user's BMI and the relevant comment. Two buttons are provided: One calculates the results and displays them in the appropriate fields, and the other enables the user to reset the form.
In addition, Dr. Cheng has added basic form checking to the script so that if either of the user's entry fields is empty, an appropriate alert is displayed. In addition, the script checks if the height and weight values are
totally illogical. For instance, if the weight value is less than zero kilograms or more than 500 kilograms, the program assumes that the user has made a mistake.
The source code for the program is in Listing W2.1.
<HTML> <HEAD> <TITLE>Ashley's JavaScript(tm) Examples</TITLE> <SCRIPT LANGUAGE="JAVASCRIPT"> <!-- hide this script tag's contents from old browsers function ClearForm(form){ form.weight.value = ""; form.height.value = ""; form.bmi.value = ""; form.my_comment.value = ""; } function bmi(weight, height) { bmindx=weight/eval(height*height); return bmindx; } function checkform(form) { if (form.weight.value==null||form.weight.value.length==0 ||form.height.value==null||form.height.value.length==0){ alert("\nPlease complete the form first"); return false; } else if (parseFloat(form.height.value) <= 0|| parseFloat(form.height.value) >=500|| parseFloat(form.weight.value) <= 0|| parseFloat(form.weight.value) >=500){ alert("\nReally know what you're doing? \nPlease enter values again. \nWeight in kilos and \nheight in cm"); ClearForm(form); return false; } return true; } function computeform(form) { if (checkform(form)) { yourbmi=Math.round(bmi(form.weight.value, form.height.value/100)); form.bmi.value=yourbmi; if (yourbmi >40) { form.my_comment.value="You are grossly obese, consult your physician!"; } else if (yourbmi >30 && yourbmi <=40) { form.my_comment.value="Umm... You are obese, want some liposuction?"; } else if (yourbmi >27 && yourbmi <=30) { form.my_comment.value="You are very fat, do something before it's too late"; } else if (yourbmi >22 && yourbmi <=27) { form.my_comment.value="You are fat, need dieting and exercise"; } else if (yourbmi >=21 && yourbmi <=22) { form.my_comment.value="I envy you. Keep it up!!"; } else if (yourbmi >=18 && yourbmi <21) { form.my_comment.value="You are thin, eat more."; } else if (yourbmi >=16 && yourbmi <18) { form.my_comment.value="You are starving. Go Find some food!"; } else if (yourbmi <16) { form.my_comment.value="You're grossly undernourished, need hospitalization "; } } return; } // -- done hiding from old browsers --> </SCRIPT> </HEAD> <BODY BACKGROUND="background.gif"> <CENTER> <H1>Ashley's JavaScript(tm) Examples:</H1> <HR SIZE=3> <UL> <LI><A HREF="#HK1997">Hong Kong and 1997</A> <LI><A HREF="#Calc">Want to know whether your weight is ideal?</A> </UL> <A NAME="HK1997"> <HR> <P> <SCRIPT LANGUAGE="JAVASCRIPT"> <!-- hide this script tag's contents from old browsers document.write('<IMG SRC="hkf.jpg"> <P>'); today = new Date(); document.write("Today is <B>"+today+"</B><P>"); BigDay = new Date("July 1, 1997") msPerDay = 24 * 60 * 60 * 1000 ; timeLeft = (BigDay.getTime() - today.getTime()); e_daysLeft = timeLeft / msPerDay; daysLeft = Math.floor(e_daysLeft); e_hrsLeft = (e_daysLeft - daysLeft)*24; hrsLeft = Math.floor(e_hrsLeft); minsLeft = Math.floor((e_hrsLeft - hrsLeft)*60); document.write("There are only<BR> <H3>" + daysLeft + " days " + hrsLeft +" hours and " + minsLeft + " minutes left </H3><BR> before Hong Kong revert from British to Chinese rule <BR> on the <B>1st of July 1997!</B><P>"); // -- done hiding from old browsers --> </SCRIPT> <FORM> <input type=button name="Refresh" value="Refresh" onclick="window.location='http://www.iohk.com/UserPages/acheng/javascript.html'"> </FORM> </A> <HR> <A NAME="Calc"> <H2><IMG SRC="scale.jpg" ALIGN=MIDDLE> Do you have an ideal weight??</H2> Enter your weight in kilograms and your height in centimeters<BR> in the form below and press the "Let's see" button<BR> (Please read disclaimer below before using this form)<BR> <FORM NAME="BMI" method=POST> <TABLE border=1> <TR> <TD><DIV ALIGN=CENTER>Your Weight (kg)</DIV></TD> <TD><DIV ALIGN=CENTER>Your Height (cm)</DIV></TD> <TD><DIV ALIGN=CENTER>Your BMI</DIV></TD> <TD><DIV ALIGN=CENTER>My Comment</DIV></TD> </TR> <TR> <TD><INPUT TYPE=TEXT NAME=weight SIZE=10 onfocus="this.form.weight.value=''"></TD> <TD><INPUT TYPE=TEXT NAME=height SIZE=10 onfocus="this.form.height.value=''"></TD> <TD><INPUT TYPE=TEXT NAME=bmi SIZE=8 ></TD> <TD><INPUT TYPE=TEXT NAME=my_comment SIZE=35 ></TD> </TABLE> <P> <INPUT TYPE="button" VALUE="Let's see" onclick="computeform(this.form)"> <INPUT TYPE="reset" VALUE="Reset" onclick="ClearForm(this.form)"> </FORM> </A> <HR> </CENTER> <B>Disclaimer</B>: This form is based on the calculation of <A HREF="http://www.iohk.com/UserPages/acheng/bmi.html"><I>"Body Mass Index"</I></A> and is only meant to be a demonstration of how Javascript(tm) could be used on a Web Page. Information it contains may not be accurate and is not designed or intended to serve as medical advice. You should not act in accordance to the "comment" provided in this form and I shall not be liable for any physical or psychological damages suffered as a result of using this form or script. <HR> Access: <IMG SRC="http://www.iohk.com/cgi-bin/nph-count?link=ashleycheng&width=6"> <P> <IMG SRC="cheng3.gif" ALIGN="LEFT" HSPACE=15><BR> Author: Ashley Cheng (<A HREF="mailto:ackcheng@ha.org.hk">ackcheng@ha.org.hk</A>) Jan 1996<BR> Go back to <A HREF="http://www.iohk.com/UserPages/acheng">my Home-Page</A> or see <A HREF="http://www.wahyan.edu.hk/ashleyticker.html"> Java(tm) applets written by me</A>. <P> </BODY> </HTML>
The script produces results similar to those in Figures 6.9 and 6.10.
Figure W2.1. Calculators and mini spreadsheets can be created using JavaScript.
Figure W2.2. Dr. Cheng uses simple error checking to ensure data is valid.
End of Output
Analysis
Dr. Cheng's page has two JavaScript applications on it: a countdown to China's take over of Hong Kong and the weight calculator we are interested in.
Cheng places all the functions for the weight calculator in the header but because the countdown application involves dynamic HTML content based on the date and time, that script is contained in the body of the HTML document.
The weight calculator is built out of four functions: ClearForm(), bmi(), checkform(), and computeform().
Before looking at each function and how it works, we need to understand the HTML form which provides the interface to the script:
<FORM NAME="BMI" method=POST> <TABLE border=1> <TR> <TD><DIV ALIGN=CENTER>Your Weight (kg)</DIV></TD> <TD><DIV ALIGN=CENTER>Your Height (cm)</DIV></TD> <TD><DIV ALIGN=CENTER>Your BMI</DIV></TD> <TD><DIV ALIGN=CENTER>My Comment</DIV></TD> </TR> <TR> <TD><INPUT TYPE=TEXT NAME=weight SIZE=10 onfocus="this.form.weight.value=''"></TD> <TD><INPUT TYPE=TEXT NAME=height SIZE=10 onfocus="this.form.height.value=''"></TD> <TD><INPUT TYPE=TEXT NAME=bmi SIZE=8 ></TD> <TD><INPUT TYPE=TEXT NAME=my_comment SIZE=35 ></TD> </TABLE> <P> <INPUT TYPE="button" VALUE="Let's see" onclick="computeform(this.form)"> <INPUT TYPE="reset" VALUE="Reset" onclick="ClearForm(this.form)"> </FORM>
For appearance, Dr. Cheng has put the four text fields into a table. He uses the <DIV ALIGN=CENTER> ... </DIV> structure to center text inside the table cells. <DIV ALIGN=CENTER> is the HTML 3 method for centering text and is supported by Navigator 2 along with Netscape's own methods, such as the CENTER tag.
The form contains four text fields: weight, height, bmi and my_comment. The two which the user usesweight and heightare cleared when the user clicks in them simply by setting the value of the field to an empty string in the onFocus event
handler:
onfocus="this.form.height.value=''"
The Let's See button uses the onClick event handler to call computeform() and passes it the form object as an argument using this.form. The Reset button calls the ClearForm() function.
The next four sections elaborate on the ClearForm(), bmi(), checkform(), and computeform() functions.
This function simply sets the values of the four fields in the form to the empty string.
The bmi() function is used to calculate the Body Mass Index using the formula bmi = weight/(heightxheight) where the weight is in kilograms and the height is in meters (not
centimeters). The function accepts weight and height as arguments and then simply calculates the BMI and returns it.
checkform() accepts the form object as an argument and performs two error checks on the data. The function is called from the computeform() function.
First the function checks if either the weight or height field in the form contains a null value or an empty string:
if (form.weight.value==null||form.weight.value.length==0 || form.height.value==null||form.height.value.length==0){ alert("\nPlease complete the form first"); return false; }
If either field is not filled in, then an alert is displayed and the function returns a false value.
If both fields are filled in, the function then checks to see if the values make sense. If they seem out of a reasonable range, then an alert is displayed and the function returns a false value. Notice the use of \n in the alert message to perform basic
formatting of the text:
else if (parseFloat(form.height.value) <= 0|| parseFloat(form.height.value) >=500|| parseFloat(form.weight.value) <= 0|| parseFloat(form.weight.value) >=500){ alert("\nReally know what you're doing? \nPlease enter values again. \nWeight in kilos and \nheight in cm"); ClearForm(form); return false; }
If the data is acceptable following both these checks, then the function simply returns a true value.
The computeform() function is where the primary work of the script is done. This function is called when the user clicks on the Let's See button, and it accepts the form object as an argument.
The script starts by calling checkform() to be sure the data is valid. If the data passes muster in the checkform() function, the function proceeds to make the necessary calculations:
yourbmi=Math.round(bmi(form.weight.value, form.height.value/100)); form.bmi.value=yourbmi;
The program first calls bmi() and passes the weight and height entered by the user. The height is divided by 100 because the bmi() function expects the height in meters, and there are 100 centimeters in a meter. Math.round() is used to round the results
to the nearest integer and then the value is assigned to yourbmi.
Notice that yourbmi is not defined using the var statement. As you learned in Chapter 4, "Functions and Objects: The Building Blocks," JavaScript is perfectly happy to define variables when they are first used without the var statement.
if (yourbmi >40) { form.my_comment.value="You are grossly obese, consult your physician!"; } else if (yourbmi >30 && yourbmi <=40) { form.my_comment.value="Umm... You are obese, want some liposuction?"; } else if (yourbmi >27 && yourbmi <=30) { form.my_comment.value="You are very fat, do something before it's too late"; } else if (yourbmi >22 && yourbmi <=27) { form.my_comment.value="You are fat, need dieting and exercise"; } else if (yourbmi >=21 && yourbmi <=22) { form.my_comment.value="I envy you. Keep it up!!"; } else if (yourbmi >=18 && yourbmi <21) { form.my_comment.value="You are thin, eat more."; } else if (yourbmi >=16 && yourbmi <18) { form.my_comment.value="You are starving. Go Find some food!"; } else if (yourbmi <16) { form.my_comment.value="You're grossly undernourished, need hospitalization "; } }
The rest of the function simply consists of a long if ..else if ... else ... construct that checks the value of yourbmi against different ranges and places the appropriate message in the my_comment field in the form.