为多行文本框指定最大长度

89

我正在尝试使用ASP:

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

我希望能够指定maxlength属性,但显然对于多行文本框来说没有可能。我一直在尝试使用一些JavaScript来处理onkeypress事件:

onkeypress="return textboxMultilineMaxNumber(this,maxlength)"

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

这个JavaScript函数本来运行正常,但是问题在于在写入字符后,它不允许你删除和替换任何字符,这种行为并不理想。

你有什么想法可以在上述代码中进行更改以避免这种情况,或者其他解决方法吗?


2
尝试了所有的答案,scottyboiler的回答绝对是最接近理想解决方案的。其他的答案都存在一些小问题(无法复制粘贴、在IE中MaxLength参数不起作用等)。 - nikib3ro
我在这里支持 @kape123 的观点。其他方法都有缺陷。毕竟,我们只是想阻止该字段允许超过给定限制,并能够在限制范围内复制和粘贴! - Fandango68
1
@Fernando68 我意识到我没有链接答案 - 这里是 link to scottyboiler solution which is closest to idea - 其他人都有一些缺陷。 - nikib3ro
@kape123 - 伙计,你落后了! :) - Fandango68
20个回答

77

使用正则表达式验证器代替。这将在客户端使用JavaScript工作,但即使JavaScript被禁用(因为长度检查也将在服务器上执行),它也能正常运行。

以下示例检查输入值的长度是否在0到100个字符之间:

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

当然,你可以使用更复杂的正则表达式来更好地满足你的需求。


1
我对这个答案唯一的问题是,当用户编辑文本以使其符合限制时,消息不会消失,这可能会让用户感到困惑。 - Liam Spencer
如果您选择此解决方案,我建议在按键时触发验证,这将使消息随着用户的输入出现和消失:http://fczaja.blogspot.co.uk/2009/07/aspnet-how-to-trigger-client-side.html - Fiona - myaccessible.website
你使用 [\s\S] 而不是更简单的 . 有特别的原因吗? - Heinzi
1
刚刚通过“试错法”发现了一个问题:.不能匹配换行符,而[\s\S]可以。详情请见:https://dev59.com/GVrUa4cB1Zd3GeqPjFwM#7095240。 - Heinzi
如果您的页面中有JavaScript,请注意可能会出现此错误:https://dev59.com/MGQn5IYBdhLWcg3wpoqp - Just a HK developer

45

试试这个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;
}

在控件上这样调用:

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

你也可以在JavaScript实现中使用checkSpecialKeys函数来验证输入。


1
这很好,但当用户输入回车符时,限制会失败。回车符不会增加JavaScript的value.length计数,但会对字符串的总大小产生贡献('\n'是两个字符)。如果您的服务器限制了字符串大小,每当有人使用回车符时仍然会发生截断。 - srmark
我的最后一条评论似乎只适用于某些浏览器。IE返回正确的长度值(包括回车符),而Webkit则不会。 - srmark
2
这段代码在服务器端无法运行,因此它是一个相当糟糕的解决方案。Alex Angas的正则表达式验证器是一个更好的解决方案,真的应该成为被接受的答案... - George

32

保持简单。大多数现代浏览器都支持在文本区域上使用maxlength属性(包括IE),因此只需在代码后端添加该属性即可。无需JS、Jquery、继承、自定义代码,不费力,不麻烦。

VB.Net:

fld_description.attributes("maxlength") = 255

C#

fld_description.Attributes["maxlength"] = 255

1
fld_description.attributes["maxlength"] = 255 gives an error for attributes - Barry Michael Doyle
1
@BarryDoyle Attributes是WebControl的公共属性。即帕斯卡命名法fld_description.Attributes["maxlength"] - Chronozoa
2
这是正确的解决方案 - 因为您正在解决 Web 控件中的错误(限制?)而不是浏览器的限制。我可能会做出的唯一修改是,我认为属性是字符串,因此应该是“255”,而不是 255。 - Brian Cryer
这就是我一直在寻找的。谢谢! - Steve
2
这段代码适用于名为“Comments”的多行文本框: Comments.Attributes.Add("maxlength", "1000");(在Page_Load事件中)。 - James Carr
这绝对是最简单的方法。 - David R Tribble

22

自己动手做:

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

这样调用:

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

为什么要重复造轮子?这种方法比使用内置机制更好吗?(Alex Angas的回答) - NickG
3
因为这个轮子的旋转效果比上面的木制版本要好!;) - Fandango68
我更喜欢这个JavaScript解决方案。上面的 RegularExpressionValidator 可能会出现问题,并需要更改 web.config。(参考:https://dev59.com/MGQn5IYBdhLWcg3wpoqp) - Just a HK developer

6
HTML5有一些变化:
ASPX:
<asp:TextBox ID="txtBox" runat="server" maxlength="2000" TextMode="MultiLine"></asp:TextBox>

C#:

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

渲染的HTML:

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

Attributes的元数据:

摘要:获取任意属性的集合(仅用于呈现),这些属性不对应控件上的属性。

返回值:一个System.Web.UI.AttributeCollection,包含名称和值对。


这是一个很好的答案,但你应该删除!IsPostBack条件,因为如果有人在Firebug中将其删除,TextBox将不会具有maxlength属性。 - krlzlx
不错的观点,虽然在我的有限内部使用应用程序中这已经足够了。 - Kristopher

5

使用自定义属性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>

这将呈现为这样

<textarea name="ctl00$BodyContentPlac
eHolder$txtAddress" rows="4" cols="17" id="txtAddress" maxlength="100"></textarea>

在IE 9或更早版本中无法工作,因此需要像Alex Angas的答案中那样与验证器结合使用。 - NickG

4
$('#txtInput').attr('maxLength', 100);

它因为无法正常工作而被投下反对票。它根本没有任何效果,你仍然可以输入超过100个字符。这使得答案毫无用处 - 因此所有的反对票。 - NickG
2
+1 这在 HTML 4.01 中可能不起作用,但是随着 'maxlength' 属性 的引入,它在 HTML 5 中起作用。 - Charles Caldwell

4

对于那些支持textarea的maxlength属性(HTML5)且无需JavaScript的浏览器(Firefox,Chrome,Safari),另一种修复方法是派生System.Web.UI.WebControls.TextBox类的子类并覆盖Render方法。然后在重写的方法中,在正常呈现之前添加maxlength属性。

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

    base.Render(writer);
}

1
你也可以将其转换为ControlAdapter,这样你就不需要用继承的文本框替换每个TextBox。 - Peter

3
使用具有runat="server"的HTML textarea可以在服务器端访问它。与使用JavaScript或正则表达式相比,这种解决方案更加简便。
<textarea runat="server" id="txt1" maxlength="100" />

注意: 要在服务器端访问Text属性,您应该使用txt1.Value而不是txt1.Text


2

我尝试了不同的方法,但每个方法都有一些弱点(例如剪切和粘贴或浏览器兼容性)。这是我目前正在使用的解决方案:

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

在这种情况下,我在按键抬起时调用multilineTextBoxKeyUp,在按键按下时调用multilineTextBoxKeyDown:
myTextBox.Attributes.Add("onkeyDown", "multilineTextBoxKeyDown(this, event, '" + maxLength + "');");
myTextBox.Attributes.Add("onkeyUp", "multilineTextBoxKeyUp(this, event, '" + maxLength + "');");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接