Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to validate user input by checking if something has been entered into the textbox. I trying to do this using javascript. What i want to achieve is, a user gets an alert box that a particular field is empty. A span will also be used to display an error message on the field that is required. Once the user starts typing, the error message should clear. Please how do i do this? Here is what I've done so far, but it is not working as expected and I feel like I'm repeating code. Fiddle

<form>
    <div id="Login">
        <div>
             <label for="signin_email">Email Address*: </label><input id="signin_email" name="signin_email" type="email" autofocus maxlength="50" /><span style="display:none;" id="signin_emailerror" name="signin_emailerror">*Please enter your Email address</span>
        </div>
        <div>
         <label for="signin_pword">Password*: </label><input id="signin_pword" name="signin_pword" type="password" maxlength="24"   /><span style="display:none;" id="signin_pworderror" name="signin_pworderror">*Please enter your Password</span>
        </div>
        <div>
           <button type="submit" id="signin" name="signin" value="Sign In" onclick="return signin_validate()">Sign in</button>
        </div>
    </div>

    <div id="register">
      <h2>Register here</h2>
          <div>
                <label for="fname">First Name*: </label>                        
                <input id="fname" name="fname" maxlength="30" type="text"  /><span style="display:none;" id="fnameerror" name="fnameerror">*Please enter your First Name</span>
          </div>
          <div>
            <label for="lname">Last Name*: </label><input id="lname" name="lname" maxlength="30" type="text"  /><span style="display:none;" id="lnameerror" name="lnameerror">*Please enter your Last Name</span>
          </div>
          <div>
            <button type="submit" id="register" name="register" value="Register" onclick="return validateForm()">Register</button>
          </div>
    </div>
</form>

Javascript:

function validateForm(){
var valid=true;
    var msg;
document.getElementById('fname').onkeyup=function(){
    if(document.getElementById('fname').value.length==0){
        valid=false;

        msg='Please enter your first name';
        document.getElementById('fnameerror').style.display='inline';
        document.getElementById('fnameerror').style.color='red';
        document.getElementById('fname').focus();
    }
    else{
        document.getElementById('fnameerror').style.display='none';
    }
if(document.getElementById('fname').value.length==0){
        document.getElementById('fnameerror').style.display='inline';
        document.getElementById('fnameerror').style.color='red';
        valid=false;
        document.getElementById('fname').focus();
        msg='Please enter your first name';
    }
    else{
        document.getElementById('fnameerror').style.display='none';
    }

    }
if(valid==false){
        alert(msg);
    }

    return valid;

}

    function signin_validate(){
    //VALIDATION FOR SIGN IN FORM
    //validating the password field
    //alert("You are here");
    var valid=true;
    var msg;

    if(document.getElementById('signin_email').value.length==0){
        valid=false;
        msg='Please enter your email';
        document.getElementById('signin_emailerror').style.display='inline';
        document.getElementById('signin_emailerror').style.color='red';
        document.getElementById('signin_email').focus();
    }


    else{

        document.getElementById('signin_emailerror').style.display='none';

        }
    document.getElementById('signin_email').onkeyup=function(){
        if(document.getElementById('signin_email').value.length==0){
        valid=false;
        msg='Please enter your email';
        document.getElementById('signin_emailerror').style.display='inline';
        document.getElementById('signin_emailerror').style.color='red';
        document.getElementById('signin_email').focus();
        }
        else{

        document.getElementById('signin_emailerror').style.display='none';

        }
    }

        if(valid==false){
        alert(msg);
    }

    return valid;


    }

Also, as seen in the fiddle, I have to 'forms', login and register. When i enter something in a field in register and i click the signin button, whatever i enter into register disappears. This happened on firefox but not on chrome, please how to fix this? Do i need to create two separate forms? Is it ideal to do so?

share|improve this question

2 Answers 2

Here's a solution that should support IE8+, but don't have IE8, so I can't confirm. It's written in Vanilla JavaScript, but you can clean this up a lot by using jQuery or some other framework.

Degrading your Browser

To simulate an old browser, I need to disable all "required" attributes. It's good to include them even if your browser doesn't support it as coding to the HTML5 standard will allow your web page to be forward compatible.

