客户端表单验证和交互的最佳 JavaScript 解决方案?

IT技术 javascript jquery html validation forms
2021-02-15 00:06:27

我们的网络表单非常复杂。什么是可扩展表单验证的好解决方案,最好是与 jQuery 一起使用的解决方案?

背景:

我们的网站有一些 Ajax,但真正的重点是通过大约 20 个多页面表单或“向导”来实现用户体验。这些表格很复杂。

  • 介绍:一些字段是浮点数或整数。验证意味着去除非十进制字符,但我们还希望确保,如果用户输入5价格字段,该字段将更新为5.00
  • 副作用:某些字段在更新时会产生副作用。例如,更新商品的价格或数量需要更新小计字段。
  • 小部件驱动的元素:某些字段是隐藏的,并且具有由小部件填充的值。例如,地图小部件可让您指向某个位置,并且使用经纬度坐标更新隐藏字段,但该位置必须在某个区域内。
  • 组:某些字段是组,例如地址/城市/州/邮编,并且仅应在填充所有字段时进行验证。
  • 服务器端验证:某些字段的验证需要通过 Ajax 请求进行后端检查
  • 每页多个表单:有时用户需要填写一个表单,然后才能打开另一个表单的对话框。框架必须比绑定更通用onSubmit——我们有时使用 Ajax 从同一页面按顺序发布多个表单。(例如,我们让用户一次性注册并创建一个小部件,但由于遗留系统,该流程需要两个 POST 请求。)
  • 可自定义的错误显示:有时错误会出现在字段上方,有时字段样式会发生变化,我们的新设计会为某些错误调用类似工具提示的弹出窗口 (ala qTip )。
  • Snappiness:用户体验是关键,触觉反馈很重要。任何解决方案
  • 提交按钮:单击提交按钮需要验证所有内容,然后显示响应——但由于某些验证是异步发生的。

我们目前正在使用jQuery 验证库,但我们的表单似乎超出了它的能力。我一直在研究<angular/>KnockoutBackbone.js 之类的东西,但我担心它们太重量级,或者它们需要我们重写我们的前端。

(这应该是一个社区维基。)

6个回答

这是一个无耻的插件,但我可以自愿提供一个我设计框架吗?我已经基于注释(a la Hibernate Validator)构建了它。它支持自定义约束,我觉得它非常强大。也是一个 Stackoverflow 问题,我要求对框架进行审查。

  • 演示:使用自定义验证约束,您可以将验证绑定到 onChange 元素。此外,由于 Regula 支持自定义验证器,您可以让自定义验证器更新字段的值(因此更改55.00)。
  • 副作用:Regula 通过自定义约束验证器支持副作用。
  • :Regula 支持验证组。您可以针对特定组进行验证。通过组合自定义验证器和组,您可以控制验证器的行为,以便在填充该组的所有元素时才进行验证(尽管您必须通过普通 Javascript 执行此检查)。
  • 服务器端验证:使用自定义约束,您可以进行 AJAX 调用以执行服务器端验证。根据当前框架的结构方式,这必然是一个阻塞的 ajax 调用。我计划在未来添加异步功能。
  • 每页多个表单:Regula 不限于每页验证一个表单。它可以处理多种形式(不确定我是否正确理解您的要求 - 所以我可能没有正确回答这部分)。
  • 可定制的错误显示:就验证而言,Regula 不会对页面的 UI 做任何事情。验证时,您会得到一组包含错误消息等的约束违规。如何显示它们取决于您。
  • Snappiness:我没有执行任何基准测试,所以我无法评论我的框架在这​​方面的表现。
  • 提交按钮:这是我尚未解决的问题(异步与同步)。

这里有一些例子:

下面显示了带有内置约束的标准验证:

<input id = "myInput"
       name = "myInput"
       type = "text"
       class = "regula-validation"
       data-constraints = '@NotEmpty @IsNumeric @Between(min=1, max=5)' />

