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

我们的网络表单确实很复杂。 什么是可扩展表单验证的最佳解决方案,最好是与jQuery兼容的解决方案?

背景:

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

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

我们目前正在使用jQuery验证库,但我们的表单似乎已超出其功能。 我一直在研究诸如<angular />,Knockout和Backbone.js之类的东西,但我担心它们太笨重,否则它们将需要我们重写前端。

(这应该是社区Wiki。)

a paid nerd asked 2020-01-13T15:08:33Z
8个解决方案
55 votes

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

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

这里有一些例子:

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

<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(已简化),展示了使用Hibernate Validator在Regula和Spring 3.0.x Web MVC之间的集成。 它没有真正的文档记录或其他任何东西,而是更多的概念证明。 我计划在github页面上添加一些有关集成及其工作方式的文档。

更新#3

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

Vivin Paliath answered 2020-01-13T15:10:58Z
13 votes

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

干杯!

Mitch Malone answered 2020-01-13T15:11:23Z
8 votes

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

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

Tracker1 answered 2020-01-13T15:11:49Z
5 votes

在撰写本文时(2013年8月),Parsley.js似乎是不错的选择。

Simone answered 2020-01-13T15:12:11Z
2 votes

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

  • 演示文稿-支持HTML5输入字段。 onFail字段可确保用户只能按特定模式输入测试。
  • 副作用-触发表单和各个字段上的事件:onFailonSuccess
  • 小部件驱动的元素-鼓励“自定义输入类型”。 基本的演示甚至包括一个自然数字古老的“年龄”字段。
  • 组-编写“功能匹配器”,其唯一目的是过滤要验证的字段。
  • 服务器端验证-是否有效,并以智能方式完成-取决于验证程序调用回调(因此是异步友好的)而不是返回值。
  • 每页有多个表单-jQuery工具似乎构建得很好,这应该不是问题。
  • 可自定义的错误显示-字段旁边的错误? 集中在一处? 没问题。 还不够好吗? 绑定事件失败。 默认情况下甚至使用工具提示。
  • 贪婪-演示非常敏捷
  • 提交按钮-没问题。

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

a paid nerd answered 2020-01-13T15:13:16Z
1 votes

服务器端验证的岩石。

如果愿意,可以通过AJAX请求提供这种验证的结果,或者使用也会添加客户端验证的服务器端框架-但不要重复编写两次。

Fenton answered 2020-01-13T15:13:41Z
0 votes

使用jQuery Validation插件。 到目前为止,我从未失败过

Hello Universe answered 2020-01-13T15:14:00Z
0 votes
 function isEmpty(text) {
if(text == undefined) {
    return true;
}
if(text.replace(/\s+/g, ' ').length == 0) {
    return true;
}
return false;
}

function isValidBoolean(text) {
   if(text == undefined || (text.toLowerCase() != "true" &&    text.toLowerCase() != "false")) {
    return false;
}
return true;
 }

  function isValidDouble(text) {
     var out = parseFloat(text);
   if(isNaN(out)) {
    return false;
  }
  return true;
  }

  function isValidLong(text) {
var out = parseInt(text);
if(isNaN(out)) {
    return false;
}
return true;
}

 function isValidDate(text) {
if(Date.parseString(text, 'MM/dd/yyyy HH:mm:ss') == null) {
    return false;
}
return true;
}

  function hasDuplicates(array) {
var valuesSoFar = {};
for (var i = 0; i < array.length; ++i) {
    var value = array[i];
    if (Object.prototype.hasOwnProperty.call(valuesSoFar, value)) {
        return true;
    }
    valuesSoFar[value] = true;
}
return false;
}
Sushant Patil answered 2020-01-13T15:14:16Z
translate from https://stackoverflow.com:/questions/4751780/best-javascript-solution-for-client-side-form-validation-and-interaction