jQuery验证textarea maxlength错误

时间:2010-12-03 15:02:06

标签: jquery validation jquery-validate

我正在使用jQuery.validate v 1.6.0来验证我的表单。

我的一个数据库字段限制为1000个字符。我在相应的textarea中添加了验证,如下所示:

在我的页面标题中,我添加了

$('form.validate').validate();

在我的页面中,我声明:

<form method="post" class="validate" action="Save">
    <textarea name="description" minlength="15" maxlength="1000" id="description" class="required"></textarea>
    <input type="submit" value="Save">    
</form>

我遇到的问题是,jQuery似乎将“新行”中涉及的字符数量与我的数据库不同。

当我输入没有新行的1000个字符时,一切顺利,验证工作正常。如果我用一些新行键入1000个字符,jQuery允许POST发生,但我的数据库拒绝插入/更新,因为数据太大。

任何提示都将不胜感激。

7 个答案:

答案 0 :(得分:5)

我使用jQuery Validate 1.9来解决这个问题。因为我在服务器上使用ASP.NET MVC 3和C#,服务器上的断点是“\ r \ n”,而在客户端上是“\ n”。当我在客户端上验证我的textarea时,验证没有失败,因为“\ n”只算作一个字符,但是当文本在服务器上进行验证时,换行符为“\ r \ n”,验证将失败。

我对这个问题的看法是覆盖jQuery验证方法“rangelengt”,因为我还定义了最小长度:

$.validator.addMethod('rangelength', function (value, element) {
        var maxlen = parseInt($(element).attr('data-val-length-max'));
        if (maxlen > 0) {
            var remaining = (maxlen - (parseInt($(element).val().replace(/(\r\n|\n|\r)/gm, '\r\n').length)));
            if (remaining < 0) {
                return false;
            }
        }

        return true;
    });

所以这段代码实际上做的是获取maxlength值,然后从元素中获取值,然后用“\ r \ n”替换所有“\ n”字符,以获得与服务器相同的字符数会。

答案 1 :(得分:2)

虽然这不是客户端解决方案,但我能够处理问题服务器端。

我基本上删除了“额外”字符,即“\ r”字符。我想这些不计入浏览器中的字符串长度,或者它们与“\ n”字符合并为一个。

就我而言,ASP.NET MVC使用C#:

[HttpPost]
public ActionResult SetComment(int id, string comment)
{
    // Yep, the browser can insert newlines as "\r\n" which overflows the allowed number of characters!
    comment = comment.Replace("\r", "");

    // More code...
}

答案 2 :(得分:2)

我也像John Bubriski那样采用了服务器端方法,但是在ASP.NET MVC中将其作为DefaultModelBinder的扩展实现,这样所有控制器操作都会立即受益:

public class NewlinesNormalizingModelBinder : DefaultModelBinder
{
    protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor)
    {
        base.BindProperty(controllerContext, bindingContext, propertyDescriptor);

        // Note: if desired, one could restrict the conversion to properties decorated with [StringLength]:
        // && propertyDescriptor.Attributes.OfType<StringLengthAttribute>().Any()
        if (propertyDescriptor.PropertyType == typeof(string))
        {
            var originalString = propertyDescriptor.GetValue(bindingContext.Model) as string;
            if (!string.IsNullOrEmpty(originalString))
            {
                var stringWithNormalizedNewlines = originalString.Replace("\r\n", "\n");
                propertyDescriptor.SetValue(bindingContext.Model, stringWithNormalizedNewlines);
            }
        }
    }
}

然后在应用程序启动时:

ModelBinders.Binders.DefaultBinder = new NewlinesNormalizingModelBinder();

答案 3 :(得分:2)

我扩展 Robin Ridderholt 解决方案,现在我们可以将maxlen引用到验证器

$.validator.addMethod('extMaxLength', function (value, element, maxlen){
            if (maxlen > 0) {
                var remaining = (maxlen - (parseInt($(element).val().replace(/(\r\n|\n|\r)/gm, '\n').length, 10)));
                if (remaining < 0) {
                    return false;
                }
            }
            return true;
        });

答案 4 :(得分:1)

我遇到了同样的问题。这是因为在javascript中,field.length会返回字符数,但是一个字符可以使用2bytes来存储信息。

我的问题是DB中的VARCHAR2字段只能存储4000字节的信息或2000字符。 我们很容易混淆,并认为我们可以在这种领域存储4000个字符。

我认为在你的情况下,字段不限于1000个字符,而是1000字节,这与你使用使用一个字节信息的“标准字符”相同,所以我将限制为2000Bytes和保持javascript验证1000chars。 然后,当然我会反对上一个答案并对字符数进行服务器端验证。

当然你有其他解决方案,例如我的情况(虽然我没有使用Jquery),我调整了字符计数器来计算每个特殊字符两次(这个问题影响换行字符,但也有重音符号.... )

答案 5 :(得分:0)

我建议改进 Jakub Berezanski 的解决方案。

我个人认为他的想法(通常在服务器端处理这个问题)非常好。

他的示例代码只有一个问题可能是,在覆盖BindProperty方法时模型最终已经无效 - 如果它只是由我们&那个字段的长度引起的#39;在那里纠正。

因此,我对他的解决方案的改进建议是在GetPropertyValue覆盖中应用相同的逻辑 - 在验证之前执行:

public class NewlinesNormalizingModelBinder : DefaultModelBinder
{
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
    {
        // Note: if desired, one could restrict the conversion to properties decorated with [StringLength]:
        // && propertyDescriptor.Attributes.OfType<StringLengthAttribute>().Any()
        if (propertyDescriptor.PropertyType == typeof(string))
        {
            string originalString = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue;

            if (!string.IsNullOrEmpty(originalString)) return originalString.Replace("\r\n", "\n");
        }

        return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
    }
}

答案 6 :(得分:-5)

删除服务器验证并仅保留客户端验证。 在html中new line = 3 char 在数据库中new line = 1 char 所以你必须只保留一个。 或更改db char设置