Introduction
In almost all the web projects, we require a multiline TextBox control. It was annoying to find that 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 user will not be able to enter characters more than the length specified.
Extending TextBox
To achieve this, I tried extending ASP.Net TextBox WebControl.
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
namespace CustomWebControls
{
public class TextArea: TextBox
{
protected override void OnPreRender(EventArgs e)
{
if (MaxLength > 0 && TextMode == TextBoxMode.MultiLine)
{
Attributes.Add("onkeypress","doKeypress(this);");
Attributes.Add("onbeforepaste","doBeforePaste(this);");
Attributes.Add("onpaste","doPaste(this);");
Attributes.Add("maxLength", this.MaxLength.ToString());
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 javascripts and a property to pass maxLength on 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 Javascript easily. In addition, page will not be bloated and 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
function doKeypress(control){
maxLength = control.attributes["maxLength"].value;
value = control.value;
if(maxLength && value.length > maxLength-1){
event.returnValue = false;
maxLength = parseInt(maxLength);
}
}
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 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 Custom Control
To test the custom control, I created a test website and added 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
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 page as:
<CustomControls:TextArea runat="server" ID="testTextArea" MaxLength="10" TextMode="MultiLine"></CustomControls:TextArea>
Then I added the javascript file in JS folder.
Tested the solution and voila! My first attempt to create an extended custom webcontrol is successful. I will appreciate your comments.
Summary of things I learned
- Extending a web control is a breeze.
- New ClientScript property of page. Related IsClientScriptIncludeRegistered and RegisterClientScriptInclude property.
- Added the tagPrefix in Web.Config instead of specifying it on each page.
Client Browsers Supported
Other Notes
- To get this control to work on other browsers also, we might need some modifications in 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 and RegisterClientScriptInclude.
- 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!