88

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?

Barry Michael Doyle
  • 9,333
  • 30
  • 83
  • 143
Blerta
  • 2,170
  • 5
  • 23
  • 34
  • 2
    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 Apr 23 '12 at 14:16
  • 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 Sep 26 '16 at 02:47
  • 1
    @Fernando68 I've realized I haven't linked the answer - here is [link to scottyboiler solution which is closest to idea](http://stackoverflow.com/a/5501813/237858) - everyone else have some failings. – nikib3ro Sep 26 '16 at 03:46
  • @kape123 - way ahead of you mate! :) – Fandango68 Sep 26 '16 at 04:30

20 Answers20

77

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.

Alex Angas
  • 59,219
  • 41
  • 137
  • 210
  • 1
    The only issue I have with this answer is that when the user edits the text to bring it within the limit, the message doesn't disappear, which can be quite confusing for the user. – Liam Spencer Jul 02 '13 at 10:19
  • If you're going for this solution I recommend also triggering the validation on key press, which makes the message appear and disappear as the user types: http://fczaja.blogspot.co.uk/2009/07/aspnet-how-to-trigger-client-side.html – Fiona - myaccessible.website Aug 21 '14 at 15:43
  • Is there any particular reason why you are using `[\s\S]` instead of the simpler `.`? – Heinzi Mar 21 '17 at 10:21
  • 1
    Just discovered why (the hard way): `.` does not match newlines, [`[\s\S]` does](http://stackoverflow.com/a/7095240/87698). – Heinzi Mar 21 '17 at 12:46
  • If you have JavaScript in your page, watch out you may get this error: https://stackoverflow.com/questions/16660900/webforms-unobtrusivevalidationmode-requires-a-scriptresourcemapping-for-jquery – Just a HK developer Nov 27 '17 at 03:05
45

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.

Raúl Roa
  • 12,061
  • 13
  • 49
  • 64
  • 1
    This is great except that the limiting fails when the user enters carriage returns. Carriage returns don't add anything to javascript's value.length count but do contribute to the overall size of the string ('\n' is two characters). If your server is limiting the string size, you'll still get truncation whenever someone uses carriage returns. – srmark May 07 '10 at 20:50
  • My last comment only seems to apply to certain browsers. IE returns a proper length value (including carriage return characters). Webkit does not. – srmark May 07 '10 at 20:54
  • 2
    This code doesn't work server side, which makes it a pretty poor solution. The regex validator from Alex Angas is a much better solution and really should be the accepted answer... – George May 07 '13 at 03:34
32

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
David R Tribble
  • 11,918
  • 5
  • 42
  • 52
Mike A.
  • 1,438
  • 13
  • 11
22

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>
scottyboiler
  • 221
  • 2
  • 2
  • Why reinvent the wheel? How is this better than using the built in mechanism? (Alex Angas's answer) – NickG Jun 11 '14 at 11:27
  • 3
    @NickG Because 'this wheel' spins better than the wooden versions above! ;) – Fandango68 Sep 26 '16 at 02:46
  • I prefer this JavaScript solution. The above `RegularExpressionValidator` may post a problem and require changing web.config. (Re: https://stackoverflow.com/questions/16660900/webforms-unobtrusivevalidationmode-requires-a-scriptresourcemapping-for-jquery) – Just a HK developer Nov 27 '17 at 03:07
6

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.

Community
  • 1
  • 1
Kristopher
  • 819
  • 14
  • 31
  • That's a good answer but you should remove the !IsPostBack condition because the TextBox will not have the maxlength property if somebody removes it in the DOM in Firebug for example. – krlzlx Feb 11 '16 at 16:34
  • Good point, though in my limited, internal use application this was sufficient. – Kristopher Feb 12 '16 at 15:35
5

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>
ebram khalil
  • 8,252
  • 7
  • 42
  • 60
Ashwini Jindal
  • 811
  • 8
  • 15
  • Doesn't work in IE 9 or previous so would need to be combined with a validator as in Alex Angas's answer. – NickG Jun 11 '14 at 11:40
4

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);
}
Keith K
  • 2,893
  • 4
  • 33
  • 43
  • 1
    You could also turn this into a ControlAdapter this way you would not need to replace every TextBox with the inherited textbox. – Peter Apr 02 '14 at 09:39
4
$('#txtInput').attr('maxLength', 100);
Michaël
  • 6,676
  • 3
  • 36
  • 55
  • It has down votes as it doesn't work. It has no effect at all and you can still type in more than 100 chars. That makes the answer useless - hence all the down votes. – NickG Jun 11 '14 at 11:35
  • 2
    +1 This may not have worked in HTML 4.01 but it works in HTML 5 with the introduction of the ['maxlength' attribute](http://www.w3schools.com/tags/att_textarea_maxlength.asp). – Charles Caldwell Mar 20 '15 at 16:15
3

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

Ali Gonabadi
  • 944
  • 1
  • 10
  • 28
2

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 + "');");
Sue Maurizio
  • 662
  • 7
  • 17
2

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..

Alex from Jitbit
  • 53,710
  • 19
  • 160
  • 149
1

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

EDIT: Try changing the event to keypressup.

Christian13467
  • 5,324
  • 31
  • 34
0

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.

Afnan Ahmad
  • 2,492
  • 4
  • 24
  • 44
0
$("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();
                    }
                }
            }
        });
Alex
  • 11
  • 1
0

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

Sumit Jambhale
  • 565
  • 8
  • 13
0

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" ...
BurnsBA
  • 4,347
  • 27
  • 39
0

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);
    }
}
Daniel Arant
  • 483
  • 1
  • 4
  • 16
0

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]

pattermeister
  • 3,132
  • 2
  • 25
  • 27
0

This is absolutely working: use textarea and value

<div class="form-group row">
<label class="col-md-4 col-form-label">Description</label>
<textarea id="txtDescription" class="form-control" style="height: 40px ; width :250px;  " runat="server" maxlength="500" tabindex="32"  ></textarea>

</div>
 </div>

In code: While saving:-

BusinessLayer.Description = txtDescription.Value.ToString();

While taking back the value :-

txtDescription.Value = BusinessLayer.Description.ToString();

Important points: Don't forget to use runat="server" Don't forget to use value while converting

0

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); 

          }
     }                  

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291