Multiline TextBox with MaxLength Validation
A simple extension of the existing TextBox control to attach JavaScript for maxlength validation.
Introduction
In almost all web projects, we require a multiline TextBox
control. It was annoying to find that the maxLength
property doesn't work on multiline textboxes. There are various solutions suggesting to use validator controls to validate length. I suggest that we should put a validator as well as extend our control so that the user will not be able to enter characters more than the length specified.
Extending the TextBox
To achieve this, I tried extending the ASP.NET TextBox
WebControl.
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
namespace CustomWebControls
{
/// <summary>
/// Extended TextBox control that applies
/// javascript validation to Multiline TextBox
/// </summary>
public class TextArea: TextBox
{
/// <summary>
/// Override PreRender to include custom javascript
/// </summary>
/// <param name="e"></param>
protected override void OnPreRender(EventArgs e)
{
if (MaxLength > 0 && TextMode == TextBoxMode.MultiLine)
{
// Add javascript handlers for paste and keypress
Attributes.Add("onkeypress","doKeypress(this);");
Attributes.Add("onbeforepaste","doBeforePaste(this);");
Attributes.Add("onpaste","doPaste(this);");
// Add attribute for access of maxlength property on client-side
Attributes.Add("maxLength", this.MaxLength.ToString());
// Register client side include - only once per page
if(!Page.ClientScript.IsClientScriptIncludeRegistered("TextArea"))
{
Page.ClientScript.RegisterClientScriptInclude("TextArea",
ResolveClientUrl("~/js/textArea.js"));
}
}
base.OnPreRender(e);
}
}
}
Now our custom control is ready to use. In the above code block, it should be self-explanatory that if I find the TextBox
's TextMode
property to be MultiLine
, I add custom JavaScript and a property to pass the maxLength
on the client side. I take advantage of ClientScript
to attach a JavaScript, only one per page. I chose to include JavaScript as an external file because this allows us to modify the JavaScript easily. In addition, the page will not be bloated and the script will be cached.
I created this control in a Project Library so that I can use this control in any of our projects.
JavaScript File
// Keep user from entering more than maxLength characters
function doKeypress(control){
maxLength = control.attributes["maxLength"].value;
value = control.value;
if(maxLength && value.length > maxLength-1){
event.returnValue = false;
maxLength = parseInt(maxLength);
}
}
// Cancel default behavior
function doBeforePaste(control){
maxLength = control.attributes["maxLength"].value;
if(maxLength)
{
event.returnValue = false;
}
}
// Cancel default behavior and create a new paste routine
function doPaste(control){
maxLength = control.attributes["maxLength"].value;
value = control.value;
if(maxLength){
event.returnValue = false;
maxLength = parseInt(maxLength);
var oTR = control.document.selection.createRange();
var iInsertLength = maxLength - value.length + oTR.text.length;
var sData = window.clipboardData.getData("Text").substr(0,iInsertLength);
oTR.text = sData;
}
}
Using the Custom Control
To test the custom control, I created a test website and added a reference to the project. I wanted to avoid the hassle of adding the Register tag on each page, so I went ahead and added the following statements in the system.web
section of web.config.
<pages>
<controls>
<add tagPrefix="CustomControls"
namespace="CustomWebControls"
assembly="CustomWebControls"></add>
</controls>
</pages>
Now I created a test web page and added the control on the page as:
<CustomControls:TextArea runat="server" ID="testTextArea"
MaxLength="10" TextMode="MultiLine"></CustomControls:TextArea>
Then I added the JavaScript file in the JS folder.
Tested the solution and voila! My first attempt to create an extended custom Web Control is successful. I will appreciate your comments.
Summary of things I learned
- Extending a Web Control is a breeze.
- The new
ClientScript
property ofPage
. And the relatedIsClientScriptIncludeRegistered
andRegisterClientScriptInclude
properties. - Added the tag prefix in Web.Config instead of specifying it on each page.
Client Browsers Supported
- IE 6.0
Other Notes
- To get this control to work on other browsers also, we might need some modifications in the JS file.
- This solution was developed in Visual Studio 2005. To convert it to Visual Studio 2003, we just need to change the calls for
IsClientScriptIncludeRegistered
andRegisterClientScriptInclude
. - It's necessary to add validation controls also for length check. This will allow you to validate the input even if client-side script fails.
Thanks CodeProject for all the help!