Getting input values from forms

Hello!

I’m trying to write some javascript code that will give a user one of two messages (Correct or incorrect) base on whether they answer a question correctly. I have 2 issues that I was hoping someone could help me with:

  1. My “incorrect” and “correct” messages all appear on the page load. Is there anyway to start without them being there?

  2. More troubling: No matter what I put into the input boxes, the “incorrect” message pops up. Basically I need to better understand how to grab the actual input value (it’s commented down below so I think that this should be a quick fix!)

Thanks so much,

Eric

function showAnswer(blurred,response)
{
    var form = blurred.form;
    var rbs = form[blurred.name];
    for ( var r = 0; r < rbs.length; ++r )
    {
        var rb = rbs[r];
        var lbl = rb.parentNode;
        var ans = lbl.getElementsByTagName("span");
        
		ans[0].style.display = ( (rb == blurred) && (response == "correct")) ? "inline" : "none";
		ans[1].style.display = ( (rb == blurred) && (response == "incorrect")) ? "inline" : "none";
    }
}

window.onload = function() 
{
	var answers = new Array("13","10.8","9.8"); ///my actual number of inputs is a lot longer, hence the array.
    var inps = document.getElementsByTagName("input");
    for ( var i = 0; i < inps.length; ++i )
    {
        inp = inps[i];
		correct_answer = answers[i];
		
		var response = "incorrect"; //Assume it's incorrect
		
		if (inp == correct_answer) {response="correct";} //this SHOULD compare the input value to the correct response...help on this line please?


        if ( inp.type == "text" ) inp.onblur = function() { 
	//Assume Correct
			showAnswer(this,response);
		}
    }
}
<form>
 <table><tr>
    <td width="30" align="center">-2</td>
    <td align="center"><label><input name="answer" type="text" size="3" maxlength="4" /><span> Correct!</span><span>  Incorrect!</span></label></td>
  </tr>
  <tr>
    <td width="30" align="center">-1</td>
    <td align="center"><label><input name="answer" type="text" size="3" maxlength="4" /><span> Correct!</span><span>  Incorrect!</span></label></td>
  </tr>
  <tr>
    <td width="30" align="center">0</td>
    <td align="center"><label><input name="answer" type="text" size="3" maxlength="4" /><span> Correct!</span><span>  Incorrect!</span></label></td>
  </tr></table?>
</form>

Checking inp.value is what answers your question, but there are several other issues with the code.

If you don’t mind, I’ve taken the liberty of refactoring it in to smaller functions, that help to simplify the whole process.

To the form, I have added a unique identifier, so that we can easily target it from the script:


<form id="questions">

I’ve also removed the much duplicated spans with their “Correct!” and “Incorrect!” pieces, and replaced them with a single span at the end of the input. That allows us to write whatever we want in to there from the script itself.

If it’s always going to be “Correct!” or “Incorrect!” then that can be done easily from the script. Other types of situations can be easily handled from the script too if need be.


<input name="answer" type="text" size="3" maxlength="4" /><span></span>

When the page loads, it initializes the questions with the appropriate answers. I have also moved the code to the end of the body, which serves two purposes. First the page appears to load faster, and secondly, the onload technique no longer is required.


var form = document.getElementById('questions'),
    answers = ['13', '10.8', '9.8'];
initQuestions(form, answers);

The initQuestions function passes each input and its appropriate answer to be individually initialized:


function initQuestions(form, answers) {
    var questions = form.getElementsByTagName('input'),
        i;
    for (i = 0; i < questions.length; i += 1) {
        if (questions[i].type === 'text') {
            initField(questions[i], answers[i]);
        }
    }
}

The initField function attaches the correct answer on the the field, so that it can be easy found by the script later on. It also associates a function on to the onblur event for the field.


function initField(input, answer) {
    input.correctAnswer = answer;
    input.onblur = checkAnswer;
}

And lastly, the checkAnswer function shows an appropriate response to the value that was entered in the field:


function checkAnswer() {
    var label = this.parentNode,
        response = label.getElementsByTagName('span')[0],
        answerIsCorrect = (this.value === this.correctAnswer);
    response.innerHTML = (answerIsCorrect) ? 'Correct!' : 'Incorrect!';
}

Finally, I’ve wrapped the code in a self-invoking function, as a form of protection for the code itself.


(function () {
    ...
}());

Ideally the script should be in its own separate file, but apart from that, here’s the complete page for testing.


<!DOCTYPE HTML>
<html>
<head>
    <title>Test questions and answers</title>
</head>
<body>
<form id="questions">
 <table><tr>
    <td width="30" align="center">-2</td>
    <td align="center"><label><input name="answer" type="text" size="3" maxlength="4" /><span></span></label></td>
  </tr>
  <tr>
    <td width="30" align="center">-1</td>
    <td align="center"><label><input name="answer" type="text" size="3" maxlength="4" /><span></span></label></td>
  </tr>
  <tr>
    <td width="30" align="center">0</td>
    <td align="center"><label><input name="answer" type="text" size="3" maxlength="4" /><span></span></label></td>
  </tr></table?>
</form>
<script type="text/javascript">
(function () {
    var form = document.getElementById('questions'),
        answers = ['13', '10.8', '9.8'];
    initQuestions(form, answers);

    function initQuestions(form, answers) {
        var questions = form.getElementsByTagName('input'),
            i;
        for (i = 0; i < questions.length; i += 1) {
            if (questions[i].type === 'text') {
                initField(questions[i], answers[i]);
            }
        }
    }
    function initField(input, answer) {
        input.correctAnswer = answer;
        input.onblur = checkAnswer;
    }
    function checkAnswer() {
        var label = this.parentNode,
            response = label.getElementsByTagName('span')[0],
            answerIsCorrect = (this.value === this.correctAnswer);
        response.innerHTML = (answerIsCorrect) ? 'Correct!' : 'Incorrect!';
    }
}());
</script>
</body>
</html>

Thank you for both a well-documented and clear (code-wise) reply. As you can probably tell, I’m a newbie at Javascript and you’ve given me some very good big-picture and detail oriented ideas, in addition to answering my question. :slight_smile: