New to JS, Please Help

My web page is at http://www.analog24.net/~cscott/Lab3-Trig/index.html

I am just learning to program in JS and one of my lessons involves this page. Rather than getting into the entire lesson (as I don’t want all the answers just given to me), I am having trouble with the following:

I have a web form that is using “onclick” to execute a function that simply displays a table. Inside of the “buildTable” function is a function call to re-display the web form (which is in the “buildForm” function).

The problem I am having is that when it executes, the table displays and so does the web form. However, clicking on the radio button again (which should call the “buildTable” function) does nothing.

I originally went this route because when I just called the “buildTable” function, it would display the table, but I would lose everything else on the page, so I had to re-paint the entire page this way instead. If you have a suggestion how to do this better, I am listening.

Here is my code. I hope you can help.

<html>
<head><title>Computer Science 553 Lab Pages</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/JavaScript">
	function buildForm(){
		document.write("<link rel='stylesheet' type='text/css' href='style.css' />");
		document.write("<h1>Lab 3: Trig Functions on the Fly</h1>");
		document.write("<div align='center'>");
		document.write("<form id='angleSelect' name='angleSelect' method='post'>");
		document.write("<input type='radio' name='angleSelect' id='angleDegrees' value='1' onclick='buildTableDegrees(\\"Degrees\\")'>");
		document.write("<label for='angleSelect'>Degrees</label>");
		document.write("<input type='radio' name='angleSelect' id='angleRadian' value='1' onclick='buildTableRadians(\\"Radians\\")'>");
		document.write("<label for='angleSelect'>Radian</label>");
		document.write("</form>");
		document.write("</div>");
	}
	function buildTableDegrees(inText){
		buildForm();
		document.write("<div align='center'>");
		document.write("<table border='1'>");
		document.write("<tr><th>" + inText + "</th>");
		document.write("<th>sin(x)</th>");
		document.write("<th>cos(x)</th>");
		document.write("<th>tan(x)</th>");
		document.write("</tr>");
		for ( var i = 0; i < 13; i++ )	{
			openTableRow();
			writeTableData(i + " " + inText)
			writeTableData("sin(" + i + ")");
			writeTableData("cos(" + i + ")");
			writeTableData("tan(" + i + ")");
			closeTableRow();
		}
		document.write("</table>");
		document.write("</div>");
	}

	function buildTableRadians(inText){
		buildForm();
		document.write("<div align='center'>");
		document.write("<table border='1'>");
		document.write("<tr><th>" + inText + "</th>");
		document.write("<th>sin(x)</th>");
		document.write("<th>cos(x)</th>");
		document.write("<th>tan(x)</th>");
		document.write("</tr>");
		for ( var i = 0; i < 13; i++ )	{
			openTableRow();
			writeTableData(i + " " + inText);	// radians Column
			writeTableData("sin(" + i + ")");	// sin(x) Column
			writeTableData("cos(" + i + ")");	// cos(x) Column
			writeTableData("tan(" + i + ")");	// tan(x) Column
			closeTableRow();
		}
		document.write("</table>");
		document.write("</div>");
	}
	
	function writeTableData(inText){
		document.write("<td>" + inText + "</td>");
	}

	function openTableRow(){
		document.write("<tr>");
	}

	function closeTableRow(){
		document.write("</tr>");
	}
</script>
</head>
<body>
<script type="text/JavaScript">buildForm();</script>
</div>

</body></html>

Hello,

document.write is one of the evil parts of javascript that you should avoid using entirely.
If it’s ran after the initial page load it replaces the whole document, which is what you’re seeing.

It’s better to replace a section of the page by setting an elements innerHTML to the new content. e.g.


