Server Side Validation

by TJ VanToll

HTML

<meta name="viewport" content="width=device-width, initial-scale=1">
<form novalidate>
    <div>
        <label for="name">Name:</label>
        <input type="text" name="name" id="name">
    </div>
    <div>
        <label for="email">Email:</label>
        <input type="email" name="email" id="email">
    </div>
    <div>
        <button>Submit</button>
    </div>
</form>

CSS

* { box-sizing: border-box; }
body {
    font-size: 1.2em;
}
body input, body button {
    font-size: 1.2em;
}

form > div {
    margin: 1em;
}
form button {
    width: 100%;
}
label { display: block; }
input {
    width: 100%;
    padding: 0.2em;
}
button {
    padding: 0.2em;
}

.error {
    color: red;
}
input.error {
    background: red;
    color: white;
}

JavaScript

// Pretend this is running server side
function validate( fields ) {
    var errors = {};
    if ( fields.name === "" ) {
        errors.name = "Name is required.";
    }
    if ( fields.email === "" ) {
        errors.email = "Email is required.";
    } else if ( !fields.email.match( /^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$/ ) ) {
        errors.email = "You must provide a valid email address.";
    }
    return errors;
};

function showErrors( errors ) {
    var field, span,
        errorMessages = document.querySelectorAll( "span.error" ),
        erredFields = document.querySelectorAll( "input.error" ),
        form = document.querySelector( "form" );
    
    for ( var i = 0; i < errorMessages.length; i++ ) {
        errorMessages[ i ].parentNode.removeChild( errorMessages[ i ] );
    }
    for ( i = 0; i < erredFields.length; i++ ) {
        erredFields[ i ].classList.remove( "error" );
    }
    
    for ( var error in errors ) {
        field = form.querySelector( "[name=" + error + "]" )
        field.classList.add( "error" );
        span = document.createElement( "span" );
        field.parentNode.appendChild( span );
        span.classList.add( "error" );
        span.innerHTML = errors[ error ];
    }
};

document.querySelector( "form" ).addEventListener( "submit", function() {
    event.preventDefault();
    
    // Mimic an actual server side call
    var errors = validate({ name: this.name.value, email: this.email.value });

    if ( Object.keys( errors ).length === 0 ) {
        alert( "Successful submission" );
    } else {
        showErrors( errors );
    }
});