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

时间:2013-07-11 16:59:17

标签: javascript validation

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

我们正在客户端进行大规模的清理和重构,我的任务是找出完成所有验证的方法。最初我将使用我们已经使用的解决方案之一,如jQuery验证或低音验证插件。但后来我正在研究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" />

然后我可以验证“addressGroup”中的所有内容,它会自动验证所有这些元素。

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

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

3 个答案:

答案 0 :(得分:2)

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

我已经回答了您可能希望查看的类似问题previously。我想建议一个我设计的名为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" /> 

将被Regula认可并经过验证。但你也可以这样做:

<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组件。因此,对于跨浏览器兼容性,您需要使用某种polyfill或垫片。

也可以进行异步验证:

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格式,你可以从here获得它。

答案 1 :(得分:1)

您应该考虑以下几点:

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

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

3 - 您可以使用pattern属性并使用正则表达式进行验证。 External Resource

我的建议:看看像Backbone或Knockout这样的MVVM库。

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

答案 2 :(得分:0)

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

它们与XHTML文档类型不兼容,但它们适用于更宽松的文档,如HTML 4.01。

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

$(someInput).data()

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