灵活而强大的表单验证解决方案

Flexible and powerful form-validation solution

本文关键字:表单 验证 解决方案      更新时间:2023-09-26

在工作中,我们有一个非常古老的Web应用程序。因此,我们有一个表单验证解决方案的大杂烩。有很多重复的验证逻辑,很多自定义验证逻辑,一些已经用jQuery验证实现的东西,一些来自 bassistance.de 验证器的东西,一些新代码甚至有HTML验证,等等。你明白了。

我们正在客户端进行大规模的清理和重构,我的任务是找出一种方法来完成所有验证。最初,我将使用我们已经使用的解决方案之一,例如jQuery验证或bassistance验证插件。但后来我正在研究HTML5验证,我真的很喜欢如何通过查看元素来判断哪些验证规则适用于它。所以我决定走这条路。但后来我意识到,对于自定义验证,我仍然必须用 Javascript 写出它们,然后没有简单的方法来判断该自定义验证规则是否适用于该元素。基本上,我想做这样的事情:

<input type="text" required="true" customValidationRule="true" />

或类似的东西。但它变得比这更复杂。我们的一些自定义验证规则需要某些参数,如果我能做这样的事情,那就太棒了:

<input type="text" required="true" customValidationRule="true" customValidationRuleParamOne="5" customValidationRuleParamTwo="6" />

我还想将某些内容作为组进行验证,例如某人的地址详细信息或信用卡详细信息,或类似的东西。例如,做这样的事情会很有用:

<input type="text" name="street" required="true" group="addressGroup" />
<input type="text" name="city" required="true" group="addressGroup" />
<input type="text" name="state" required="true" group="addressGroup" />
<input type="text" name="zip" required="true" group="addressGroup" />

然后我可以验证"地址组"中的所有内容,它会自动验证所有这些元素。

为了使事情变得更加复杂,我们还提供了使用 JSR-303 进行的服务器端验证。我们目前为此进行 AJAX 调用,但我想以某种方式将其附加到元素以及使用类似 asyncValidationRule="true"> 之类的属性。你能在HTML5中做这样的事情吗?

理解我是否要求太多。但是,是否有至少具有其中一些功能的验证库?我最想要的是能够在元素本身上指定验证规则。如果它没有任何其他要求,也可以。我可以以某种方式解决这个问题。

免责声明:我在这场比赛中有一匹马;我是以下库的作者。

我之前回答过一个类似的问题,你可能想看看。我想建议一个我设计的框架,叫做Regula。它满足了您要求的大部分内容。可以使用 data-constraints 属性将验证规则(或约束(直接附加到元素上。

例如,您可以执行以下操作:

<input type="text" name="something" data-constraints='@Required' />

您甚至可以设置错误消息或标签等内容:

<input type="text" name="something" data-constraints='@Required(label="something" message="{label} is required.")' />

自定义验证也很容易。你确实需要在 JavaScript 中定义一次验证器,但之后你可以使用它:

regula.custom({
   name: "MustBe42",
   defaultMessage: "The answer must be equal to 42",
   validator: function() {
      return this.value == 42;
   }
});

然后:

<input type="text" name="something" data-constraints='@MustBe42' />

还支持参数:

regula.custom({
   name: "MustBeSpecifiedNumber",
   params: ["number"],
   defaultMessage: "The answer must be equal to {number}",
   validator: function(params) {
      return this.value === params.number;
   }
});

然后:

<input type="text" name="something" data-constraints='@MustBeSpecifiedNumber(number=10)' />

您询问了验证组,这也可以在 Regula 中完成:

<input type="text" name="street" data-constraints='@Required(groups=[AddressGroup])' />
<input type="text" name="city" data-constraints='@Required(groups=[AddressGroup])' />
<input type="text" name="state" data-constraints='@Required(groups=[AddressGroup])' />
<input type="text" name="zip" data-constraints='@Required(groups=[AddressGroup])' />

然后,您可以使用以下方法进行验证:

var constraintViolations = regula.validate({
    groups: [regula.Group.AddressGroup] //AddressGroup property is automatically added
});

就HTML5支持和异步验证而言,这些功能将在Regula的1.3版本中提供,该版本目前处于Alpha阶段。我有一些小功能和文档需要更新,但您应该能够查看 GitHub 上当前的内容,它应该对您有用。HTML5和异步验证大部分已经完成。

关于HTML5约束,您可以使用本机属性,也可以使用Regula包装的版本,这些版本为您提供了更多选项,例如分配给组和自定义消息。例如:

<input type="text" name="something" required="true" /> 

将被雷古拉认可并验证。但您也可以这样做:

<input type="text" name="something" data-constraints='@HTML5Required(groups=[MyGroup], message="{label} is required!", label="something")' /> 
<input type="text" name="somethingElse" data-constraints='@HTML5Required(groups=[MyGroup], message="{label} is required!", label="somethingElse")' /> 

通常,仅使用本机HTML5验证无法做到这一点。但是,需要注意的重要一点是,浏览器必须支持HTML5验证才能正常工作。Regula 不会尝试模拟 HTML5 功能,因为它涉及的不仅仅是简单的验证;它还涉及特定的 UI 组件。因此,为了跨浏览器兼容性,您需要使用某种填充或填充程序。

异步验证也是可能的:

regula.custom({
    name: "AsyncConstraint",
    async: true,
    defaultMessage: "{label} did not validate properly.",
    validator: function(params, validator, callback) {
        jQuery.ajax({
            url: "myurl",
            dataType: "json",
            data: someData,
            success: function(data) {                    
                callback(data.successful)
            }
        });
    }
});

然后,您可以使用以下内容注释元素:

<input type="text" name="something" data-constraints='@AsynchronousConstraint' /> 

并使用以下方法进行验证:

//Simply calling validate will validate all constraints on all elements
regula.validate(function(constraintViolations) {
    //do stuff with constraintViolations
});

执行条件验证和使用预先存在的验证器也很容易:

regula.custom({
   name: "ConditionalRequired",
   defaultMessage: "The answer must be equal to {number}",
   validator: function(params, validator) {
      var result = true;
      if(some condition is true) {
          result = validator.required(this, params, validator);
      }
      return result;
   }
});

validator 对象基本上允许您访问每个约束的原始验证器函数。

Regula还有许多其他特性,比如复合约束(基本上就像JSR-303一样(。

Regula 没有任何与 UI 相关的逻辑,例如显示错误消息。它只是一个验证引擎,所以它只这样做。您希望如何显示错误消息取决于您。

希望您觉得这很有用!正如我之前提到的,当前版本是 1.3.0;它在 alpha 中,您可以从这里获得它。

您应该考虑的一些要点:

1-并非所有浏览器都支持 html5。

2-您无法自定义必填字段的默认错误消息。

3-您可以使用模式属性并使用正则表达式进行验证。外部资源

我的建议:看看MVVM库,如Backbone或Knockout。

http://backbonejs.org/#Model-validate

HTML5 data-* 属性对于此类问题很有用。http://www.slideshare.net/lensco/html5-data-attributes

它们不能很好地处理XHTML文档类型,但它们可以处理更宽松的文档类型,例如HTML 4.01。

jQuery 1.9(我认为以前的版本也是如此(允许你做这样的事情:

$(someInput).data()

它将返回一个包含所有 data-* 属性(在 camelCase 中(及其各自值的对象。