Page and control level validation using javascript with asp.net

This sample is a complete minimal implementation of client side verification of inputs before a pass to the server is made. Verification is done on control level with the onblur() event, and on page level when the form is submitted. This validation is faster then round-tripping to the server for each event, especialy with large complex pages with a lot of controls. The downside is additional code (javascript) in the markup section of your pages. Additionaly you need to consider which validation is still needed serverside, since any client side script code can be manipulated rather easily with customer facing code.

Markup

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>
 
<!DOCTYPE html>
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <!-- Mini style sheet for formatting the validation indicator -->
    <style type="text/css">
        .ValidationMessageClass {
            background-color: red;
            color: white;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            Input a number: 
            <!-- The textbox is validation when the content changes -->
            <asp:TextBox ID="TextBoxWaarde" runat="server" Text=""></asp:TextBox>
             
            <!-- Page level validation is performed on submission -->
            <asp:Button ID="Button1" runat="server" Text="Check input"
                OnClientClick="return Validate();" OnClick="Button1_Click" />
            <asp:Label runat="server" ID="LabelPageSubmitted" Text="Not Valid"></asp:Label>
 
        </div>
    </form>
</body>
</html>
 
 
<script type="text/javascript">
    var waardeHandle = document.getElementById('<%=TextBoxWaarde.ClientID %>');
    waardeHandle.onblur = function () {
        // Configure
        var minLength = 1;
        var maxLength = 6;
        var waardeValue = document.getElementById('<%=TextBoxWaarde.ClientID %>').value;
        // Perform validation
        if (waardeValue.length < minLength
            || waardeValue.length > maxLength
            || isNaN(waardeValue)) {
            // Invalid, color red and insert warning span if not already there
            var next = this.nextSibling;
            if (!next || next.className != 'ValidationMessageClass') {
                var warnSpan = document.createElement("span");
                warnSpan.innerHTML = '*';
                warnSpan.className = 'ValidationMessageClass';
                this.parentNode.insertBefore(warnSpan, this.nextSibling);
            }
        } else {
            // valid, remove formatting and error span
            var nextremove = this.nextSibling;
            if (nextremove && nextremove.className == 'ValidationMessageClass') {
                this.parentNode.removeChild(nextremove);
            }
        }
    };
    // validate during page-submit. If any controls have a warning behind them the page does not validate.
    function Validate() {
        var check01 = waardeHandle.value;
        if (isNaN(check01) || check01.length < 1 || check01.length > 6)
        {
            return false;
        }
        // ... repeat ...
        return true;
    }
</script>

Code behind

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
 
namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
 
        }
 
        protected void Button1_Click(object sender, EventArgs e)
        {
            LabelPageSubmitted.Text = "Valid";
        }
    }
}

Cleaning up

Code clobbering the markup isnt a good thing, so the next step is to put the javascript code in a seperate file. We cant simply copy/paste the lot of it into a seperate file because we will no longer have the clientId value’s at our disposal. The logical solution is to keep a small javascript snippet in the markup to establish the client objects, and move the rest to a seperate javascript code-behind file.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>
 
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <!-- Mini style sheet for formatting the validation indicator -->
    <style type="text/css">
        .ValidationMessageClass {
            background-color: red;
            color: white;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            Input a number: 
            <!-- The textbox is validation when the content changes -->
            <asp:TextBox ID="TextBoxWaarde" runat="server" Text=""></asp:TextBox>
 
            <!-- Page level validation is performed on submission -->
            <asp:Button ID="Button1" runat="server" Text="Check input"
                OnClientClick="return Validate();"
                OnClick="Button1_Click" />
            <asp:Label runat="server" ID="LabelPageSubmitted" Text="Not Valid"></asp:Label>
 
        </div>
    </form>
 
 
    <!-- Javascript object id emissions -->
    <script type="text/javascript">
        var TextBoxWaardeHandle = document.getElementById('<%=TextBoxWaarde.ClientID %>');
    </script>
 
    <!-- Page code -->
    <script type="text/javascript" src="Default.js"></script>
</body>
</html>

JS Code behind

// Javascript code-behind
 
TextBoxWaardeHandle.onblur = function () {
    // Configure
    var minLength = 1;
    var maxLength = 6;
    var waardeValue = TextBoxWaardeHandle.value;
 
    // Perform validation
    if (waardeValue.length < minLength
        || waardeValue.length > maxLength
        || isNaN(waardeValue)) {
        // Invalid, color red and insert warning span if not already there
        var next = this.nextSibling;
        if (!next || next.className != 'ValidationMessageClass') {
            var warnSpan = document.createElement("span");
            warnSpan.innerHTML = '*';
            warnSpan.className = 'ValidationMessageClass';
            this.parentNode.insertBefore(warnSpan, this.nextSibling);
        }
    } else {
        // valid, remove formatting and error span
        var nextremove = this.nextSibling;
        if (nextremove && nextremove.className == 'ValidationMessageClass') {
            this.parentNode.removeChild(nextremove);
        }
    }
};
 
// validate during page-submit. If any controls have a warning behind them the page does not validate.
function Validate() {
    var check01 = TextBoxWaardeHandle.value;
    if (isNaN(check01) || check01.length < 1 || check01.length > 6) {
        return false;
    }
    // ... repeat ...
    return true;
}

CS Code behind

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
 
namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
 
        }
 
        protected void Button1_Click(object sender, EventArgs e)
        {
            LabelPageSubmitted.Text = "Valid";
        }
    }
}