<!doctype html>
<html>
<head><title>Computer Science 553 Lab Pages</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<script type="text/javascript">
function buildTable(inText) {
  var html = "";
  html += "<div align='center'>";
  html += "<table border='1'>";
  html += "<tr><th>" + inText + "</th>";
  html += "<th>sin(x)</th>";
  html += "<th>cos(x)</th>";
  html += "<th>tan(x)</th>";
  html += "</tr>";
  for (var i = 0; i < 13; i++)  {
    html += "<tr>";
    html += "<td>" + (i + " " + inText) + "</td>"
    html += "<td>sin(" + i + ")</td>"
    html += "<td>cos(" + i + ")</td>"
    html += "<td>tan(" + i + ")</td>"
    html += "</tr>";
  }
  html += "</table>";
  html += "</div>";

  document.getElementById('results').innerHTML = html;
}
</script>
</head>
<body>
<h1>Lab 3: Trig Functions on the Fly</h1>
<div align="center">
  <form method="post">
    <input type="radio" name="angleSelect" id="angleDegrees" value="1" onclick="buildTable('Degrees')">
    <label for="angleSel">Degrees</label>
    <input type="radio" name="angleSelect" id="angleRadians" value="1" onclick="buildTable('Radians')">
    <label for="angleSel">Radian</label>
  </form>
</div>
<div id="results"></div>
</body>
</html>

You should be weary of ever building long strings of HTML like this in javascript though.
Any time you see yourself doing this you would be better using a javascript template like EJS.

Hope it helps

Thank you for your time. This was very helpful, especially the EJS link.

After doing some research, I finally ended up with 3 files. The index.html page looks like this:

<html>
<head><title>Computer Science 553 Lab Pages</title>
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<script type="text/JavaScript" src="trig.js"></script>
	<h1>Table of Sines, Cosines, and Tangents</h1>
	<h2>Charles P. Scott    |    9092</h2>
	
	<script type="text/JavaScript">buildForm();</script>
	<br />

</body></html>

The styles.css file looks like this:

/* Lab 3: Trig Functions On The Fly */

body{
	font-family:arial,helvetica,san-serif;
	background:#ffffff;
	color:#000000;
	margin-top:0px;
}

