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

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.

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.

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.

License

Share

About the Author

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.

Hi,
This is a very nice article. This will working fine when I use this custom control in normal page or ascx. But when I used many nested ascx within that I registered this custom control within a update panel, then it will give me the jScript Object expected error!

I have resolve that issue when I modify my custom "MyTextArea" class as given below.
ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "MyTextArea", _script, false);
where _script is used as inline script.

I have also tried to locate my java script function from .js file but give error like "could not load respective javascript", eventhough the path of the .js file is proper.
ScriptManager.RegisterClientScriptInclude(this,this.GetType(), "MyTextArea", ResolveUrl("~/js/textArea.js");
So, that I have to skip above line.

Again when I use "<asp:customvalidator ....=""> for check box, then it will not render the ClientValidationFunction="CheckIsAgree" and give jScript object expected error.

I needed to set the MaxLength property from Codebehind. Made possible with this change of OnPreRender method, which uses the programatically set value if existing, otherwise the MaxLength property from aspx:

Thanks for the, good work, your solution works well, i have tested it in IE and Firefox. I really like how your solution takes into account pasting data into multi-lined txt boxes. Keep up the good work.

As for Client side validation Vs server side validation. There are good pros and cons for each method, but the best would be a combination of both of them. However due my laziness the java script solution is my option, cause it is easier to apply

your article is quite usefull since M$ did not make the MaxLength functional for multiline textboxes.

i wanted to use your code and strated testing. however i discovered a bug. first i limited tehe 105 value to 10 so i could verify it easier. i noticed that i could actually insert one more character than the limit (106) if i used the tab to navigate. to test it even further i pasted a textbox and a button. when the user clicks the button the text would be copied from the your control to the textbox. as i tried i noticed that also the extra character was copied.

filxed the problem by using the "onblur" event instead of "onmousemove", which fires when the control loses focus so the char gets truncated.

True enough. But client-side validation should never be trusted (since it can be bypassed easily) and if used, should always be validated again on the server side. It may not be a bad idea to add the RegEx control to your Textarea control so that it validates on both ends.

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.

Nice solution.
However while I've been playing around with it, I've noticed that onkeypress event does not work as you have expected. It is fired just after the key is released, but before the symbol is actually added to the textarea, so we have one unwanted extra symbol in the textarea.
I suggest using onkeyup event instead of keypress.

You have used 'ResolveClientUrl' method to access textarea.js. I have found elsewhere that using ResolveClientUrl in case of url rewriting may cause problem. It does not return the correct relative path. Will it be a good idea to use ResolveUrl instead? What do you think?

What I mean is - if user is accessing a page (with your control in it) 'testapplication\productList.aspx?category=beverages'. It will work great. But suppose user is accessing friendly url 'testapplication\products\beverages.aspx', which internally maps to above url - 'testapplication\productList.aspx?category=beverages'. Then we have a problem. Because ResolveClientUrl will return relative path as \products\textarea.js. which will be wrong.

ResolveClientUrl() method is similar to the standard ResolveUrl() method, except for one important fact: it creates relative paths rather than absolute paths. So, ResolveUrl() gives us something like testapplication\productList.aspx?category=beverages, but what ResolveClientUrl() gives us is testapplication\products\beverages.aspx. So you are right, when using Url Rewrite, we must use ResolveUrl() instead of ResolveClientUrl().

I have implemented your code and it does what you say, however, it does not update the designer file with a web control e.g. TextBox or TextArea and there is no way to get the data out of the control from codebehind. Is there something else I must do?

In the default.aspx code I have "<csc:textarea id="Quest1" runat="server" columns="60" rows="5" maxlength="400">" in the default.aspx.designer.vb there should be something like "Protected WithEvents Quest1 As Global.System.Web.UI.WebControls.TextBox" or .TextArea ?? But there's not, so in the codebehind I can't do Quest1.text = "abc"