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

标签 javascript validation

在工作中,我们有一个相当古老的 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" />

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

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

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

最佳答案

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

我回答过类似的问题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 支持和异步验证而言,这些功能将在目前处于 Alpha 阶段的 Regula 1.3 版中提供。我有一些小功能和文档要更新,但您应该能够检查当前 GitHub 上的内容,它应该适合您。 HTML5 和异步验证已基本完成。

关于 HTML5 约束,您可以使用 native 属性,或使用 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")' /> 

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

异步验证也是可能的:

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 获得它.

关于javascript - 灵活而强大的表单验证解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17599276/

相关文章:

javascript - 带有嵌套路由的 Ember 动态路由

javascript - 在Canvas中实现拉伸(stretch)橡皮筋效果

Laravel 验证有时会规定日期验证

javascript - Bootstrap 表单验证在不需要输入时以绿色突出显示标签文本?

javascript - 如何使用 Promise 在 Canvas 上加载图像

javascript - 在不同的.js文件中使用两个同名的方法

javascript - 如何从 php 服务器获取带有 $.ajax 的 zip

php - 我应该 mysql_real_escape_string 我从用户那里获得的所有 cookie 以避免 php 中的 mysql 注入(inject)吗?

javascript - 如何验证在 Jquery 中动态添加的 div 子元素?

javascript - 通过 jQuery 检索输入后触发 Parsley.js 验证错误