/    Sign up×
Community /Pin to ProfileBookmark

Input Validation Failure

Hello everyone! I have made a program that calculates a person’s GPA and it worked fine [URL=”http://userpages.umbc.edu/~ofek1/gpa.html”]http://userpages.umbc.edu/~ofek1/gpa.html[/URL].
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);

    }[/CODE]

    to post a comment
    JavaScript

    13 Comments(s)

    Copy linkTweet thisAlerts:
    @KorSep 20.2010 — 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.
    Copy linkTweet thisAlerts:
    @OfekmeisterauthorSep 20.2010 — 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.
    Copy linkTweet thisAlerts:
    @FangSep 20.2010 — [CODE]
    [COLOR="Red"]//[/COLOR] see http://alt-tag.com/blog/archives/2006/02/ie-dom-bugs/
    [COLOR="Red"]var newCredits = document.createElement('input'); // Create credit input field
    newCredits.setAttribute('type', 'text');
    newCredits.setAttribute('name', 'credits')[/COLOR];
    newCredits.setAttribute('maxlength', '1');
    [COLOR="Blue"]newCredits.onchange = function() {return ValidateCredits(this.value);};
    newCredits.form = 'gpaf';[/COLOR]
    [/CODE]

    Depending on what Validate does

    [I]onsubmit="Validate(); return false;" [/I] or [I]onsubmit="return Validate();" [/I]
    Copy linkTweet thisAlerts:
    @KorSep 20.2010 — and:
    <i>
    </i>newCredits.setAttribute('max[B][COLOR="Blue"]L[/COLOR][/B]ength', '1');
    Copy linkTweet thisAlerts:
    @OfekmeisterauthorSep 20.2010 — 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!"
    Copy linkTweet thisAlerts:
    @FangSep 21.2010 — 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".
    [/QUOTE]
    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.
    Copy linkTweet thisAlerts:
    @OfekmeisterauthorSep 21.2010 — The form is created dynamically after user's input:

    [CODE]<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">


    <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">


    <head>

    <meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
    <meta http-equiv="expires" content="Sat, 13 Sept 2008 12:00:00 GMT" />
    <meta http-equiv="cache-control" content="no-cache" />
    <meta http-equiv="pragma" content="no-cache" />

    <title>GPA Calculator</title>

    <script type="text/javascript" src="gpahtml.js"></script>

    </head>


    <body onload="GiveFocus()">

    <script type="text/javascript">
    //<![CDATA[
    <!--

    var semester = prompt("Enter the semester: ");
    var course = 1;

    do
    {

    numCourses = prompt("How many courses are you taking in the " + semester + " semester?");

    } while (numCourses <= 0 || isNaN(numCourses));

    numCourses = parseInt(numCourses);

    document.write('<form name="gpaf" id="gpaf" onsubmit="Validate(); return false;"><strong>Semester: </strong><input type="text" name="sem" value=' + semester + ' /><br />');

    while (numCourses > 0)
    {

    document.write('Number of credits for course ' + course + ': <br /><input type="text" name="credits" maxlength="1" onchange="ValidateCredits(this.value)" /><br /> Grade points earned for course ' + course + ': <br /><input type="text" name="points" maxlength="1" onchange="ValidatePoints(this.value)" /><br /><br />');

    numCourses--;
    course++;

    if (numCourses == 0)
    {

    document.write('<div id="newclass"><input type="submit" value="Calculate GPA" /></div></form><br />');

    document.write('<button type="button" onclick="AddClass()">Add a class</button>');

    }

    }

    //-->
    //]]>
    </script>

    </body>


    </html>[/CODE]
    Copy linkTweet thisAlerts:
    @OfekmeisterauthorSep 21.2010 — This is the javascript file, commented:

    [CODE]/***
    ** 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();

    }

    }[/CODE]
    Copy linkTweet thisAlerts:
    @OfekmeisterauthorSep 21.2010 — I have no clue
    Copy linkTweet thisAlerts:
    @FangSep 22.2010 — A created element can only be inserted once. The <br> has to be created each time[CODE] var creditText = document.createTextNode('Number of credits for course: ' + courseCount); // Insert credit input field
    marker.parentNode.insertBefore(creditText, marker);
    marker.parentNode.insertBefore(document.createElement('br'), marker);
    marker.parentNode.insertBefore(newCredits, marker);
    marker.parentNode.insertBefore(document.createElement('br'), marker);

    var pointText = document.createTextNode('Grade points earned for course: ' + courseCount); // Insert point input field
    marker.parentNode.insertBefore(pointText, marker);
    marker.parentNode.insertBefore(document.createElement('br'), marker);
    marker.parentNode.insertBefore(newPoints, marker);
    marker.parentNode.insertBefore(document.createElement('br'), marker);
    [/CODE]

    The same layout can be achieved with css. This is the preferred method to useinput {display:block; margin-bottom:2em;}
    Copy linkTweet thisAlerts:
    @OfekmeisterauthorSep 23.2010 — 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);

    }

    }[/CODE]


    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?
    Copy linkTweet thisAlerts:
    @OfekmeisterauthorSep 23.2010 — I deleted IE cache and now it WORKS! You too? http://userpages.umbc.edu/~ofek1/gpa.html
    Copy linkTweet thisAlerts:
    @FangSep 23.2010 — Appears to work, although I didn't check the validity of the final calculation.
    ×

    Success!

    Help @Ofekmeister spread the word by sharing this article on Twitter...

    Tweet This
    Sign in
    Forgot password?
    Sign in with TwitchSign in with GithubCreate Account
    about: ({
    version: 0.1.9 BETA 5.20,
    whats_new: community page,
    up_next: more Davinci•003 tasks,
    coming_soon: events calendar,
    social: @webDeveloperHQ
    });

    legal: ({
    terms: of use,
    privacy: policy
    });
    changelog: (
    version: 0.1.9,
    notes: added community page

    version: 0.1.8,
    notes: added Davinci•003

    version: 0.1.7,
    notes: upvote answers to bounties

    version: 0.1.6,
    notes: article editor refresh
    )...
    recent_tips: (
    tipper: @AriseFacilitySolutions09,
    tipped: article
    amount: 1000 SATS,

    tipper: @Yussuf4331,
    tipped: article
    amount: 1000 SATS,

    tipper: @darkwebsites540,
    tipped: article
    amount: 10 SATS,
    )...