jQuery(document).ready(function() {
    // must call regula.binnd() first. The best place would be in an
    // onload handler. This function looks for elements with
    // a class name of "regula-validation" and binds the
    // appropriate constraints to the elements

    regula.bind(); 

    jQuery("#myForm").submit(function() {
        // this function performs the actual validation
        var validationResults = regula.validate();

        for(var index in validationResults) {
             var validationResult = validationResults[index];
             alert(validationResult.message);
        }
    });
});

如您所见,您只处理违反约束的情况,因此显示错误消息的方式完全取决于您。

这是自定义约束的示例:

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

及其用途:

<input id = "theAnswerToLifeTheUniverseAndEverything" 
       name = "theAnswerToLifeTheUniverseAndEverything" 
       value = ""
       class = "regula-validation"
       data-constraints = "@MustBe42" />

由于验证器是一个 Javascript 函数,你可以让它做任何事情(所以这解决了你关于副作用的问题)。

这是另一个接受参数的约束的示例:

regula.custom({
   name: "DivisibleBy",
   defaultMessage: "{label} must be divisible by {divisor}",
   params: ["divisor"],
   validator: function(params) {
      var divisor = params["divisor"];
      return (this.value % divisor) == 0;
   }
});

和用法:

<input id = "number" 
       name = "number" 
       value = ""
       class = "regula-validation"
       data-constraints = "@DivisibleBy(divisor=3, label='The Number')" />

以下是使用验证组的示例:

<input id = "score"
       name = "score"
       type = "text"
       class = "regula-validation"
       data-constraints = '@IsNumeric(label="Score", 
                                      message="{label} needs to be a number!"
                                      groups=[FirstGroup, SecondGroup, ThirdGroup]' />

<input id = "age"
       name = "age"
       type = "text"
       class = "regula-validation"
       data-constraints = '@IsNumeric(label="Age", 
                                      message="{label} needs to be a number!"
                                      groups=[SecondGroup]' />

<input id = "name"
       name = "name"
       type = "text"
       class = "regula-validation"
       data-constraints = '@NotEmpty(label="Name", 
                                     message="{label} cannot be empty!"
                                     groups=[FirstGroup]' />

以及仅验证的代码段FirstGroup(仅验证scorename验证):

var constraintViolations = regula.validate({groups: [regula.Group.FirstGroup]});
var messages = "";

for(var index in constraintViolations) {
      var constraintViolation = constraintViolations[index];
      messages += constraintViolation.message + "\n";
}

if(messages != "") {
   alert(messages);
}

如果您打算尝试一下,我建议您下载1.1.1当前文档特别匹配该版本。1.2.1 中,我添加了对复合约束的支持,但我没有更新我的文档来反映这一点。

我理解这是否不能解决您的所有问题,或者这不是您想要的。我以为我只是把它放在那里。另外,如果您确实检查了它,那么我将确保更新文档以反映版本1.2.1我一直忙于学校和工作,所以我没有时间去做。

更新 #1

Sohnee提到了客户端验证。我实际上正在研究 Regula 和 Spring 3 之间的集成。希望我能很快发布它(再次取决于工作和学校)。集成的工作原理是将 Hibernate 验证约束转换为 Regula 验证约束。这样,您只需编写一次验证代码(大多数情况下)。但是对于自定义约束,您仍然需要在 Javascript 端(自定义验证器)编写代码。但是一旦您使用 Hibernate 验证约束在服务器端注释代码,您就无需在客户端执行任何操作;这些约束会自动应用于客户端的表单元素。

Matthew Abbott还能够将 Regula 与 ASP.NET MVC 集成

更新 #2

在 github 上有一个演示 webapp(mavenized)它展示了 Regula 和 Spring 3.0.x Web MVC 之间使用 Hibernate Validator 的集成。它没有真正记录或任何东西,它更像是概念证明。我计划向 github 页面添加一些关于集成及其工作原理的文档。

更新 #3

我已经更新了wiki上的文档,它现在对应于最新版本1.2.2(我做了一个小错误修正,这就是它现在1.2.2 的原因)。

