Click here to Skip to main content
15,868,141 members
Articles / Web Development / HTML

Extending the ASP.NET multiline TextBox control to limit the number of characters entered

Rate me:
Please Sign up or sign in to vote.
4.74/5 (45 votes)
16 Nov 2007CPOL2 min read 189.2K   898   79   38
Developers use multiline TextBox controls in almost all web projects. Since the MaxLength property of a TextBox control does not work when the TextMode property is set to Multiline, we usually use Validator controls to validate the length.

Introduction

Developers use multiline TextBox controls in almost all web projects. Since the MaxLength property of a TextBox control does not work when the TextMode property is set to Multiline, we usually use Validator controls to validate the length. In this hands-on article, we are going to extend the TextBox control using JavaScript in order to limit the number of characters entered by the user to the length specified.

Using the code

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Globalization;
using System.Threading;

namespace CustomServerControls
{
    [DefaultProperty("Text")]
    [ToolboxData("<{0}:TextArea runat="server"></{0}:TextArea>")]
    public class TextArea : TextBox
    {
        public override TextBoxMode TextMode
        {
            get
            {
                return TextBoxMode.MultiLine;
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            if (MaxLength > 0)
            {
                if (!Page.ClientScript.IsClientScriptIncludeRegistered("TextArea"))
                {
                    Page.ClientScript.RegisterClientScriptInclude("TextArea", 
                                      ResolveUrl("~/textarea.js"));
                }
                this.Attributes.Add("onkeyup", "LimitInput(this)");
                this.Attributes.Add("onbeforepaste", "doBeforePaste(this)");
                this.Attributes.Add("onpaste", "doPaste(this)");
                this.Attributes.Add("onmousemove", "LimitInput(this)");
                this.Attributes.Add("maxLength", this.MaxLength.ToString());
            }
                base.OnPreRender(e);
        }
    }
}

The code above creates a new TextArea custom server control by extending ASP.NET's TextBox control. By overriding the OnPreRender function, we include attributes to the HTML of the control. We add custom JavaScript and a property to pass MaxLength on the client side.

To show the working TextArea control, I prepared the following HTML:

ASP.NET
<%@ Page Language="C#" AutoEventWireup="true" 
         CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register TagPrefix="csc" Namespace="CustomServerControls" %> 

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>TextArea Custom Server Control with MaxLength property</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <csc:TextArea id="TextArea" runat="server" 
            MaxLength="105" Rows="10" 
            Width="300px"></csc:TextArea>
    </div>
    </form>
</body>
</html>

In the above HTML, I register the custom control with the web page by using the following line:

ASP.NET
<%@ Register TagPrefix="csc" Namespace="CustomServerControls" %>

If you don't want to add the above registration line on each page that you use the TextArea control, you may add the following statement in the system.web section of the web.config file:

ASP.NET
<pages>
   <controls>
    <add tagPrefix="csc" namespace="CustomServerControls"></add>
   </controls>
</pages>  

I added the control on the page as:

ASP.NET
<csc:TextArea id="TextArea" runat="server" MaxLength="105" Rows="10" Width="300px">
</csc:TextArea>

Let's compare the rendered output of a multiline textbox control and our text area control:

The rendered output of a standard multiple line ASP.NET TextBox is:

ASP.NET
<textarea name="TextArea" id="TextArea" rows="10" cols="20" style="width:300px;" ></textarea>

The rendered output of our TextArea custom server control is:

ASP.NET
<textarea name="TextArea" rows="10" cols="20" id="TextArea"
  onkeypress="LimitInput(this)" onbeforepaste="doBeforePaste(this)"
  onpaste="doPaste(this)" onmousemove="LimitInput(this)" maxLength="105"
  style="width:300px;"></textarea>

The JavaScript event handlers doBeforePaste and doPaste are only implemented in Internet Explorer. These event handlers are used to check the length of characters that are pasted by using a mouse in Internet Explorer. Unfortunately, the doBeforePaste and doPaste event handlers are not defined in other browsers and we cannot catch a mouse paste in browsers other than IE. Therefore, I added an onmousemove event handler in order to check the length of characters that are pasted by using a mouse after a mouse move. The onkeypress event handler handles the standard character input.

JavaScript
function doBeforePaste(control)
{
   maxLength = control.attributes["maxLength"].value;
   if(maxLength)
   {
       event.returnValue = false;
   }
}
function doPaste(control)
{
   maxLength = control.attributes["maxLength"].value;
   value = control.value;
   if(maxLength){
        event.returnValue = false;
        maxLength = parseInt(maxLength);
        var o = control.document.selection.createRange();
        var iInsertLength = maxLength - value.length + o.text.length;
        var sData = window.clipboardData.getData("Text").substr(0,iInsertLength);
        o.text = sData;
    }
}
function LimitInput(control)
{
    if(control.value.length >

Updates

  • Nov 10, 2007 - The onkeypress JavaScript event handler is changed with the onkeyup JavaScript event handler. (You may check the reason at KeyPress, KeyDown, KeyUp - The Difference Between JavaScript Key Events)
  • Nov 9, 2007 - Instead of using the 'ResolveClientUrl' method to access textarea.js which may cause a problem in the case of URL rewriting, the 'ResolveUrl' method is used.
  • The code is tested on Firefox, IE 6.0, and IE 7.0.

      Try the online demo of the extended ASP.NET multiline TextBox control that limits the number of characters entered. You may find more articles about ASP.NET, JavaScript, and C# on my blog.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
Unknown
Blogging Developer is an accomplished project manager with more than 8 years of experience in web development, web strategy, e-commerce, and search engine optimization, specialized in object-oriented, multi-tiered design and analysis with hands-on experience in the complete life cycle of the implementation process including requirements analysis, prototyping, proof of concept, database design, interface implementation, testing, and maintenance.

Solid project management skills, expertise in leading and mentoring individuals to maximize levels of productivity, while forming cohesive team environments.

Comments and Discussions

 
BugMy vote of 5 Pin
zhangtai19-Sep-12 18:40
zhangtai19-Sep-12 18:40 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey17-Feb-12 20:55
professionalManoj Kumar Choubey17-Feb-12 20:55 
GeneralWell Done Pin
norchr14-Apr-10 11:56
norchr14-Apr-10 11:56 
GeneralObject expected error while using this customer control into update panel [modified] Pin
Rakesh N Bhavsar22-Feb-10 0:34
Rakesh N Bhavsar22-Feb-10 0:34 
GeneralNice Control Pin
thatraja19-Jan-10 3:14
professionalthatraja19-Jan-10 3:14 
QuestionDatabinding issues? Pin
mminnich28-Dec-09 5:27
mminnich28-Dec-09 5:27 
GeneralSet MaxLength from CodeBehind Pin
Ken Robert Andersen7-May-09 23:34
Ken Robert Andersen7-May-09 23:34 
GeneralThanks Pin
Grettir Strong6-Feb-09 7:34
Grettir Strong6-Feb-09 7:34 
GeneralNice Solution Pin
Alpha_Jujster2-Feb-09 3:02
Alpha_Jujster2-Feb-09 3:02 
Generalvalidation not working quite right Pin
HalfHuman7-Jan-08 1:13
HalfHuman7-Jan-08 1:13 
GeneralHi Pin
Srinath Gopinath24-Nov-07 8:01
Srinath Gopinath24-Nov-07 8:01 
QuestionWhy not just use a Regular Expression? Pin
orengold21-Nov-07 7:13
orengold21-Nov-07 7:13 
AnswerRe: Why not just use a Regular Expression? Pin
blogging developer21-Nov-07 10:03
blogging developer21-Nov-07 10:03 
GeneralRe: Why not just use a Regular Expression? Pin
orengold21-Nov-07 10:52
orengold21-Nov-07 10:52 
GeneralFirefox counts characters different from IE (AFAIK) [modified] Pin
Mark Cranness19-Nov-07 14:37
Mark Cranness19-Nov-07 14:37 
Firefox counts characters in lines with linebreaks differently than IE (AFAIK).
When I did similar to this article, Firefox was calculating a different count and confusing things. Firefox only stores and only counts the CR character, and does not store or count any LF character.

To see the problem, visit your test website
... and enter these characters:
0123456789
0123456789
0123456789
0123456789
0123456789
0123456789
0123456789
0123456789
0123456789
012346

Including the CR LF at the end of each line, this is 114 characters once it gets back to the ASP.NET code, which exceeds the 105 limit that your test website is trying to enforce.

My code went like so:

<br />
<asp:TextBox ID="textBoxNotes" runat="server" <br />
TextMode="MultiLine" Rows="5"></asp:TextBox><br />
<br />
<asp:CustomValidator ID="customValidatorNotesMaxLength" runat="server" ControlToValidate="textBoxNotes"<br />
ErrorMessage="Too many characters, please abbreviate." OnServerValidate="customValidatorNotesMaxLength_ServerValidate"></asp:CustomValidator>


<br />
/// <summary><br />
/// JavaScript validation for textBoxNotes.<br />
/// (TextBox.MaxLength does not work for multiline (HTML textarea) textboxes.)<br />
/// </summary><br />
/// <remarks>Firefox has only a single CR char for line ends, but .NET converts <br />
/// these to CR LF and counts them as two chars, so do our own count.</remarks><br />
private const string customValidatorNotesMaxLength_ClientValidate = @"<br />
function customValidatorNotesMaxLength_ClientValidate(oSrc, args) {{<br />
    var length = 0;<br />
    for (i = 0; i < args.Value.length; i++) {{<br />
        var c = args.Value[i];<br />
        if (c == '\n') length += 2;<br />
        else if (c != '\r') length++;<br />
    }}<br />
    args.IsValid = length <= {0};<br />
}}" + "\r\n";<br />
<br />
/// <summary><br />
/// Call the ASP.NET validator on each key-press, rather than on field-exit.<br />
/// </summary><br />
private const string textBox_LimitText = @"<br />
function textBox_LimitText(textBox) {<br />
    ValidatorValidate(textBox.Validators[0], null, null);<br />
}" + "\r\n";<br />
...<br />
// Hook up JavaScript to limit the number of characters in a multiline textarea<br />
// (TextBox.MaxLength does not work for multiline (HTML textarea) textboxes)<br />
int notesMaxLength = this.DataSet.Table.Column.MaxLength;<br />
this.textBoxNotes.Attributes.Add("onKeyDown", "javascript:textBox_LimitText(this)");<br />
this.textBoxNotes.Attributes.Add("onKeyUp", "javascript:textBox_LimitText(this)");<br />
this.ClientScript.RegisterClientScriptBlock(<br />
    this.GetType(), "textBox_LimitText", textBox_LimitText, true);<br />
// Client-side validation for max length<br />
this.customValidatorNotesMaxLength.ClientValidationFunction<br />
    = "customValidatorNotesMaxLength_ClientValidate";<br />
this.ClientScript.RegisterClientScriptBlock(<br />
    this.GetType(), "customValidatorNotesMaxLength_ClientValidate", <br />
    String.Format(customValidatorNotesMaxLength_ClientValidate, notesMaxLength),<br />
    true);<br />
...<br />
    /// <summary><br />
    /// TextBox.MaxLength does not work for multi-line (HTML textarea) textboxes...<br />
    /// </summary><br />
    protected void customValidatorNotesMaxLength_ServerValidate(object source, ServerValidateEventArgs e) {<br />
    e.IsValid = this.textBoxNotes.Text.Length <= this.DataSet.Table.Column.MaxLength;<br />
    }

Generalonkeypress Pin
Paulius9-Nov-07 2:10
Paulius9-Nov-07 2:10 
GeneralRe: onkeypress Pin
blogging developer9-Nov-07 22:53
blogging developer9-Nov-07 22:53 
QuestionResolveClientUrl problem? Pin
tvj088-Nov-07 6:14
tvj088-Nov-07 6:14 
AnswerRe: ResolveClientUrl problem? Pin
blogging developer8-Nov-07 6:23
blogging developer8-Nov-07 6:23 
GeneralGood Pin
rajantawate1(http//www.tawateventures.com31-Oct-07 11:10
rajantawate1(http//www.tawateventures.com31-Oct-07 11:10 
Generaldesigner.vb Pin
aurand20-Sep-07 11:35
aurand20-Sep-07 11:35 
GeneralRe: designer.vb Pin
blogging developer20-Sep-07 21:42
blogging developer20-Sep-07 21:42 
GeneralRe: designer.vb Pin
aurand21-Sep-07 2:19
aurand21-Sep-07 2:19 
GeneralRe: designer.vb Pin
blogging developer21-Sep-07 2:26
blogging developer21-Sep-07 2:26 
GeneralRe: designer.vb Pin
aurand21-Sep-07 2:27
aurand21-Sep-07 2:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.