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

标签 javascript jquery html validation forms

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

4年前关闭。




Improve this question




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

背景:

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

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

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

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

    最佳答案

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

  • 介绍 :使用自定义验证约束,您可以将验证绑定(bind)到 onChange 元素。此外,由于 Regula 支持自定义验证器,您可以让自定义验证器更新字段的值(因此将 5 更改为 5.00 )。
  • 副作用 :Regula 通过自定义约束验证器支持副作用。
  • 群组 :Regula 支持验证组。您可以针对特定组进行验证。通过组合自定义验证器和组,您可以控制验证器的行为,以便仅在填充该组的所有元素时才进行验证(尽管您必须通过普通的 Javascript 执行此检查)。
  • 服务器端验证 :使用自定义约束,您可以进行 AJAX 调用以执行服务器端验证。根据当前框架的结构方式,这必然是一个阻塞的 ajax 调用。我计划在 future 添加异步功能。
  • 每页多个表格 :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 我添加了对复合约束的支持,但我没有更新我的文档来反射(reflect)这一点。

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

    更新 #1

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

    Matthew Abbott还可以integrate Regula with ASP.NET MVC .

    更新 #2

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

    更新 #3

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

    关于javascript - 客户端表单验证和交互的最佳 JavaScript 解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4751780/

    相关文章:

    Javascript "mouseover"和 "mouseout"事件

    javascript - 如何防止 Canvas 在移动设备上表现得像图像?

    javascript - 如何使用正则表达式获取阿拉伯字符串中的单词列表?

    javascript - 尝试使用 Jquery UI 同时运行两个动画

    html - 我的 div 违背我的意愿相互覆盖

    javascript - 通过Helper访问全局变量

    javascript - 无法使用 jQuery 委托(delegate)滚动事件

    JavaScript(用一个按钮打开和关闭某些东西)

    html - 如何使用 Struts 2.x 指定 HTML5 属性?

    css - 标题菜单大小没有响应