a:link	{color: #009900;}
a:visited	{color: #999999;}
a:hover	{color: #333333;}
a:focus 	{color: #333333;}
a:active 	{color: #009900;}

h1, h2, h3, h4, h5{
	text-align:center;
}

h1{
	color:darkgreen;
}

h2{
	color:mediumblue;
}

table{
    width:70%;
    margin-left:15%;
    margin-right:15%;
    padding:7px;
    border-spacing:7px;
}

table/*, table.tableForm*/{
    border:1px solid #000000;
    align:center;
}

.tableForm{
    width:40%;
    margin-left:30%;
    margin-right:30%;
    background-color:lightblue;
    padding:0px;
    border-spacing:0px;
}

table.tableForm.td{
	vertical-align:middle;
	text-align:center;
	position:absolute;
	top:50%;
	height:10em;
	margin-top:-5em
}

.alt{
	background:darkblue;
	color:white;
}

th, td{
	border:1px solid black;
	vertical-align:middle;
	text-align:center;
}
th{
	background-color:green;
	color:#ffffff;
	font-size:20px;
	padding:5px;
}

label {
	float: center;
	text-align: right;
	margin-right: 15px;
	width: 100px;
}

and the trig.js file looks like this:

function buildForm(){
	var tableForm = document.createElement('table');
	tableForm.setAttribute('class','tableForm');
	var tRowForm = document.createElement('tr');
	var tCellForm = document.createElement('td');

	var form = document.createElement("form");

	// First Radio Input
	var radioDegrees = document.createElement('input');
	radioDegrees.setAttribute('type','radio');
	radioDegrees.setAttribute('name','angleSelect');
	radioDegrees.setAttribute('onclick','buildTable("degrees")');
	form.appendChild(radioDegrees);
	var radioDegreesL = document.createElement('label');
	radioDegreesL.appendChild(document.createTextNode('Display in Degrees'));
	form.appendChild(radioDegreesL);

	// Second Radio Input
	var radioRadians = document.createElement('input');
	radioRadians.setAttribute('type','radio');
	radioRadians.setAttribute('name','angleSelect');
	radioRadians.setAttribute('onclick','buildTable("radians")');
	form.appendChild(radioRadians);
	var radioRadiansL = document.createElement('label');
	radioRadiansL.appendChild(document.createTextNode('Display in Radians'));
	form.appendChild(radioRadiansL);
	
	tCellForm.appendChild(form);
	tRowForm.appendChild(tCellForm);	
	tableForm.appendChild(tRowForm);	
	document.body.appendChild(tableForm);
}

function buildTable(tableType){
	var table1 = document.createElement("table");
	//table1.style.width='70%';
	//table1.setAttribute('border','1');
	table1.setAttribute('id','myTable');
		var tRowH = document.createElement('tr');
		var tCellH_1 = document.createElement('th');
			tRowH.appendChild(tCellH_1);
			
			if (tableType==="degrees"){
				tCellH_1.appendChild(document.createTextNode('Degrees'));
			} else if (tableType==="radians"){
				tCellH_1.appendChild(document.createTextNode('Radians'));
			}
			
		var tCellH_2 = document.createElement('th');
			tRowH.appendChild(tCellH_2);
			tCellH_2.appendChild(document.createTextNode('sin(x)'));
		var tCellH_3 = document.createElement('th');
			tRowH.appendChild(tCellH_3);
			tCellH_3.appendChild(document.createTextNode('cos(x)'));
		var tCellH_4 = document.createElement('th');
			tRowH.appendChild(tCellH_4);
			tCellH_4.appendChild(document.createTextNode('tan(x)'));
		table1.appendChild(tRowH);

		var angleR = 0;
		var angleD = 0;
		
	for ( var i=0; i<25; i++ ) {
		var tRow = document.createElement('tr');
		if ((i+1)%2==0){
			tRow.setAttribute('class','alt');
		}
		
		var tCell_1 = document.createElement('td');
		tRow.appendChild(tCell_1);
		
		if (tableType==="degrees"){
			tCell_1.appendChild(document.createTextNode(angleD + "°"));
		} else if (tableType==="radians"){
			var angleRImg = document.createElement('img');
			angleRImg.setAttribute('src', 'images/img' + angleD + '.gif');
			tCell_1.appendChild(angleRImg);
		}
		
		var tCell_2 = document.createElement('td');
		tRow.appendChild(tCell_2);
		var result=Math.round(Math.sin(angleR)*100000)/100000
		tCell_2.appendChild(document.createTextNode(result));
		
		
		var tCell_3 = document.createElement('td');
		tRow.appendChild(tCell_3);
		var result=Math.round(Math.cos(angleR)*100000)/100000
		tCell_3.appendChild(document.createTextNode(result));
		
		var tCell_4 = document.createElement('td');
		tRow.appendChild(tCell_4);
		if ((angleD === 90) || (angleD === 270)){
			var result= "Undefined";
		}
		else {
			var result=Math.round(Math.tan(angleR)*100000)/100000
		}
		tCell_4.appendChild(document.createTextNode(result));

		table1.appendChild(tRow);
		angleR += Math.PI/12; // The Same as 15 Degrees
		angleD += 15;
	}
		if (document.getElementById("myTable") instanceof HTMLTableElement) {
			var currentTable = document.getElementById("myTable");
			currentTable.parentNode.replaceChild(table1, currentTable);
		}
		else {
			document.body.appendChild(table1);
		}
}

It is all working now.

What do you think?

Good work getting things running, that’s the first step :wink:

This style of javascript is DOM scripting and isn’t very popular anymore because it’s so long winded creating, appending, setting attributes using DOM methods.
It’s much better to separate your HTML from the data using JS templates.
There’s no reason to build the form with javascript so I’d keep that in the page from the beginning like in my example.

That’s a good suggestion. My problem is that I did not know how to make the JavaScript display the table at a specific location.

Have another look at my first example, there is a div with id=“results”, you can set it’s content with the following

document.getElementById('results').innerHTML = html;

Thank you for all you help. Now that I am beginning to understand, I am off to the next project lesson.