+1的详细答案。听起来你的框架做了很多提问者的要求。
2021-04-16 00:06:27
回答写得好!我目前正在研究 jQuery UI 表单小部件和添加验证module的可能性,您的框架看起来是一个很好的灵感来源!
2021-04-16 00:06:27
+1 适合轻量级需求(约 27kb 缩小对于这么多有趣的功能非常有用)。
2021-04-19 00:06:27
哇,如果你要投反对票,至少要有礼貌地解释原因。我什至通过说这是一个无耻的插头来限定这个答案。严重地。
2021-04-20 00:06:27
看起来像 fValidate 的精神继承者(不是我的反对票,顺便说一句)
2021-04-25 00:06:27

我已经多次将这个jQuery formValidator与一大堆不同的环境结合使用。我希望它有所帮助,因为我很少花一个多小时来设置它。

干杯!

我会说jQuery 验证插件做得很好。我将它与元数据插件结合起来将服务器端验证参数传递给客户端。我还为所有表单包装了一些关键点,以便我可以使用通用模式进行验证,以及一些特殊/自定义状态。这包括自定义警报消息和显示。

它并没有开箱即用地完成您想要的一切,但它是我见过的最佳选择和最佳默认行为。同样,我确实使用了元数据(属性“data-meta”)。它可以随您的意愿弯曲。我还使用元数据来控制绑定到客户端的输入元素。这将我的客户端逻辑与服务器端分开,但从长远来看,尝试从服务器端逻辑注入 js 更容易。

在撰写本文时(2013 年 8 月), Parsley.js看起来是一个不错且受欢迎的选择。

Parsley 是我向开发人员推荐的。
2021-04-16 00:06:27
Parsley 在撰写本文时很棒,但他们的新版本的 UX 非常糟糕。其他人也发现了这个吗?
2021-05-15 00:06:27

我自己回答这个问题,因为我们团队中有人注意到jQuery Tools 中的 Validator

  • 演示文稿- 支持 HTML5 输入字段。pattern字段确保用户只能输入特定模式的测试。
  • 副作用- 在表单和单个字段上触发事件:onFailonSuccess
  • 小部件驱动的元素- 鼓励“自定义输入类型”。基本演示甚至包括一个自然数旧的“年龄”字段。
  • - 编写一个“函数匹配器”,其唯一目的是过滤要验证的字段。
  • 服务器端验证- 执行并智能执行 - 取决于您的验证器调用回调(因此它是异步友好的)而不是返回值。
  • 每页多个表单- jQuery 工具似乎构建得非常好,这应该不是问题。
  • 可定制的错误显示- 字段旁边的错误?都在一处?没问题。还是不够好?失败时绑定事件。甚至默认使用工具提示。
  • 活泼- 演示非常活泼
  • 提交按钮- 没问题。

更新:是的,刚刚使用 jQuery Tools 的验证器工具提示重新实现了我们网站的一部分。极好的!

我接受了这个答案,因为 jQuery Tools 尽管有点被忽视,但仍然是最好的,因为它支持 HTML5,与 IE7 和 IE9 兼容,并且很容易重用(我们有站点范围的行为和验证器默认值)。三年来,basstance.de Validator 插件一直是一个痛苦之源,我们已尽一切努力将其删除。
2021-04-18 00:06:27
这个库看起来缺乏支持
2021-04-18 00:06:27
太糟糕了,这被接受为答案。在我看来,jQuery 工具一团糟,需要彻底改革。开发人员自己承认,已经对维护该项目失去了兴趣,并且 6 个月多以来一直未能找到愿意接管该项目的程序员。远离这个答案,这是我的建议,并使用由 jQuery 团队成员开发非常出色的插件
2021-04-22 00:06:27
我还没有尝试过 jQuery 工具验证,但是 Basistance 验证器也让我很沮丧。
2021-04-29 00:06:27
我完全不同意,但这不是这些评论中讨论的内容。
2021-05-16 00:06:27