Hello everyone! I have made a program that calculates a person's GPA and it worked fine http://userpages.umbc.edu/~ofek1/gpa.html.
Yesterday, though, I added a "Add a class" button and now have 2 problems.
1. If I say I'm taking ONE class and enter grades it calls GenerateGradeReport() and everything works fine. If I enter anything but a number it alerts the user and doesn't call GenerateGradeReport(), perfect still.
However, if I say I'm taking MORE THAN ONE class (even before adding a class dynamically) and enter grades it calls GenerateGradeReport() and everything works fine, still. But...if I enter anything but a number it alerts the user BUT STILL CALLS GenerateGradeReport()! As in only the first class' input controls the submission. The rest of the inputs can be invalid but it still proceeds!
And in the form if I try onsubmit="return Validate(); return false;" (like it should be) instead of just onsubmit="Validate(); return false;" (like it is now), the page gets reloaded on submission!
2. The is pretty minor but, in my function AddClass() the line breaks aren't getting inserted. I must have incorrect syntax
Code:
function AddClass()
{
var newCredits = document.createElement('input'); // Create credit input field
newCredits.setAttribute('type', 'text');
newCredits.setAttribute('name', 'credits');
newCredits.setAttribute('maxlength', '1');
newCredits.setAttribute('onchange', 'return ValidateCredits(this.value)');
newCredits.setAttribute('form', 'gpaf');
var newPoints = document.createElement('input'); // Create point input field
newPoints.setAttribute('type', 'text');
newPoints.setAttribute('name', 'points');
newPoints.setAttribute('maxlength', '1');
newPoints.setAttribute('onchange', 'return ValidatePoints(this.value)');
newPoints.setAttribute('form', 'gpaf');
var courseCount = document.getElementsByName('credits').length + 1; // Constants, for later use
var marker = document.getElementById('submit');
var newLine = document.createElement('br');
var creditText = document.createTextNode('Number of credits for course: ' + courseCount); // Insert credit input field
marker.parentNode.insertBefore(creditText, marker);
marker.parentNode.insertBefore(newLine, marker);
marker.parentNode.insertBefore(newCredits, marker);
marker.parentNode.insertBefore(newLine, marker);
var pointText = document.createTextNode('Grade points earned for course: ' + courseCount); // Insert point input field
marker.parentNode.insertBefore(pointText, marker);
marker.parentNode.insertBefore(newLine, marker);
marker.parentNode.insertBefore(newPoints, marker);
marker.parentNode.insertBefore(newLine, marker);
}
You have a bigger problem than those you have mentioned. Your code won't work under IE, for several reasons: IE does not consider the events as attributes. IE has a bug: it does not handle too well the name attribute in case of DOM new created elements. IE needs the camel-case in case of creating compounded HTML attributes. Don't give your submit button the name or id = submit. IE will be confounded whether it's about the submit() method or the element called submit.
Kor, I'm very confused. I don't understand why IE doesn't even display the initial prompt, I mean that works in FF, Chrome, and Safari. I did what you said, though, and put a div around the submit button instead.
Note: My IE testing may be inaccurate because I have the IE9 beta, and it won't let me uninstall.
Kor, I changed them to camelcase, Fang I cannot use newCredits.onchange = function() {return ValidateCredits(this.value);};
newCredits.form = 'gpaf'; because an error says "setting a property that has only a getter".
Guys! The only actual problem with my function AddClass() is the line breaks aren't getting inserted. The issue comes even if I don't call it.
"However, if I say I'm taking MORE THAN ONE class (even before adding a class dynamically) and enter grades it calls GenerateGradeReport() and everything works fine, still. But...if I enter anything but a number it alerts the user BUT STILL CALLS GenerateGradeReport()! As in only the first class' input controls the submission. The rest of the inputs can be invalid but it still proceeds!"
Fang I cannot use newCredits.onchange = function() {return ValidateCredits(this.value);};
newCredits.form = 'gpaf'; because an error says "setting a property that has only a getter".
Probably a conflict with 'form', use a different name. If the changes are not made the code will not work in IE.
Post the relevant html; dom changes can silently fail if a method does not work.
At least 98% of internet users' DNA is identical to that of chimpanzees
/***
** ValidateCredits - Checks if value entered is a valid number of credits
** Input - A number
** Output - Boolean value
*****/
function ValidateCredits(validNumber)
{
validNumber = parseInt(validNumber);
if (validNumber <= 0 || validNumber >= 5 || isNaN(validNumber))
{
alert("Enter a positive integer from 1 to 4 for the number of credits");
return false;
}
else
{
return true;
}
}
/********
** ValidatePoints - Checks if value entered is a valid number of points
** Input - A number
** Output - Boolean value
********/
function ValidatePoints(validNumber)
{
validNumber = parseInt(validNumber);
if (validNumber < 0 || validNumber > 4 || isNaN(validNumber))
{
alert("Enter a positive integer from 0 to 4 for the number of points earned");
return false;
}
else
{
return true;
}
}
/****************************************************************************
** TotalPoints - Totals the number of quality points earned
** Input - None
** Output - Total quality points earned
****************************************************************************/
function TotalPoints()
{
var numCredits = document.getElementsByName('credits');
var numPoints = document.getElementsByName('points');
var totalPoints = 0;
for (var i = 0; i < numCredits.length; i++)
{
totalPoints = totalPoints + (parseInt(numCredits[i].value) * parseInt(numPoints[i].value));
}
return totalPoints;
}
/****************************************************************************
** TotalCredits - Totals the number of credits taken
** Input - None
** Output - Total credits taken
****************************************************************************/
function TotalCredits()
{
var numCredits = document.getElementsByName('credits');
var totalCredits = 0;
for (var i = 0; i < numCredits.length; i++)
{
totalCredits = totalCredits + parseInt(numCredits[i].value);
}
return totalCredits;
}
/****************************************************************************
** GenerateGradeReport - Displays the grade report to the user
** Input - Semester
** Output - None
****************************************************************************/
function GenerateGradeReport(semester)
{
var finalGPA = CalculateGPA();
var totalCredits = TotalCredits();
var totalPoints = TotalPoints();
parent.showframe.document.getElementById('s').innerHTML = "GPA report for " + semester + "<br /><br />";
parent.showframe.document.getElementById('ct').innerHTML = "Credits taken: " + totalCredits + "<br /><br />";
parent.showframe.document.getElementById('qp').innerHTML = "Quality points earned: " + totalPoints + "<br /><br />";
parent.showframe.document.getElementById('gpa').innerHTML = "GPA for " + semester + ": " + finalGPA.toFixed(3) + "<br /><br />";
}
/****************************************************************************
** CalculateGPA - Divides total quality points by number of credits taken
** Input - None
** Output - Calculated GPA
****************************************************************************/
function CalculateGPA()
{
var finalGPA;
finalGPA = TotalPoints() / TotalCredits();
finalGPA = parseFloat(finalGPA);
return finalGPA;
}
/****************************************************************************
** Validate - Checks if all entries are valid
** Input - None
** Output - None
****************************************************************************/
function Validate()
{
var numCredits = document.getElementsByName('credits');
var numPoints = document.getElementsByName('points');
var semester = document.getElementsByName('sem');
for (var i = 0; i < numCredits.length; i++)
{
if (!ValidateCredits(numCredits[i].value) || !ValidatePoints(numPoints[i].value))
{
return false; /* NOT RETURNING FALSE ON ANY CLASS AFTER THE FIRST!!! */
}
else
{
GenerateGradeReport(semester[0].value);
}
}
}
/****************************************************************************
** AddClass - Adds input fields for a new class
** Input - None
** Output - None
****************************************************************************/
function AddClass()
{
var newCredits = document.createElement('input'); // Create credit input field
newCredits.setAttribute('type', 'text');
newCredits.setAttribute('name', 'credits');
newCredits.setAttribute('maxLength', '1');
newCredits.setAttribute('onChange', 'ValidateCredits(this.value)');
var newPoints = document.createElement('input'); // Create point input field
newPoints.setAttribute('type', 'text');
newPoints.setAttribute('name', 'points');
newPoints.setAttribute('maxLength', '1');
newPoints.setAttribute('onChange', 'ValidatePoints(this.value)');
var courseCount = document.getElementsByName('credits').length + 1; // Constants, for later use
var marker = document.getElementById('newclass');
var newLine = document.createElement('br');
var creditText = document.createTextNode('Number of credits for course: ' + courseCount); // Insert credit input field
marker.parentNode.insertBefore(creditText, marker);
marker.parentNode.insertBefore(newLine, marker);
marker.parentNode.insertBefore(newCredits, marker);
marker.parentNode.insertBefore(newLine, marker);
var pointText = document.createTextNode('Grade points earned for course: ' + courseCount); // Insert point input field
marker.parentNode.insertBefore(pointText, marker);
marker.parentNode.insertBefore(newLine, marker);
marker.parentNode.insertBefore(newPoints, marker);
marker.parentNode.insertBefore(newLine, marker);
}
/****************************************************************************
** GiveFocus - Gives focus to the first input field
** Input - None
** Output - None
****************************************************************************/
function GiveFocus()
{
var cred = document.getElementsByName('credits');
if (cred.length == 0)
{
cred.focus();
}
else
{
cred[0].focus();
}
}
Line breaks worked, thanks. Got it! My else statement was applicable to EVERY iteration of the loop, not just at the end. Now it works:
Code:
function Validate()
{
var numCredits = document.getElementsByName('credits');
var numPoints = document.getElementsByName('points');
var semester = document.getElementsByName('sem');
var boo = true;
for (var i = 0; i < numPoints.length; i++)
{
if (!ValidateCredits(numCredits[i].value) || !ValidatePoints(numPoints[i].value))
{
boo = false;
break;
}
}
if (boo == false)
{
return boo;
}
else
{
GenerateGradeReport(semester[0].value);
}
}
Now, can one of you please tell me what this is doing in IE for you? http://userpages.umbc.edu/~ofek1/gpa.html I don't trust mine because it's the beta.
For me, it loads the "showframe" containing the directions and then freezes. It doesn't even get to the prompts, the very first step! Why??? Though, when I open it locally, it works fine. What's happenning?
Last edited by Ofekmeister; 09-22-2010 at 10:19 PM.
Bookmarks