84
votes

I'm trying to use asp:

<asp:TextBox ID="txtInput" runat="server" TextMode="MultiLine"></asp:TextBox>

I want a way to specify the maxlength property, but apparently there's no way possible for a multiline textbox. I've been trying to use some JavaScript for the onkeypress event:

onkeypress="return textboxMultilineMaxNumber(this,maxlength)"

function textboxMultilineMaxNumber(txt, maxLen) {
    try {
        if (txt.value.length > (maxLen - 1)) return false;
    } catch (e) { }
    return true;
}

While working fine the problem with this JavaScript function is that after writing characters it doesn't allow you to delete and substitute any of them, that behavior is not desired.

Have you got any idea what could I possibly change in the above code to avoid that or any other ways to get round it?

19
Tried all answers and answer by scottyboiler is definitely the closes to ideal solution. All others have small problems (don't work with copy-paste, MaxLength parameter not working in IE, etc). - nikib3ro
I second @kape123 here. All the others have failings. After all we just want to stop the field from allowing anymore than the limit given and to be able to copy & paste within the limit! - Fandango68
@Fernando68 I've realized I haven't linked the answer - here is link to scottyboiler solution which is closest to idea - everyone else have some failings. - nikib3ro
@kape123 - way ahead of you mate! :) - Fandango68

19 Answers

75
votes

Use a regular expression validator instead. This will work on the client side using JavaScript, but also when JavaScript is disabled (as the length check will be performed on the server as well).

The following example checks that the entered value is between 0 and 100 characters long:

<asp:RegularExpressionValidator runat="server" ID="valInput"
    ControlToValidate="txtInput"
    ValidationExpression="^[\s\S]{0,100}$"
    ErrorMessage="Please enter a maximum of 100 characters"
    Display="Dynamic">*</asp:RegularExpressionValidator>

There are of course more complex regexs you can use to better suit your purposes.

44
votes

try this javascript:

function checkTextAreaMaxLength(textBox,e, length)
{

        var mLen = textBox["MaxLength"];
        if(null==mLen)
            mLen=length;

        var maxLength = parseInt(mLen);
        if(!checkSpecialKeys(e))
        {
         if(textBox.value.length > maxLength-1)
         {
            if(window.event)//IE
              e.returnValue = false;
            else//Firefox
                e.preventDefault();
         }
    }   
}
function checkSpecialKeys(e)
{
    if(e.keyCode !=8 && e.keyCode!=46 && e.keyCode!=37 && e.keyCode!=38 && e.keyCode!=39 && e.keyCode!=40)
        return false;
    else
        return true;
}

On the control invoke it like this:

<asp:TextBox Rows="5" Columns="80" ID="txtCommentsForSearch" MaxLength='1999' onkeyDown="checkTextAreaMaxLength(this,event,'1999');"  TextMode="multiLine" runat="server"> </asp:TextBox>

You could also just use the checkSpecialKeys function to validate the input on your javascript implementation.

30
votes

keep it simple. Most modern browsers support a maxlength attribute on a text area (IE included), so simply add that attribute in code-behind. No JS, no Jquery, no inheritance, custom code, no fuss, no muss.

VB.Net:

fld_description.attributes("maxlength") = 255

C#

fld_description.Attributes["maxlength"] = 255
22
votes

Roll your own:

function Count(text) 
{
    //asp.net textarea maxlength doesnt work; do it by hand
    var maxlength = 2000; //set your value here (or add a parm and pass it in)
    var object = document.getElementById(text.id)  //get your object
    if (object.value.length > maxlength) 
    {
        object.focus(); //set focus to prevent jumping
        object.value = text.value.substring(0, maxlength); //truncate the value
        object.scrollTop = object.scrollHeight; //scroll to the end to prevent jumping
        return false;
    }
    return true;
}

Call like this:

<asp:TextBox ID="foo" runat="server" Rows="3" TextMode="MultiLine" onKeyUp="javascript:Count(this);" onChange="javascript:Count(this);" ></asp:TextBox>
6
votes

Things have changed in HTML5:

ASPX:

<asp:TextBox ID="txtBox" runat="server" maxlength="2000" TextMode="MultiLine"></asp:TextBox>

C#:

if (!IsPostBack)
{
    txtBox.Attributes.Add("maxlength", txtBox.MaxLength.ToString());
}

Rendered HTML:

<textarea name="ctl00$DemoContentPlaceHolder$txtBox" id="txtBox" maxlength="2000"></textarea>

The metadata for Attributes:

