To calculate torque I need to look up a value from a table which I've hardcoded based on three conditions: grade, size, and thread. Then I need to multiply it by coefficients associated with the selected lubricants.
I've written the code to be a web-app, but it will also just run as an html file sitting on a company drive, not connected to the internet. Because it's offline, I needed to hardcode the values instead of look them up from a data file because of same-origin policy and JavaScript security settings. It's not ideal style, but I couldn't think of an alternative.
It works, but I want to make sure it's really robust and easy for anyone to maintain after my internship is done. It's one of the first programs I've written in this language and I don't get easily offended, so please be thorough! I'm not sure what's considered good style or efficient. Also, this needs to be run on IE8 so some things I've done have reflected the limitations of that browser.
JavaScript
var size;
var grade;
var thread;
var value;
document.getElementById("message").innerHTML = "Select grade.";
function fetch_grade_sizes() {
// get grade from select menu
var grade_menu = document.getElementById("grade_menu");
grade = grade_menu.options[grade_menu.selectedIndex].value;
// get thread from radio buttons
var radios = document.getElementsByName("radio");
for (var i = 0, length = radios.length; i < length; i++) {
if (radios[i].checked) {
thread = radios[i].value;
break;
}
}
// tell user to select any missing values
if( grade === undefined || grade == ""){
document.getElementById("message").innerHTML = "Select grade.";
return;
}
else if ( thread === undefined || thread === null){
document.getElementById("message").innerHTML = "Select thread.";
return;
}
else
document.getElementById("message").innerHTML = "Select size.";
// get the sizes corresponding to that grade and thread
var size_keys = [];
for (var key in torque_table[grade][thread]) {
size_keys.push(key);
}
// populate the drop down selet menu with those sizes
create_menu("size_menu_location", "size_menu", size_keys);
}
function calculate(form_data) {
document.getElementById("message").innerHTML = "Select lubricant.";
// get selected size
var size_menu = document.getElementById("size_menu");
size = size_menu.options[size_menu.selectedIndex].value;
// if anything hasn't been selected yet, prompt the user
if( grade === undefined || grade == ""){
document.getElementById("message").innerHTML = "Select grade.";
return;
}
else if ( thread === undefined || thread === null){
document.getElementById("message").innerHTML = "Select thread.";
return;
}
else if (size === undefined || size == "" ){
document.getElementById("message").innerHTML = "Select size.";
return;
}
// look up the torque
var torque = torque_table[grade][thread][size];
// multiply each checked value together and
// create a string of the values separated by multiplication signs
var check_number = 1;
var check_string = "";
for (i = 0; i < form_data.check_menu.length; i++) {
if (form_data.check_menu[i].checked) {
check_string += " × " + form_data.check_menu[i].value;
check_number *= form_data.check_menu[i].value;
// clear the command to select something after a lubricant is selected
document.getElementById("message").innerHTML = "<br/>";
}
}
// round the resulting value to one decimal place
value = Math.round((torque * check_number) * Math.pow(10, 1)) / Math.pow(10, 1);
var value_in = Math.round((torque * check_number * 12) * Math.pow(10, 1)) / Math.pow(10, 1);
var value_SI = Math.round((torque * check_number * 1.35581795) * Math.pow(10, 1)) / Math.pow(10, 1);
// display the multiplication string and the resulting value
document.getElementById("number").innerHTML = value + " ft-lbs ";
document.getElementById("string").innerHTML = torque + " ft-lbs " + check_string + " = ";
document.getElementById("additional_info").innerHTML = "<br>Other units: " + value_in + " in-lbs, " + value_SI + " Nm";
}
function create_menu(div_id, sel_id, menu_options) {
var myDiv = document.getElementById(div_id);
// wipe what's already in the div we're putting this menu
myDiv.innerHTML = "";
// create select menu and size
var selectList = document.createElement("select");
selectList.setAttribute("id", sel_id);
selectList.setAttribute("onclick", "calculate(this.form);");
myDiv.appendChild(selectList);
// make an unselectable placeholder
var option = document.createElement("option");
//option.setAttribute("disabled","true");
option.innerHTML = "Select size";
option.setAttribute("value", "");
selectList.appendChild(option);
// populate the menu with the options from the array
for (var i = 0; i < menu_options.length; i++) {
var option = document.createElement("option");
option.setAttribute("value", menu_options[i]);
option.innerHTML = menu_options[i];
selectList.appendChild(option);
}
};
grade_1 = {
'coarse': {
'1/4"': 3.28,
'5/16"': 6.75,
'3/8"': 12.0,
'7/16"': 19.2,
'1/2"': 29.3,
'9/16"': 42.2,
'5/8"': 58.3,
'3/4"': 103,
'7/8"': 167,
'1"': 250,
'1-1/8"': 354,
'1-1/4"': 500,
'1-3/8"': 655,
'1-1/2"': 869
},
'fine': {
'1/4"': 3.75,
'5/16"': 7.49,
'3/8"': 13.6,
'7/16"': 21.4,
'1/2"': 33.0,
'9/16"': 47.1,
'5/8"': 66.0,
'3/4"': 115,
'7/8"': 184,
'1"': 273,
'1-1/8"': 397,
'1-1/4"': 553,
'1-3/8"': 746,
'1-1/2"': 978
}
};
//grade_5, grade_8 = .... same things
var torque_table = {
"grade_1": grade_1,
"grade_5": grade_5,
"grade_8": grade_8,
"stainless": stainless,
"monel": monel,
"ASTM_A325": ASTM_A325
};
HTML
<font size="5"><b>Torque Calculator
</b></font>
<FORM NAME="calculation">
<br/>
<select id="grade_menu" onchange="fetch_grade_sizes();">
<option value="" disabled selected>Select grade</option>
<option value="grade_1">Grade 1</option>
<option value="grade_5">Grade 5</option>
<option value="grade_8">Grade 8</option>
<option value="ASTM_A325">ASTM A325</option>
<option value="stainless">316 Stainless</option>
<option value="monel">Monel</option>
</select>
<INPUT TYPE="radio" name="radio" id="radio_menu" onclick="fetch_grade_sizes();" VALUE="coarse" />coarse
<INPUT TYPE="radio" name="radio" id="radio_menu" onclick="fetch_grade_sizes();" VALUE="fine" />fine
<br/>
<div id="size_menu_location">
<select id="size_menu">
<option value="" disabled selected>Select size</option>
</select>
</div>
<br><b>Check lubricant used:</b> <br>
<br/>
<INPUT TYPE="Checkbox" id="check_menu" onclick="calculate(this.form);" VALUE="1.00" />Steel (clean, dry, non-plated)<br/>
<INPUT TYPE="Checkbox" id="check_menu" onclick="calculate(this.form);" VALUE="1.00" />Black oxide<br/>
<INPUT TYPE="Checkbox" id="check_menu" onclick="calculate(this.form);" VALUE="0.90" />Silver grade anti-seize<br/>
<INPUT TYPE="Checkbox" id="check_menu" onclick="calculate(this.form);" VALUE="0.80" />WD-40 <br/>
<INPUT TYPE="Checkbox" id="check_menu" onclick="calculate(this.form);" VALUE="0.75" />Grease with nickel and graphite flakes <br/>
<INPUT TYPE="Checkbox" id="check_menu" onclick="calculate(this.form);" VALUE="0.70" />Motor oil with cadmium plating <br/>
<INPUT TYPE="Checkbox" id="check_menu" onclick="calculate(this.form);" VALUE="0.65" />Nickel based anti-seize <br/>
<INPUT TYPE="Checkbox" id="check_menu" onclick="calculate(this.form);" VALUE="0.45" />Never-seize<br/>
<INPUT TYPE="Checkbox" id="check_menu" onclick="calculate(this.form);" VALUE="0.80" />243<br/>
<INPUT TYPE="Checkbox" id="check_menu" onclick="calculate(this.form);" VALUE="0.85" />246<br/>
<INPUT TYPE="Checkbox" id="check_menu" onclick="calculate(this.form);" VALUE="0.95" />248<br/>
<INPUT TYPE="Checkbox" id="check_menu" onclick="calculate(this.form);" VALUE="1.00" />277
</FORM>
<br/>
<div id="message"></div>
<table>
<td>
<div id="string"></div>
</td>
<td>
<div id="number"></div>
</td>
</table>
<div id="additional_info"></div>
<font size='1'><br>About:<br>
Calculated by multiplying standard dry torque with a stress of 70% minimum <br>
tensile strength or 75% the proof strength by a coefficient representing <br>
the effect of anti-seize compounds, lubricants, platings, coatings, etc. <br>
For steel, this cooefficient is equal to the torque coefficient (K) times 5.0 <br>
<br>Values are from <i>Pocket Ref</i> by Thomas J. Glover, 4th ed., 2011. pg 213</font>