Here is a method to "turn-off" all required inputs.

// Strip out the require to simulate IE9
var simulateLegacyBrowser = function() {
    var nodes = document.querySelectorAll('[required=true]');
    Array.prototype.forEach.call(
        Array.prototype.slice.call(nodes),
        function(node) {
            node.required = false;
        });
};

Setting up your HTML

If you don't have access to the required attribute due to a legacy browser, the next best thing you can do is name your classes. You can then access all "required" elements by the class name. As an example:

<form id='myForm'>
    <div class="required">
        <label for='field1'>Field 1</label>
        <input typue="text" id='field1' name='field1' required='true' />
        <span class='status'></span>
    </div>
    <div class="required">
        <label for='field2'>Field 1</label>
        <input typue="text" id='field2' name='field2' required='true' />
        <span class='status'></span>
    </div>
    <div>
        <input type='submit' />
    </div>
</form>

Validating your Form

To validate the form, you'll have to hijack the onSubmit function. When working with JavaScript, it's best to be as unobtrusive as possible. That means that the HTML shouldn't be dependent on the JavaScript. If the user uses a browser without JavaScript, you'll have to use the server to validate your forms.

Here is the code. I had to create some helper methods to keep the code clean and working across browsers. This isn't a full proof solution, as it only select .required inputs. You'll have to modify this to support <select>, <textarea>, etc... I'll leave that as an exercise for you.

A note on getNextNode. The reason why I can't just call node.nextSibling is that in some browsers, node.nextSibling will return the next text node, in contrast, some browsers return the next element. So we need to setup a function to ensure cross-browser compatibility.

This code can be further generalized to work with any form you want, but I'll leave that to you to fix up.

// Get the next Element
var getNextNode = function(root) {
    var node = root;
    do {
        node = node.nextSibling;
    } while ( node.nodeType != 1 );
    return node;
};

// Set an input as invalid
var setInvalid = function(input) {
    var status = getNextNode(input);
    status.textContent = "This is a required field";
    input.className = [input.className, 'invalid'].join(' ');
};

// Set an input as valid
var setValid = function(input) {
    var status = getNextNode(input);
    status.textContent = '';
    input.className = input.className.replace(/invalid/g, '');
};

document.forms['myForm'].onsubmit = function(e) {
    e.preventDefault();
    e.stopPropagation();
    // Change this to select required elements
    var requiredInputs = document.querySelectorAll('.required input'); 
    // Loop through each "required" input
    Array.prototype.forEach.call(
        Array.prototype.slice.call(requiredInputs),
        // For each input
        function(input) {
            // If it's valid is empty
            if (input.value.length === 0) {
                setInvalid(input);
            } else {
                setValid(input);
            }
        });
};

Making it pretty

To make this look nice to the end user, if it permits, try to use CSS. This will separate your presentation from your logic. Use classes in your logic to call the correct presentations to apply. As an example, here is the presentation for this:

.required label:after {
    content: '*';
}

.required .status {
    color: red;
}

.required .invalid {
    border: 1px solid red;
}

Putting it all together

You can see a working example at this jsFiddle. Good luck and have fun coding!

Advanced Solution

For your interest, a more advance solution is available at this jsFiddle. I won't attach the code to this solution as it is beyond the scope, but it is much more configurable. In this solution, you can modify your HTML and then add the state settings for your HTML to a configuration array, which will update the DOM based on the state of the input.

share|improve this answer
    
@seun One more note, I recommend separating your two forms from each other. Have a <form> for login and another <form> for register. This way you can validate them separately using the code above if you have different rules for each. –  Pete Apr 7 '14 at 15:13
    
@seun Sorry, one more thing to note. I use the Array.prototype.forEach function, but you can easily use a for loop. The for loop should make this compatible with IE7+. –  Pete Apr 7 '14 at 15:19

You seem to be re-inventing the wheel a little bit. Why don't you simply add required to your input fields to stop them from being blank?

http://www.w3schools.com/tags/att_input_required.asp

That way it'll sort this issue out for you and you don't have the horrible alert message involved at all

share|improve this answer
    
The 'required'attribute isn't supported on all browsers though. @David G –  seun Apr 7 '14 at 14:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.