Summary: Gets the collection of arbitrary attributes (for rendering only) that do not correspond to properties on the control.

Returns: A System.Web.UI.AttributeCollection of name and value pairs.

4
votes

Another way of fixing this for those browsers (Firefox, Chrome, Safari) that support maxlength on textareas (HTML5) without javascript is to derive a subclass of the System.Web.UI.WebControls.TextBox class and override the Render method. Then in the overridden method add the maxlength attribute before rendering as normal.

protected override void Render(HtmlTextWriter writer)
{
    if (this.TextMode == TextBoxMode.MultiLine
        && this.MaxLength > 0)
    {
        writer.AddAttribute(HtmlTextWriterAttribute.Maxlength, this.MaxLength.ToString());
    }

    base.Render(writer);
}
4
votes

use custom attribute maxsize="100"

<asp:TextBox ID="txtAddress" runat="server"  maxsize="100"
      Columns="17" Rows="4" TextMode="MultiLine"></asp:TextBox>
   <script>
       $("textarea[maxsize]").each(function () {
         $(this).attr('maxlength', $(this).attr('maxsize'));
         $(this).removeAttr('maxsize'); 
       });
   </script>

this will render like this

<textarea name="ctl00$BodyContentPlac
eHolder$txtAddress" rows="4" cols="17" id="txtAddress" maxlength="100"></textarea>
3
votes
$('#txtInput').attr('maxLength', 100);
3
votes

Use HTML textarea with runat="server" to access it in server side. This solution has less pain than using javascript or regex.

<textarea runat="server" id="txt1" maxlength="100" />

Note: To access Text Property in server side, you should use txt1.Value instead of txt1.Text

2
votes

I tried different approaches but every one had some weak points (i.e. with cut and paste or browser compatibility). This is the solution I'm using right now:

function multilineTextBoxKeyUp(textBox, e, maxLength) {
    if (!checkSpecialKeys(e)) {
        var length = parseInt(maxLength);
        if (textBox.value.length > length) {
            textBox.value = textBox.value.substring(0, maxLength);
        }
    }
}

function multilineTextBoxKeyDown(textBox, e, maxLength) {
    var selectedText = document.selection.createRange().text;
    if (!checkSpecialKeys(e) && !e.ctrlKey && selectedText.length == 0) {
        var length = parseInt(maxLength);
        if (textBox.value.length > length - 1) {
            if (e.preventDefault) {
                e.preventDefault();
            }
            else {
                e.returnValue = false;
            }
        }
    }
}

function checkSpecialKeys(e) {
    if (e.keyCode != 8 && e.keyCode != 9 && e.keyCode != 33 && e.keyCode != 34 && e.keyCode != 35 && e.keyCode != 36 && e.keyCode != 37 && e.keyCode != 38 && e.keyCode != 39 && e.keyCode != 40) {
        return false;
    } else {
        return true;
    }
}

In this case, I'm calling multilineTextBoxKeyUp on key up and multilineTextBoxKeyDown on key down:

myTextBox.Attributes.Add("onkeyDown", "multilineTextBoxKeyDown(this, event, '" + maxLength + "');");
myTextBox.Attributes.Add("onkeyUp", "multilineTextBoxKeyUp(this, event, '" + maxLength + "');");
2
votes

Here's how we did it (keeps all code in one place):

<asp:TextBox ID="TextBox1" runat="server" TextMode="MultiLine"/>
<% TextBox1.Attributes["maxlength"] = "1000"; %>

Just in case someone still using webforms in 2018..

1
votes

Have a look at this. The only way to solve it is by javascript as you tried.

EDIT: Try changing the event to keypressup.

0
votes

The following example in JavaScript/Jquery will do that-

<telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">
<script type="text/javascript">
     function count(text, event) {

         var keyCode = event.keyCode;

         //THIS IS FOR CONTROL KEY
         var ctrlDown = event.ctrlKey;

         var maxlength = $("#<%=txtMEDaiSSOWebAddress1.ClientID%>").val().length;

         if (maxlength < 200) {
             event.returnValue = true;
         }
         else {

             if ((keyCode == 8) || (keyCode == 9) || (keyCode == 46) || (keyCode == 33) || (keyCode == 27) || (keyCode == 145) || (keyCode == 19) || (keyCode == 34) || (keyCode == 37) || (keyCode == 39) || (keyCode == 16) || (keyCode == 18) ||
                 (keyCode == 38) || (keyCode == 40) || (keyCode == 35) || (keyCode == 36) || (ctrlDown && keyCode == 88) || (ctrlDown && keyCode == 65) || (ctrlDown && keyCode == 67) || (ctrlDown && keyCode == 86)) 

                  {
                 event.returnValue = true;
                  }

             else {

                 event.returnValue = false;
             }
         }

     }

     function substr(text)
      {
          var txtWebAdd = $("#<%=txtMEDaiSSOWebAddress1.ClientID%>").val();
          var substrWebAdd;
          if (txtWebAdd.length > 200) 
          {                 
              substrWebAdd = txtWebAdd.substring(0, 200);                                  
              $("#<%=txtMEDaiSSOWebAddress1.ClientID%>").val('');
              $("#<%=txtMEDaiSSOWebAddress1.ClientID%>").val(substrWebAdd); 

          }
     }                  

0
votes

This snippet worked in my case. I was searching for the solution and thought to write this so that it may help any future reader.

ASP

<asp:TextBox ID="tbName" runat="server" MaxLength="250" TextMode="MultiLine" onkeyUp="return CheckMaxCount(this,event,250);"></asp:TextBox>

Java Script

function CheckMaxCount(txtBox,e, maxLength)
{
    if(txtBox)
    {  
        if(txtBox.value.length > maxLength)
        {
            txtBox.value = txtBox.value.substring(0, maxLength);
        }
        if(!checkSpecialKeys(e))
        {
            return ( txtBox.value.length <= maxLength)
        }
    }
}

function checkSpecialKeys(e)
{
    if(e.keyCode !=8 && e.keyCode!=46 && e.keyCode!=37 && e.keyCode!=38 && e.keyCode!=39 && e.keyCode!=40)
        return false;
    else
        return true;
}

@Raúl Roa Answer did worked for me in case of copy/paste. while this does.

0
votes
$("textarea[maxlength]").on("keydown paste", function (evt) {
            if ($(this).val().length > $(this).prop("maxlength")) {
                if (evt.type == "paste") {
                    $(this).val($(this).val().substr(0, $(this).prop("maxlength")));
                } else {
                    if ([8, 37, 38, 39, 40, 46].indexOf(evt.keyCode) == -1) {
                        evt.returnValue = false;
                        evt.preventDefault();
                    }
                }
            }
        });
0
votes

you can specify the max length for the multiline textbox in pageLoad Javascript Event

function pageLoad(){
                     $("[id$='txtInput']").attr("maxlength","10");
                    }

I have set the max length property of txtInput multiline textbox to 10 characters in pageLoad() Javascript function

0
votes

This is the same as @KeithK's answer, but with a few more details. First, create a new control based on TextBox.

using System.Web.UI;
using System.Web.UI.WebControls;

namespace MyProject
{
    public class LimitedMultiLineTextBox : System.Web.UI.WebControls.TextBox
    {
        protected override void Render(HtmlTextWriter writer)
        {
            this.TextMode = TextBoxMode.MultiLine;

            if (this.MaxLength > 0)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Maxlength, this.MaxLength.ToString());
            }

            base.Render(writer);
        }
    }
}  

Note that the code above always sets the textmode to multiline.

In order to use this, you need to register it on the aspx page. This is required because you'll need to reference it using the TagPrefix, otherwise compilation will complain about custom generic controls.

<%@ Register Assembly="MyProject" Namespace="MyProject" TagPrefix="mp" %>

<mp:LimitedMultiLineTextBox runat="server" Rows="3" ...
0
votes

Nearly all modern browsers now support the use of the maxlength attribute for textarea elements.(https://caniuse.com/#feat=maxlength)

To include the maxlength attribute on a multiline TextBox, you can simply modify the Attributes collection in the code behind like so:

txtTextBox.Attributes["maxlength"] = "100";

If you don't want to have to use the code behind to specify that, you can just create a custom control that derives from TextBox:

public class Textarea : TextBox
{
    public override TextBoxMode TextMode
    {
        get { return TextBoxMode.MultiLine; }
        set { }
    }

    protected override void OnPreRender(EventArgs e)
    {
        if (TextMode == TextBoxMode.MultiLine && MaxLength != 0)
        {
            Attributes["maxlength"] = MaxLength.ToString();
        }

        base.OnPreRender(e);
    }
}
0
votes

MaxLength is now supported as of .NET 4.7.2, so as long as you upgrade your project to .NET 4.7.2 or above, it will work automatically.

You can see this in the release notes here - specifically:

Enable ASP.NET developers to specify MaxLength attribute for Multiline asp:TextBox. [449020, System.Web.dll, Bug]